Index: openacs-4/packages/dotlrn-ecommerce/catalog/dotlrn-ecommerce.en_US.ISO-8859-1.xml
===================================================================
RCS file: /usr/local/cvsroot/openacs-4/packages/dotlrn-ecommerce/catalog/dotlrn-ecommerce.en_US.ISO-8859-1.xml,v
diff -u
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ openacs-4/packages/dotlrn-ecommerce/catalog/dotlrn-ecommerce.en_US.ISO-8859-1.xml 4 Jun 2005 10:05:17 -0000 1.1
@@ -0,0 +1,14 @@
+
+
@course_list.course_info;noquote@ @@ -273,15 +309,6 @@ } -set instructor_community_id [parameter::get -package_id [ad_conn package_id] -parameter InstructorCommunityId -default 0 ] -set _instructors [dotlrn_community::list_users $instructor_community_id] -if { [llength $_instructors] == 0 } { - set _instructors 0 -} else { - foreach instructor $_instructors { - lappend __instructors [ns_set get $instructor user_id] - } -} set grade_tree_id [db_string grade_tree { select tree_id from category_tree_translations @@ -343,18 +370,21 @@ # Build sessions set calendar_id [dotlrn_calendar::get_group_calendar_id -community_id $community_id] - + lappend calendar_id_list $calendar_id set sessions [util_memoize [list dotlrn_ecommerce::section::sessions $calendar_id]] set instructors [util_memoize [list dotlrn_ecommerce::section::instructors $community_id $__instructors]] if { [llength $instructors] == 1 } { - set instructors "Instructor: [join $instructors ", "] (view bio)" + set instructors "Instructor: [join $instructors ", "]" } elseif { [llength $instructors] > 1 } { - set instructors "Instructors: [join $instructors ", "] (view bios)" + set instructors "Instructors: [join $instructors ", "]" } else { set instructors "" } + if { ! [empty_string_p $instructors] && $member_p } { + append instructors " [_ dotlrn-ecommerce.view_bios]" + } } if { ! [empty_string_p $product_id] } { Index: openacs-4/packages/dotlrn-ecommerce/lib/user-info.tcl =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/dotlrn-ecommerce/lib/user-info.tcl,v diff -u -r1.1 -r1.2 --- openacs-4/packages/dotlrn-ecommerce/lib/user-info.tcl 2 Jun 2005 06:39:41 -0000 1.1 +++ openacs-4/packages/dotlrn-ecommerce/lib/user-info.tcl 4 Jun 2005 10:05:17 -0000 1.2 @@ -148,8 +148,8 @@ {html {size 10}} } - {add:text(submit) {label "Update Participant"}} - {addpatron:text(submit) {label "Update Participant and Select Patron"}} + {add:text(submit) {label "Select Participant"}} + {addpatron:text(submit) {label "Select Participant and Select Patron"}} {cancel:text(submit) {label "Cancel"}} } -on_request { foreach var { authority_id first_names last_name email username screen_name url bio } { @@ -159,6 +159,7 @@ select * from person_info where person_id = :user_id + limit 1 } } -on_submit { set user_info(authority_id) $user(authority_id) @@ -203,6 +204,7 @@ select 1 from person_info where person_id = :user_id + limit 1 }] } { db_dml update_extra_info { update person_info Index: openacs-4/packages/dotlrn-ecommerce/sql/postgresql/dotlrn-ecommerce-create.sql =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/dotlrn-ecommerce/sql/postgresql/dotlrn-ecommerce-create.sql,v diff -u -r1.2 -r1.3 --- openacs-4/packages/dotlrn-ecommerce/sql/postgresql/dotlrn-ecommerce-create.sql 2 Jun 2005 06:39:42 -0000 1.2 +++ openacs-4/packages/dotlrn-ecommerce/sql/postgresql/dotlrn-ecommerce-create.sql 4 Jun 2005 10:05:18 -0000 1.3 @@ -42,6 +42,7 @@ select acs_rel_type__create_role('as_session_role', 'Assessment Sessions Role', 'Assessment Sessions Role'); select acs_rel_type__create_role('ec_product_role', 'Ecommerce Product Role', 'Ecommerce Product Role'); +select acs_rel_type__create_role('member_rel_role', 'Member Relationship Role', 'Member Relationship Role'); create table person_info ( person_id integer references persons not null, Index: openacs-4/packages/dotlrn-ecommerce/tcl/apm-callback-procs.tcl =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/dotlrn-ecommerce/tcl/apm-callback-procs.tcl,v diff -u -r1.2 -r1.3 --- openacs-4/packages/dotlrn-ecommerce/tcl/apm-callback-procs.tcl 2 Jun 2005 06:39:42 -0000 1.2 +++ openacs-4/packages/dotlrn-ecommerce/tcl/apm-callback-procs.tcl 4 Jun 2005 10:05:18 -0000 1.3 @@ -37,6 +37,8 @@ # Associate an ecommerce product to an assessment session result rel_types::new -role_one as_session_role -role_two ec_product_role as_session_ec_product_rel "Assessment Session to ECommerce Product" "Assessment Sessions to ECommerce Products" as_sessions 0 1 ec_product 0 1 + + rel_types::new -role_one member_rel_role -role_two user membership_patron_rel "Membership Patron" "Membership Patrons" dotlrn_member_rel 0 65535 user 0 65535 } ad_proc -private dotlrn-catalog::package_mount { Index: openacs-4/packages/dotlrn-ecommerce/tcl/implementation-procs.tcl =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/dotlrn-ecommerce/tcl/implementation-procs.tcl,v diff -u -r1.2 -r1.3 --- openacs-4/packages/dotlrn-ecommerce/tcl/implementation-procs.tcl 2 Jun 2005 06:39:42 -0000 1.2 +++ openacs-4/packages/dotlrn-ecommerce/tcl/implementation-procs.tcl 4 Jun 2005 10:05:18 -0000 1.3 @@ -11,20 +11,74 @@ } ad_proc -callback ecommerce::after-checkout -impl dotlrn-ecommerce { - -user_id - -product_id + -user_id:required + -product_id:required + -patron_id -price } { - Add user to community + Add users to community } { - # Get community mapped to product - db_foreach communities { - select community_id - from dotlrn_ecommerce_section - where product_id = :product_id - } { - ns_log notice "dotlrn-ecommerce callback: Adding user $user_id to community $community_id" + # Check first if user_id is actually a group + if { [acs_object_type $user_id] == "group" } { + set user_ids [db_list group_members { + select distinct object_id_two + from acs_rels + where object_id_one = :user_id + and rel_type = 'membership_rel' + }] + ns_log notice "dotlrn-ecommerce callback: Adding users ([join $user_ids ,]) in group $user_id" + } else { + set user_ids [list $user_id] + } - dotlrn_community::add_user $community_id $user_id + if { [exists_and_not_null patron_id] } { + if { ! [dotlrn::user_p -user_id $patron_id] } { + dotlrn::user_add -user_id $patron_id + } } + + foreach user_id $user_ids { + if { ! [dotlrn::user_p -user_id $user_id] } { + dotlrn::user_add -user_id $user_id + } + + # Get community mapped to product + db_foreach communities { + select community_id + from dotlrn_ecommerce_section + where product_id = :product_id + } { + ns_log notice "dotlrn-ecommerce callback: Adding user $user_id to community $community_id" + + if { [catch { + + dotlrn_community::add_user $community_id $user_id + + # Keep track of patron relationships + if { [exists_and_not_null patron_id] } { + if { [db_0or1row member_rel { + select rel_id + from dotlrn_member_rels_full + where community_id = :community_id + and user_id = :user_id + limit 1 + }] } { + set patron_rel_id [db_exec_plsql relate_patron { + select acs_rel__new (null, + 'membership_patron_rel', + :rel_id, + :patron_id, + null, + null, + null) + }] + } + } + + } errMsg] } { + # Fixes for possible double click + ns_log notice "dotlrn-ecommerce callback: Probably a double-click: $errMsg" + } + } + } } \ No newline at end of file Index: openacs-4/packages/dotlrn-ecommerce/www/contextbar.adp =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/dotlrn-ecommerce/www/contextbar.adp,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs-4/packages/dotlrn-ecommerce/www/contextbar.adp 4 Jun 2005 10:05:18 -0000 1.1 @@ -0,0 +1 @@ +@context_bar;noquote@
Index: openacs-4/packages/dotlrn-ecommerce/www/contextbar.tcl =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/dotlrn-ecommerce/www/contextbar.tcl,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs-4/packages/dotlrn-ecommerce/www/contextbar.tcl 4 Jun 2005 10:05:18 -0000 1.1 @@ -0,0 +1,32 @@ +# Add a [ Administer ] link at the far right to the context bar. + +# @param context_addition + +# @author Bart Teeuwisse (bart.teeuwisse@thecodemill.biz) +# @cvs-id $Id: contextbar.tcl,v 1.1 2005/06/04 10:05:18 hamiltonc Exp $ +# @creation-date September 2002 + +# Create an empty context_addition list if no addition has been passed +# in. + +if {![info exists context_addition]} { + set context_addition {} +} + +# Create a context bar with the passed in addition(s) if any. + +if {[empty_string_p $context_addition]} { + set context_bar [ad_context_bar] +} else { + set context_bar [eval ad_context_bar $context_addition] +} + +# Check for admin rights to this (the ecommerce) package. + +set ec_admin_p [ad_permission_p [ad_conn package_id] admin] +set ec_admin_link admin/ + +# Get the name of the ecommerce package + +set ec_system_name [ec_system_name] + Index: openacs-4/packages/dotlrn-ecommerce/www/index.adp =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/dotlrn-ecommerce/www/index.adp,v diff -u -r1.1 -r1.2 --- openacs-4/packages/dotlrn-ecommerce/www/index.adp 31 May 2005 22:04:53 -0000 1.1 +++ openacs-4/packages/dotlrn-ecommerce/www/index.adp 4 Jun 2005 10:05:18 -0000 1.2 @@ -13,5 +13,5 @@[ Administer ] - - \ No newline at end of file + + \ No newline at end of file Index: openacs-4/packages/dotlrn-ecommerce/www/index.tcl =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/dotlrn-ecommerce/www/index.tcl,v diff -u -r1.1 -r1.2 --- openacs-4/packages/dotlrn-ecommerce/www/index.tcl 31 May 2005 22:04:53 -0000 1.1 +++ openacs-4/packages/dotlrn-ecommerce/www/index.tcl 4 Jun 2005 10:05:18 -0000 1.2 @@ -5,7 +5,7 @@ @creation-date 31-01-2005 } { - + {view "list"} } set page_title "[_ dotlrn-catalog.course_catalog]" set context "" @@ -23,4 +23,6 @@ set tree_id [db_string get_tree_id { } -default "-1"] set add_course_url [export_vars -base admin/course-add-edit { return_url }] -set admin_p [permission::permission_p -object_id $cc_package_id -privilege "admin"] \ No newline at end of file +set admin_p [permission::permission_p -object_id $cc_package_id -privilege "admin"] + +set item_template "one-course?cal_item_id=\$item_id" \ No newline at end of file Index: openacs-4/packages/dotlrn-ecommerce/www/one-course.adp =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/dotlrn-ecommerce/www/one-course.adp,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs-4/packages/dotlrn-ecommerce/www/one-course.adp 4 Jun 2005 10:05:18 -0000 1.1 @@ -0,0 +1 @@ +@course_key@
\ No newline at end of file Index: openacs-4/packages/dotlrn-ecommerce/www/one-course.tcl =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/dotlrn-ecommerce/www/one-course.tcl,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs-4/packages/dotlrn-ecommerce/www/one-course.tcl 4 Jun 2005 10:05:18 -0000 1.1 @@ -0,0 +1,18 @@ +ad_page_contract { + show one course + for now redirect to index page + + @author Dave Bauer (dave@thedesignexperience.org) + @creation-date 2005-06-02 +} { + cal_item_id:integer,optional +} + +if {[info exists cal_item_id] && ![string equal "" $cal_item_id]} { +set course_key [db_string get_course_key "select d1.course_key from dotlrn_catalog d1,cr_items ci, (select distinct des.course_id from cal_items c,dotlrn_ecommerce_section des, dotlrn_communities dc, portal_element_map pem, portal_pages pp, portal_element_parameters pep where pep.key='calendar_id' and pep.value=c.on_which_calendar and pem.element_id=pep.element_id and pem.page_id=pp.page_id and pp.portal_id=dc.portal_id and c.cal_item_id=:cal_item_id and dc.community_id=des.community_id) d2 where d1.course_id=ci.live_revision and ci.item_id=d2.course_id" -default ""] + ad_returnredirect "./\#${course_key}" + ad_script_abort +} + +# TODO make a course details page + Index: openacs-4/packages/dotlrn-ecommerce/www/admin/course-info.tcl =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/dotlrn-ecommerce/www/admin/course-info.tcl,v diff -u -r1.1 -r1.2 --- openacs-4/packages/dotlrn-ecommerce/www/admin/course-info.tcl 31 May 2005 22:04:54 -0000 1.1 +++ openacs-4/packages/dotlrn-ecommerce/www/admin/course-info.tcl 4 Jun 2005 10:05:18 -0000 1.2 @@ -29,7 +29,7 @@ permission::require_permission -object_id $course_id -privilege "admin" db_1row get_course_info { } -set page_title "$course_key [_ dotlrn-catalog.course_info]" +set page_title "$course_key" set asm_name [db_string get_asm_name { } -default "[_ dotlrn-catalog.not_associated]"] set item_id [dotlrn_catalog::get_item_id -revision_id $course_id] @@ -233,7 +233,7 @@ registration { label "Registration" display_template { - Registrants
+ Registrants
@section_list.attendees@ participants , } } @@ -246,7 +246,8 @@ attendance { label "Attendance" display_template { - Attendance + Attendance
@section_list.available_slots@ available
+ Related Users
} } expenses { @@ -259,8 +260,8 @@ label "Purchases" html { align center } display_template { - Patron
- Participant
+ + Individual
Group } } Index: openacs-4/packages/dotlrn-ecommerce/www/admin/membership-add.adp =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/dotlrn-ecommerce/www/admin/membership-add.adp,v diff -u -r1.2 -r1.3 --- openacs-4/packages/dotlrn-ecommerce/www/admin/membership-add.adp 2 Jun 2005 06:39:43 -0000 1.2 +++ openacs-4/packages/dotlrn-ecommerce/www/admin/membership-add.adp 4 Jun 2005 10:05:18 -0000 1.3 @@ -1,14 +1,21 @@@title@ @context;noquote@ - -Select a patron for @user.first_names@ @user.last_name@ (@user.email@)
- - -- - - Other users related to @user.first_names@ @user.last_name@ (@user.email@)
++ + +Users related to @user.first_names@ @user.last_name@ (@user.email@)
+ + ++ + + Select a patron for @user.first_names@ @user.last_name@ (@user.email@)
++ + + -Select a patron for users @group_name@
+\ No newline at end of file + \ No newline at end of file Index: openacs-4/packages/dotlrn-ecommerce/www/admin/membership-add.tcl =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/dotlrn-ecommerce/www/admin/membership-add.tcl,v diff -u -r1.2 -r1.3 --- openacs-4/packages/dotlrn-ecommerce/www/admin/membership-add.tcl 2 Jun 2005 06:39:43 -0000 1.2 +++ openacs-4/packages/dotlrn-ecommerce/www/admin/membership-add.tcl 4 Jun 2005 10:05:18 -0000 1.3 @@ -20,6 +20,8 @@ participant_id:optional {cancel ""} + + user_ids:integer,multiple,optional } -properties { } -validate { } -errors { @@ -66,6 +68,16 @@ and (case when :patron = '' then true else lower(first_names||' '||last_name||' '||email) like '%'||lower(:patron)||'%' end) + and not user_id + in (select object_id_two + from acs_rels + where object_id_one = :user_id + and rel_type = 'patron_rel') + and not user_id + in (select object_id_one + from acs_rels + where object_id_two = :user_id + and rel_type = 'patron_rel') }] 0 {{} 0}] if { [llength $patron_list] == 1 } { @@ -99,13 +111,13 @@ } lappend validate {relationship - { $relationship != [list [list 0 $community_id]] || ![empty_string_p [template::element::get_value patron relationship_new]] } + { ![empty_string_p $relationship] || ![empty_string_p [template::element::get_value patron relationship_new]] } "Please select a relationship or enter a new one" } } else { ad_form -name "patron" -export { patron } -form { {patron_id:integer(select),optional {label "Patron"} {options {$patron_list}} - {help_text "Select a patron from the list. Can't find the patron?
Create an account and return to this form"} + {help_text "Select a patron from the list. Can't find the patron?
Create an account and return to this form"} } } @@ -115,15 +127,15 @@ } lappend validate {relationship - { $relationship != [list [list 0 $community_id]] || ![empty_string_p [template::element::get_value patron relationship_new]] } + { ![empty_string_p $relationship] || ![empty_string_p [template::element::get_value patron relationship_new]] } "Please select a relationship or enter a new one" } } -ad_form -extend -name "patron" -export { user_id community_id section_id referer } \ +ad_form -extend -name "patron" -export { user_id community_id section_id referer user_ids:multiple } \ -validate $validate \ -form { - {relationship:text(category),optional,multiple {label "Relationship"} {category_application_id $community_id} {html {size 4}} + {relationship:text(category),multiple,optional {label "Relationship"} {category_application_id $community_id} {html {size 4}} {help_text "Please select one or enter one below if not in the list"} {assign_single_p t} } @@ -153,7 +165,7 @@ } # Check if no categories were selected - if { $relationship == [list [list 0 $community_id]] } { + if { [empty_string_p $relationship] } { set relationship "" # See if user entered a new relationship and add that @@ -175,13 +187,15 @@ # ad_returnredirect [export_vars -base membership-add { user_id { confirmed_p 1 } community_id section_id referer }] if { ! [empty_string_p [template::element get_value patron proceed]] } { - ad_returnredirect [export_vars -base "[apm_package_url_from_key ecommerce]shopping-cart-add" { product_id }] + ad_returnredirect [export_vars -base "ecommerce/shopping-cart-add" { product_id { user_id $patron_id } { participant_id $user_id } }] } else { ad_returnredirect $referer } ad_script_abort } +if { ! [info exists user_ids] } { + template::list::create \ -name "patrons" \ -multirow "patrons" \ @@ -192,18 +206,52 @@ } relationship { label Relationship + display_template { + @patrons.relationship;noquote@ + } } + actions { + label "" + display_template { + Select as Patron + } + } } -db_multirow -extend { relationship } patrons patrons { - select rel_id, person__name(object_id_two) as patron - from acs_rels - where rel_type = 'patron_rel' - and object_id_one = :user_id +db_multirow -extend { relationship patron_url } patrons patrons { + select r.rel_id, u.user_id as patron_id, u.first_names||' '||u.last_name||' ('||u.email||')' as patron, 1 as direction + from acs_rels r, dotlrn_users u + where r.object_id_two = u.user_id + and r.rel_type = 'patron_rel' + and r.object_id_one = :user_id + + union + + select r.rel_id, u.user_id as patron_id, u.first_names||' '||u.last_name||' ('||u.email||')' as patron, 2 as direction + from acs_rels r, dotlrn_users u + where r.object_id_one = u.user_id + and r.rel_type = 'patron_rel' + and r.object_id_two = :user_id + and not r.object_id_one in (select object_id_two + from acs_rels r + where rel_type = 'patron_rel' + and object_id_one = :user_id) } { foreach category [category::get_mapped_categories $rel_id] { lappend relationship [category::get_name $category] } set relationship [join $relationship ", "] + + if { $direction == 1 } { + set relationship "« $relationship" + } else { + set relationship "$relationship »" + } + + set patron_url [export_vars -base "ecommerce/shopping-cart-add" { product_id { user_id $patron_id } { participant_id $user_id } }] +} + +} else { +set group_name "[person::name -person_id [lindex $user_ids 0]] to [person::name -person_id [lindex $user_ids [expr [llength $user_ids]-1]]]" } \ No newline at end of file Index: openacs-4/packages/dotlrn-ecommerce/www/admin/participant-add.adp =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/dotlrn-ecommerce/www/admin/participant-add.adp,v diff -u -r1.1 -r1.2 --- openacs-4/packages/dotlrn-ecommerce/www/admin/participant-add.adp 2 Jun 2005 06:39:43 -0000 1.1 +++ openacs-4/packages/dotlrn-ecommerce/www/admin/participant-add.adp 4 Jun 2005 10:05:18 -0000 1.2 @@ -1,9 +1,9 @@@title@ @context@ - +\ No newline at end of file + addpatron_url="@addpatron_url;noquote@" cancel="@cancel@"/> Index: openacs-4/packages/dotlrn-ecommerce/www/admin/participant-add.tcl =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/dotlrn-ecommerce/www/admin/participant-add.tcl,v diff -u -r1.1 -r1.2 --- openacs-4/packages/dotlrn-ecommerce/www/admin/participant-add.tcl 2 Jun 2005 06:39:43 -0000 1.1 +++ openacs-4/packages/dotlrn-ecommerce/www/admin/participant-add.tcl 4 Jun 2005 10:05:18 -0000 1.2 @@ -22,12 +22,13 @@ set title "" set context "" -db_1row get_section_info "select c.course_id, s.section_name, s.product_id +db_1row get_section_info "select c.course_id, c.course_name, s.section_name, s.product_id from dotlrn_ecommerce_section s, dotlrn_catalogi c, cr_items ci where s.course_id = c.item_id and ci.live_revision=c.revision_id and s.section_id = :section_id" +set title "Partipant Info for $course_name: $section_name" set context [list [list [export_vars -base course-info { course_id }] $section_name] "Participants and Patrons"] -set add_url [export_vars -base "[apm_package_url_from_key ecommerce]shopping-cart-add" { product_id }] +set add_url [export_vars -base "ecommerce/shopping-cart-add" { product_id user_id }] set addpatron_url [export_vars -base "[apm_package_url_from_key dotlrn-ecommerce]admin/membership-add" { user_id section_id community_id {referer $return_url} }] Index: openacs-4/packages/dotlrn-ecommerce/www/admin/patrons.adp =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/dotlrn-ecommerce/www/admin/patrons.adp,v diff -u -r1.1 -r1.2 --- openacs-4/packages/dotlrn-ecommerce/www/admin/patrons.adp 31 May 2005 22:04:54 -0000 1.1 +++ openacs-4/packages/dotlrn-ecommerce/www/admin/patrons.adp 4 Jun 2005 10:05:18 -0000 1.2 @@ -1,5 +1,5 @@ - Participants and Patrons +Participants and Related Users @context;noquote@ \ No newline at end of file Index: openacs-4/packages/dotlrn-ecommerce/www/admin/patrons.tcl =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/dotlrn-ecommerce/www/admin/patrons.tcl,v diff -u -r1.2 -r1.3 --- openacs-4/packages/dotlrn-ecommerce/www/admin/patrons.tcl 2 Jun 2005 06:39:43 -0000 1.2 +++ openacs-4/packages/dotlrn-ecommerce/www/admin/patrons.tcl 4 Jun 2005 10:05:18 -0000 1.3 @@ -22,28 +22,93 @@ participant { label Participant } - patron { - label Patron - } relationship { label Relationship + display_template { + @patrons.relationship;noquote@ + } } + patron { + label "Related User" + display_template { + + @patrons.patron@ +
Phone: @patrons.phone@ ++ @patrons.patron@ + + } + } + patron_p { + label "Patron for this Section" + display_template { ++ Yes + + } + html { align center } + } } db_multirow -extend { relationship } patrons patrons { - select r.rel_id, person__name(d.user_id) as participant, person__name(r.object_id_two) as patron - from acs_rels r, dotlrn_member_rels_full d - where r.object_id_one = d.user_id - and r.rel_type = 'patron_rel' - and d.community_id = (select community_id - from dotlrn_ecommerce_section - where section_id = :section_id) + select rels.rel_id, rels.patron_rel_id, rels.participant, rels.patron, rels.direction, r.rel_id as patron_p, a.phone + from ( + + select d.rel_id, + r.rel_id as patron_rel_id, + (select first_names||' '||last_name||' ('||email||')' from dotlrn_users where user_id = d.user_id) as participant, + (select first_names||' '||last_name||' ('||email||')' from dotlrn_users where user_id = r.object_id_two) as patron, + 1 as direction, + d.community_id, + r.object_id_two as patron_id + from acs_rels r, dotlrn_member_rels_full d + where r.object_id_one = d.user_id + and r.rel_type = 'patron_rel' + and d.community_id = (select community_id + from dotlrn_ecommerce_section + where section_id = :section_id) + + union + + select d.rel_id, + r.rel_id as patron_rel_id, + (select first_names||' '||last_name||' ('||email||')' from dotlrn_users where user_id = d.user_id) as participant, + (select first_names||' '||last_name||' ('||email||')' from dotlrn_users where user_id = r.object_id_one) as patron, + 2 as direction, + d.community_id, + r.object_id_one as patron_id + from acs_rels r, dotlrn_member_rels_full d + where r.object_id_two = d.user_id + and r.rel_type = 'patron_rel' + and d.community_id = (select community_id + from dotlrn_ecommerce_section + where section_id = :section_id) + and not r.object_id_one in (select r.object_id_two + from acs_rels r, dotlrn_member_rels_full d + where r.object_id_one = d.user_id + and r.rel_type = 'patron_rel' + and d.community_id = (select community_id + from dotlrn_ecommerce_section + where section_id = :section_id)) + +) rels left join acs_rels r +on (rels.rel_id = r.object_id_one and r.rel_type = 'membership_patron_rel' and rels.patron_id = r.object_id_two) +left join ec_addresses a +on (r.object_id_two = a.user_id) + + order by lower(rels.participant) } { - foreach category [category::get_mapped_categories $rel_id] { + foreach category [category::get_mapped_categories $patron_rel_id] { lappend relationship [category::get_name $category] } set relationship [join $relationship ", "] + + if { $direction == 1 } { + set relationship "$relationship »" + } else { + set relationship "« $relationship" + } } db_1row get_section_info "select c.course_id, s.section_name Index: openacs-4/packages/dotlrn-ecommerce/www/admin/process-group-purchase-confirm.adp =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/dotlrn-ecommerce/www/admin/process-group-purchase-confirm.adp,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs-4/packages/dotlrn-ecommerce/www/admin/process-group-purchase-confirm.adp 4 Jun 2005 10:05:18 -0000 1.1 @@ -0,0 +1,9 @@ ++ @title@ +@context@ + + You are about to create @num_members@ users under group @name@
+ to be paid for by @patron_name@. + + +\ No newline at end of file Index: openacs-4/packages/dotlrn-ecommerce/www/admin/process-group-purchase-confirm.tcl =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/dotlrn-ecommerce/www/admin/process-group-purchase-confirm.tcl,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs-4/packages/dotlrn-ecommerce/www/admin/process-group-purchase-confirm.tcl 4 Jun 2005 10:05:18 -0000 1.1 @@ -0,0 +1,4 @@ +# packages/dotlrn-ecommerce/www/admin/process-group-purchase-confirm.tcl + +set title "Confirm Group Purchase" +set context "" \ No newline at end of file Index: openacs-4/packages/dotlrn-ecommerce/www/admin/process-group-purchase.tcl =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/dotlrn-ecommerce/www/admin/process-group-purchase.tcl,v diff -u -r1.1 -r1.2 --- openacs-4/packages/dotlrn-ecommerce/www/admin/process-group-purchase.tcl 31 May 2005 22:04:54 -0000 1.1 +++ openacs-4/packages/dotlrn-ecommerce/www/admin/process-group-purchase.tcl 4 Jun 2005 10:05:18 -0000 1.2 @@ -7,55 +7,154 @@ @creation-date 2005-05-19 } -query { section_id:integer,notnull + + {patron ""} + {patron_id 0} + + user_id:integer,optional,notnull } -properties { page_title context } -set user_id [ad_conn user_id] +if { [info exists user_id] } { + set patron_id $user_id +} -ad_form -name process-group \ +set patron_list [linsert [db_list_of_lists patrons { + select first_names||' '||last_name||' ('||email||')', user_id + from dotlrn_users + where (case when :patron = '' + then true + else lower(first_names||' '||last_name||' '||email) like '%'||lower(:patron)||'%' end) +}] 0 {{} 0}] + +if { [llength $patron_list] == 1 } { + set form [rp_getform] + ns_set delkey $form __refreshing_p + ns_set put $form __refreshing_p 0 +} + +set maxparticipants "" +set available_slots 0 +db_0or1row participants { + select v.maxparticipants, s.community_id, s.section_name, c.course_name + from dotlrn_ecommerce_section s, ec_custom_product_field_values v, dotlrn_catalogi c, cr_items ci + where s.product_id = v.product_id + and s.section_id = :section_id + and s.course_id = c.item_id + and ci.live_revision = c.revision_id +} + +if { ![empty_string_p $maxparticipants] } { + db_1row attendees { + select count(*) as attendees + from dotlrn_member_rels_approved + where community_id = :community_id + and (rel_type = 'dotlrn_member_rel' + or rel_type = 'dotlrn_club_student_rel') + } + + set available_slots [expr $maxparticipants - $attendees] +} + +if { [empty_string_p $maxparticipants] } { + set validate { + {num_members + {$num_members > 1 } + "Please enter a value greater than 1" + } + } +} else { + set validate { + {num_members + {$num_members > 1 && $num_members <= $available_slots } + "Please enter a value from 2 to $available_slots" + } + } +} + +set next_url [export_vars -base process-group-purchase { section_id patron patron_id }] + +if { ( [empty_string_p $patron] || [llength $patron_list] == 1 ) && ! $patron_id } { + ad_form -name "process-group" -export { {patron_id 0} } -form { + {patron:text,optional {label "Search Patron"} {html {onchange "if (this.value != '') { this.form.__refreshing_p.value = 1; } else { this.form.__refreshing_p.value = 0 ; }"}} + {help_text "Enter a string to search names and email addresses.
Or Create an account and return to this form"} + } + } + + lappend validate {patron + { ! [empty_string_p $patron] } + "Please enter a search string" + } + lappend validate {patron + { [llength $patron_list] > 1 } + "No users found. Please try again" + } +} elseif { $patron_id } { + acs_user::get -user_id $patron_id -array patron_user + + ad_form -name "process-group" -export { patron patron_id } -form { + {patron_name:text(inform) {label "Patron"} {value "$patron_user(first_names) $patron_user(last_name) ($patron_user(email))"}} + } + +} else { + ad_form -name "process-group" -export { patron } -form { + {patron_id:integer(select),optional {label "Patron"} {options {$patron_list}} + {help_text "Select a patron from the list. Can't find the patron?
Create an account and return to this form"} + } + } + + lappend validate {patron_id + { $patron_id } + "Please select a patron from the list" + } +} + +ad_form -extend -name process-group \ -export { section_id } \ + -validate $validate \ + -confirm_template "process-group-purchase-confirm" \ -form { group_id:key {name:text {label "Group Name"}} {num_members:integer(text) {label "Number of attendees"}} } -new_data { # FIXME do checking of max attendees etc here -# FIXME figure out why this doesn't work in a transaction -# db_transaction { + # FIXME figure out why this doesn't work in a transaction + # db_transaction { set unique_group_name "${name}_${group_id}" - group::new -group_id $group_id -group_name $unique_group_name - set section_community_id [db_string get_community_id "select community_id from dotlrn_ecommerce_section where section_id=:section_id" -default ""] - if {[string equal "" $section_community_id]} { - # FIXME error, do something clever here - } - for { set i 1 } { $i <= $num_members } { incr i } { - array set new_user [auth::create_user \ - -username "${name} Attendee $i" \ - -email "[util_text_to_url -text ${name}-attendee-${i}]@example.com" \ - -first_names "$name" \ - -last_name "Attendee $i" \ - -nologin] -# ad_return_complaint 1 "new_user '[array get new_user]' section_community_id '${section_community_id}'" -# if {[info exists new_user(user_id)]} { -# relation_add -member_state approved dotlrn_club_student_rel $section_community_id $new_user(user_id) - relation_add relationship $group_id $section_community_id - package_exec_plsql -var_list [list [list community_id $section_community_id] [list rel_type "dotlrn_club_student_rel"] [list user_id $new_user(user_id)] [list member_state approved]] dotlrn_club_student_rel new - relation_add -member_state approved membership_rel $group_id $new_user(user_id) + group::new -group_id $group_id -group_name $unique_group_name + set section_community_id [db_string get_community_id "select community_id from dotlrn_ecommerce_section where section_id=:section_id" -default ""] + if {[string equal "" $section_community_id]} { + # FIXME error, do something clever here + } + for { set i 1 } { $i <= $num_members } { incr i } { + array set new_user [auth::create_user \ + -username "${name} Attendee $i" \ + -email "[util_text_to_url -text ${name}-attendee-${i}]@example.com" \ + -first_names "$name" \ + -last_name "Attendee $i" \ + -nologin] + # ad_return_complaint 1 "new_user '[array get new_user]' section_community_id '${section_community_id}'" + # if {[info exists new_user(user_id)]} { + # relation_add -member_state approved dotlrn_club_student_rel $section_community_id $new_user(user_id) +# package_exec_plsql -var_list [list [list community_id $section_community_id] [list rel_type "dotlrn_club_student_rel"] [list user_id $new_user(user_id)] [list member_state approved]] dotlrn_club_student_rel new + relation_add -member_state approved membership_rel $group_id $new_user(user_id) + # } + lappend new_users $new_user(user_id) + } # } - } -# } + relation_add relationship $group_id $section_community_id } -after_submit { - set course_id [db_string get_course_id " select c.course_id - from dotlrn_ecommerce_section s, dotlrn_catalogi c, cr_items ci - where s.course_id = c.item_id - and ci.live_revision=c.revision_id - and s.section_id = :section_id" -default ""] - ad_returnredirect -message "Added $num_members from $name" [export_vars -base course-info {course_id}] + set product_id [db_string get_course_id "select product_id from dotlrn_ecommerce_section where section_id = :section_id" -default ""] +# set referer [export_vars -base [ad_conn package_url]admin/course-info {course_id}] + + ad_returnredirect -message "Added $num_members from $name" [export_vars -base "ecommerce/shopping-cart-add" { product_id { user_id $patron_id } { participant_id $group_id } { item_count $num_members } }] +# ad_returnredirect -message "Added $num_members from $name" [export_vars -base membership-add { user_id {user_ids:multiple $new_users} section_id {community_id $section_community_id} referer }] } -set page_title "Add Group" +set page_title "Add Group to $course_name: $section_name" set context [list $page_title] ad_return_template \ No newline at end of file Index: openacs-4/packages/dotlrn-ecommerce/www/admin/process-purchase.adp =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/dotlrn-ecommerce/www/admin/process-purchase.adp,v diff -u -r1.2 -r1.3 --- openacs-4/packages/dotlrn-ecommerce/www/admin/process-purchase.adp 2 Jun 2005 06:39:43 -0000 1.2 +++ openacs-4/packages/dotlrn-ecommerce/www/admin/process-purchase.adp 4 Jun 2005 10:05:18 -0000 1.3 @@ -1,5 +1,5 @@- Process Purchase +@title@ @context;noquote@ Index: openacs-4/packages/dotlrn-ecommerce/www/admin/process-purchase.tcl =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/dotlrn-ecommerce/www/admin/process-purchase.tcl,v diff -u -r1.2 -r1.3 --- openacs-4/packages/dotlrn-ecommerce/www/admin/process-purchase.tcl 2 Jun 2005 06:39:43 -0000 1.2 +++ openacs-4/packages/dotlrn-ecommerce/www/admin/process-purchase.tcl 4 Jun 2005 10:05:18 -0000 1.3 @@ -19,16 +19,21 @@ } -errors { } +set title "" + if { [exists_and_not_null section_id] } { - db_1row get_section_info "select c.course_id, s.section_name, s.community_id, s.product_id + db_1row get_section_info "select c.course_id, c.course_name, + s.section_name, s.community_id, s.product_id from dotlrn_ecommerce_section s, dotlrn_catalogi c, cr_items ci where s.course_id = c.item_id and ci.live_revision=c.revision_id and s.section_id = :section_id" set context [list [list [export_vars -base course-info { course_id }] $section_name] "Process Purchase"] + set title "Select Participant for $course_name: $section_name" + if { [empty_string_p $return_url] } { set return_url [export_vars -base [ad_conn package_url]admin/course-info {course_id}] } @@ -95,8 +100,8 @@ } } - set add_url [export_vars -base "[apm_package_url_from_key ecommerce]shopping-cart-add" { product_id }] - set addpatron_url [export_vars -base "[apm_package_url_from_key dotlrn-ecommerce]admin/membership-add" { user_id section_id community_id {referer $return_url} }] + set add_url [export_vars -base "ecommerce/shopping-cart-add" { product_id }] + set addpatron_url [export_vars -base "membership-add" { user_id section_id community_id {referer $return_url} }] } set next_url [export_vars -base membership-add { section_id community_id { referer $return_url} }] \ No newline at end of file Index: openacs-4/packages/dotlrn-ecommerce/www/admin/ecommerce/checkout-2-oracle.xql =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/dotlrn-ecommerce/www/admin/ecommerce/Attic/checkout-2-oracle.xql,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs-4/packages/dotlrn-ecommerce/www/admin/ecommerce/checkout-2-oracle.xql 4 Jun 2005 10:05:18 -0000 1.1 @@ -0,0 +1,23 @@ + + + + Index: openacs-4/packages/dotlrn-ecommerce/www/admin/ecommerce/checkout-2.adp =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/dotlrn-ecommerce/www/admin/ecommerce/Attic/checkout-2.adp,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs-4/packages/dotlrn-ecommerce/www/admin/ecommerce/checkout-2.adp 4 Jun 2005 10:05:18 -0000 1.1 @@ -0,0 +1,28 @@ ++ + +oracle +8.1.6 ++ + ++ select p.no_shipping_avail_p, p.product_name, p.one_line_description, p.product_id, count(*) as quantity, u.offer_code, i.color_choice, i.size_choice, i.style_choice + from ec_orders o, ec_items i, ec_products p, (select offer_code, product_id + from ec_user_session_offer_codes usoc + where usoc.user_session_id=:user_session_id) u + where i.product_id=p.product_id + and o.order_id=i.order_id + and p.product_id= u.product_id(+) + and o.user_session_id=:user_session_id and o.order_state='in_basket' + group by p.no_shipping_avail_p, p.product_name, p.one_line_description, p.product_id, u.offer_code, i.color_choice, i.size_choice, i.style_choice + ++ Completing Your Order: Verify shopping cart contents +@context_bar;noquote@ +@ec_system_owner;noquote@ + ++ + + +Index: openacs-4/packages/dotlrn-ecommerce/www/admin/ecommerce/checkout-2.tcl =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/dotlrn-ecommerce/www/admin/ecommerce/Attic/checkout-2.tcl,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs-4/packages/dotlrn-ecommerce/www/admin/ecommerce/checkout-2.tcl 4 Jun 2005 10:05:18 -0000 1.1 @@ -0,0 +1,192 @@ +ad_page_contract { + @param address_id a stored address + @param usca_p User session started or not + + @author + @creation-date + @author ported by Jerry Asher (jerry@theashergroup.com) + @author Bart Teeuwisse (bart.teeuwisse@thecodemill.biz) + @revision-date April 20002 + +} { + address_id:optional,naturalnum + usca_p:optional +} + +# ec_redirect_to_https_if_possible_and_necessary + +# We need them to be logged in + +set user_id [ad_verify_and_get_user_id] +if {$user_id == 0} { + set return_url "[ad_conn url]" + ad_returnredirect "/register?[export_url_vars return_url]" + ad_script_abort +} + +# User sessions: +# 1. get user_session_id from cookie +# 2. if user has no session (i.e. user_session_id=0), attempt to set it if it hasn't been +# attempted before +# 3. if it has been attempted before, give them message that we can't do shopping carts +# without cookies + +set user_session_id [ec_get_user_session_id] +ec_create_new_session_if_necessary [export_url_vars address_id] + +# Make sure they have an in_basket order, otherwise they've probably +# gotten here by pushing Back, so return them to index.tcl + +set success_p [db_0or1row get_order_id_and_order_owner " + select order_id, user_id as order_owner + from ec_orders + where user_session_id = :user_session_id + and order_state='in_basket' "] +if { ! $success_p } { + + # No rows came back, so they probably got here by pushing "Back", + # so just redirect them to index.tcl + + rp_internal_redirect index + ad_script_abort +} + +if { $order_owner != $user_id } { + + # make sure the order belongs to this user_id (why? because + # before this point there was no personal information associated + # with the order (so it was fine to go by user_session_id), but + # now there is, and we don't want someone messing with their + # user_session_id cookie and getting someone else's order) + + # If they get here, either they managed to skip past checkout.tcl, + # or they messed w/their user_session_id cookie; + ad_returnredirect [ec_securelink [ec_url]checkout.tcl] + ad_script_abort +} + +# Make sure there's something in their shopping cart, otherwise +# redirect them to their shopping cart which will tell them that it's +# empty. + +if { [db_string get_ec_item_count " + select count(*) + from ec_items + where order_id=:order_id"] == 0 } { + rp_internal_redirect shopping-cart + ad_script_abort +} + +# Either address_id should be a form variable, or it should already be +# in the database for this order + +# Make sure address_id, if it exists, belongs to them, otherwise +# they've probably gotten here by form surgery, in which case send +# them back to checkout.tcl if it is theirs, put it into the database +# for this order + +# If address_id doesn't exist, make sure there is an address for this +# order, otherwise they've probably gotten here via url surgery, so +# redirect them to checkout.tcl + +if { [info exists address_id] && ![empty_string_p $address_id] } { + set n_this_address_id_for_this_user [db_string get_an_address_id " + select count(*) + from ec_addresses + where address_id = :address_id + and user_id=:user_id"] + if {$n_this_address_id_for_this_user == 0} { + ad_returnredirect [ec_securelink [ec_url]checkout] + ad_script_abort + } + + # It checks out ok + + db_dml update_ec_order_address " + update ec_orders + set shipping_address = :address_id + where order_id = :order_id" +} else { + + set address_id [db_string get_address_id " + select shipping_address + from ec_orders + where order_id=:order_id" -default ""] + if { [empty_string_p $address_id] } { + + # No shipping address is needed if the order only consists of + # soft goods not requiring shipping. + + if {[db_0or1row shipping_avail " + select p.no_shipping_avail_p, count (*) + from ec_items i, ec_products p + where i.product_id = p.product_id + and p.no_shipping_avail_p = 'f' + and i.order_id = :order_id + group by no_shipping_avail_p"]} { + ad_returnredirect [ec_securelink [ec_url]checkout] + ad_script_abort + } + } +} + +# Everything is ok now; the user has a non-empty in_basket order and +# an address associated with it, so now get the other necessary +# information + +set form_action [ec_securelink [ec_url]select-shipping] +set rows_of_items "" +set shipping_avail_p 1 + +db_foreach get_shipping_data " + select p.no_shipping_avail_p, p.product_name, p.one_line_description, p.product_id, count(*) as quantity, u.offer_code, i.color_choice, i.size_choice, i.style_choice + from ec_orders o, ec_items i, ec_products p, (select offer_code, product_id + from ec_user_session_offer_codes usoc + where usoc.user_session_id=:user_session_id) u + where i.product_id=p.product_id + and o.order_id=i.order_id + and p.product_id= u.product_id(+) + and o.user_session_id=:user_session_id and o.order_state='in_basket' + group by p.no_shipping_avail_p, p.product_name, p.one_line_description, p.product_id, u.offer_code, i.color_choice, i.size_choice, i.style_choice" { + + if { [string compare $no_shipping_avail_p "t"] == 0 } { + set shipping_avail_p 0 + } + + set option_list [list] + if { ![empty_string_p $color_choice] } { + lappend option_list "Color: $color_choice" + } + if { ![empty_string_p $size_choice] } { + lappend option_list "Size: $size_choice" + } + if { ![empty_string_p $style_choice] } { + lappend option_list "Style: $style_choice" + } + set options [join $option_list ", "] + + # Trying out the fancy new . arrays. It would be much better to + # rework this for a 2D array,multiple setup, but I don't have time + # to think about it now... + + append rows_of_items " +Please verify that the items and quantities shown below are correct. Put a 0 (zero) in the + Quantity field to remove a particular item from your order.
+ + ++ " +} + +set tax_exempt_options "" +if { [ad_parameter -package_id [ec_id] OfferTaxExemptStatusP ecommerce 0] } { + append tax_exempt_options " ++ $product_name[ec_decode $options "" "" ", $options"] +
+ [ec_price_line $product_id $user_id $offer_code]+ Yes
Is your organization tax exempt? (If so, we will ask you to + provide us with an exemption certificate.)
+ No" +} + +set context_bar [template::adp_parse [acs_root_dir]/packages/[ad_conn package_key]/www/contextbar [list context_addition [list "Completing Your Order"]]] +set ec_system_owner [ec_system_owner] +db_release_unused_handles +ad_return_template Index: openacs-4/packages/dotlrn-ecommerce/www/admin/ecommerce/checkout-2.xql =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/dotlrn-ecommerce/www/admin/ecommerce/Attic/checkout-2.xql,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs-4/packages/dotlrn-ecommerce/www/admin/ecommerce/checkout-2.xql 4 Jun 2005 10:05:18 -0000 1.1 @@ -0,0 +1,63 @@ + + ++ + Index: openacs-4/packages/dotlrn-ecommerce/www/admin/ecommerce/checkout-3-oracle.xql =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/dotlrn-ecommerce/www/admin/ecommerce/Attic/checkout-3-oracle.xql,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs-4/packages/dotlrn-ecommerce/www/admin/ecommerce/checkout-3-oracle.xql 4 Jun 2005 10:05:18 -0000 1.1 @@ -0,0 +1,23 @@ + + ++ + ++ select order_id, + user_id as order_owner + from ec_orders + where user_session_id=:user_session_id + and order_state='in_basket' + ++ + ++ select count(*) + from ec_items + where order_id=:order_id + ++ + ++ select count(*) + from ec_addresses + where address_id=:address_id + and user_id=:user_id + ++ + ++ update ec_orders set shipping_address=:address_id where order_id=:order_id + ++ + ++ select shipping_address + from ec_orders + where order_id=:order_id + ++ + ++ select p.no_shipping_avail_p, p.product_name, p.one_line_description, p.product_id, + count(*) as quantity, + u.offer_code, + i.color_choice, i.size_choice, i.style_choice + 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) + left join (select offer_code, product_id + from ec_user_session_offer_codes usoc + where usoc.user_session_id=:user_session_id) u on (p.product_id = u.product_id) + where o.user_session_id=:user_session_id and o.order_state='in_basket' + group by p.no_shipping_avail_p, p.product_name, p.one_line_description, p.product_id, u.offer_code, i.color_choice, i.size_choice, i.style_choice + ++ Index: openacs-4/packages/dotlrn-ecommerce/www/admin/ecommerce/checkout-3-postgresql.xql =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/dotlrn-ecommerce/www/admin/ecommerce/Attic/checkout-3-postgresql.xql,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs-4/packages/dotlrn-ecommerce/www/admin/ecommerce/checkout-3-postgresql.xql 4 Jun 2005 10:05:18 -0000 1.1 @@ -0,0 +1,21 @@ + + ++ + +oracle +8.1.6 ++ + ++ select ec_order_cost(:order_id) + from dual + ++ + ++ select ec_gift_certificate_balance(:user_id) + from dual + ++ Index: openacs-4/packages/dotlrn-ecommerce/www/admin/ecommerce/checkout-3.adp =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/dotlrn-ecommerce/www/admin/ecommerce/Attic/checkout-3.adp,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs-4/packages/dotlrn-ecommerce/www/admin/ecommerce/checkout-3.adp 4 Jun 2005 10:05:19 -0000 1.1 @@ -0,0 +1,24 @@ ++ + +postgresql +7.1 ++ + ++ select ec_order_cost(:order_id) + ++ + ++ select ec_gift_certificate_balance(:user_id) + ++ Completing Your Order: Verify and submit order +@context_bar;noquote@ +@ec_system_owner;noquote@ + ++ + ++ + + + +Index: openacs-4/packages/dotlrn-ecommerce/www/admin/ecommerce/checkout-3.tcl =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/dotlrn-ecommerce/www/admin/ecommerce/Attic/checkout-3.tcl,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs-4/packages/dotlrn-ecommerce/www/admin/ecommerce/checkout-3.tcl 4 Jun 2005 10:05:19 -0000 1.1 @@ -0,0 +1,165 @@ +ad_page_contract { + + Users should get here from + process-order-quantity-payment-shipping.tcl; this page just + summarizes their order before they submit it. + + @param usca_p User session begun or not + @param referer Referring page + + @author + @creation-date + @author ported by Jerry Asher (jerry@theashergroup.com) + @author revised by Bart Teeuwisse (bart.teeuwisse@thecodemill.biz) + @revision-date April 2002 + +} { + usca_p:optional + referer:optional + + user_id:integer,notnull + participant_id:integer,optional +} + +ec_redirect_to_https_if_possible_and_necessary + +# Make sure we have all their necessary info, otherwise they probably got +# here via url surgery or by pushing Back + +# 1. There should be an in_basket order for their user_session_id. +# 2. The order should have the correct user_id associated with it. +# 3. The order should contain items. +# 4. The order should have an address associated with it. +# 5. The order should have credit card and shipping method associated with it. + +# We need them to be logged in + +#set user_id [ad_verify_and_get_user_id] +if {$user_id == 0} { + set return_url "[ad_conn url]" + ad_returnredirect "/register?[export_url_vars return_url]" + ad_script_abort +} + +# Make sure they have an in_basket order, otherwise they've probably +# gotten here by pushing Back, so return them to index.tcl + +set user_session_id [ec_get_user_session_id] +ec_create_new_session_if_necessary +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 ""] +if { [empty_string_p $order_id] } { + + # Then they probably got here by pushing "Back", so just redirect + # them to index.tcl + ns_log Notice "checkout-3.tcl ref(55): user_id:$user_id, user_session_id:$user_session_id, order_id is empty, redirecting to index" + rp_internal_redirect index + ad_script_abort +} + +# Make sure there's something in their shopping cart, otherwise +# redirect them to their shopping cart which will tell them that it's +# empty. + +if { [db_string get_ec_item_count " + select count(*) + from ec_items + where order_id=:order_id"] == 0 } { + ns_log Notice "checkout-3.tcl ref(68): order_id:$order_id, no items in basket, redirecting to shopping-cart" + rp_internal_redirect shopping-cart + ad_script_abort +} + +# Make sure the order belongs to this user_id, otherwise they managed +# to skip past checkout*.tcl, or they messed w/their user_session_id +# cookie + +set order_owner [db_string get_order_owner " + select user_id + from ec_orders + where order_id=:order_id"] +if { $order_owner != $user_id } { + ns_log Notice "checkout-3.tcl ref(82): order_owner:$order_owner not matching order_id:$order_id, redirecting to checkout" + rp_internal_redirect checkout + ad_script_abort +} + +# Make sure there is an address for this order, otherwise they've +# probably gotten here via url surgery, so redirect them to +# checkout.tcl + +# set address_id [db_string get_address_id " +# select shipping_address +# from ec_orders +# where order_id=$order_id" -default ""] +# if { [empty_string_p $address_id] } { + +# # No shipping address is needed if the order only consists of soft +# # goods not requiring shipping. + +# if {[db_0or1row shipping_avail " +# select p.no_shipping_avail_p, count (*) +# from ec_items i, ec_products p +# where i.product_id = p.product_id +# and p.no_shipping_avail_p = 'f' +# and i.order_id = :order_id +# group by no_shipping_avail_p"]} { +# ns_log Notice "checkout-3.tcl ref(110): no shipping address needed for order_id:$order_id, redirecting to checkout" +# ad_returnredirect [ec_securelink [ec_url]checkout] +# ad_script_abort +# } +# } + +# Make sure there is a credit card (or that the +# gift_certificate_balance covers the cost) and a shipping method for +# this order, otherwise they've probably gotten here via url surgery, +# so redirect them to checkout-2.tcl + +set creditcard_id [db_string get_creditcard_id " + select creditcard_id + from ec_orders + where order_id=:order_id" -default ""] +if { [empty_string_p $creditcard_id] } { + + # Ec_order_cost returns price + shipping + tax - gift_certificate + # BUT no gift certificates have been applied to in_basket orders, + # so this just returns price + shipping + tax + + set order_total_price_pre_gift_certificate [db_string get_pre_gc_price " + select ec_order_cost(:order_id) + from dual"] + set gift_certificate_balance [db_string get_gc_balance " + select ec_gift_certificate_balance(:user_id) + from dual"] + if { $gift_certificate_balance < $order_total_price_pre_gift_certificate } { + set gift_certificate_covers_cost_p "f" + } else { + set gift_certificate_covers_cost_p "t" + } +} + +# set shipping_method [db_string get_shipping_method " +# select shipping_method +# from ec_orders +# where order_id=:order_id" -default ""] +# if { [empty_string_p $shipping_method] || ([empty_string_p $creditcard_id] && [exists_and_equal gift_certificate_covers_cost_p "f"]) } { +# ns_log Notice "checkout-3.tcl ref(146): no shipping method for order_id:$order_id. Redirecting to checkout-2" +# rp_internal_redirect checkout-2 +# ad_script_abort +# } + +# Done with all the checks. Their order is ready to go! Now show +# them a summary before they submit their order +#if {[exists_and_equal referer "checkout-one-form-2"]} { + set display_progress "f" +#} else { +# set display_progress "t" +#} + +set order_summary [ec_order_summary_for_customer $order_id $user_id] +set context_bar [template::adp_parse [acs_root_dir]/packages/[ad_conn package_key]/www/contextbar [list context_addition [list "Completing Your Order"]]] +set ec_system_owner [ec_system_owner] +db_release_unused_handles Index: openacs-4/packages/dotlrn-ecommerce/www/admin/ecommerce/checkout-3.xql =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/dotlrn-ecommerce/www/admin/ecommerce/Attic/checkout-3.xql,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs-4/packages/dotlrn-ecommerce/www/admin/ecommerce/checkout-3.xql 4 Jun 2005 10:05:19 -0000 1.1 @@ -0,0 +1,54 @@ + + ++ + Index: openacs-4/packages/dotlrn-ecommerce/www/admin/ecommerce/checkout-one-form-2-oracle.xql =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/dotlrn-ecommerce/www/admin/ecommerce/Attic/checkout-one-form-2-oracle.xql,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs-4/packages/dotlrn-ecommerce/www/admin/ecommerce/checkout-one-form-2-oracle.xql 4 Jun 2005 10:05:19 -0000 1.1 @@ -0,0 +1,52 @@ + + + ++ + ++ select order_id + from ec_orders + where user_session_id=:user_session_id + and order_state='in_basket' + ++ + ++ select count(*) + from ec_items + where order_id=:order_id + ++ + ++ select user_id + from ec_orders + where order_id=:order_id + ++ + ++ select shipping_address + from ec_orders + where order_id=$order_id + ++ + ++ select creditcard_id + from ec_orders + where order_id=:order_id + ++ + ++ select shipping_method + from ec_orders + where order_id=:order_id + ++ + ++ insert into ec_problems_log + (problem_id, problem_date, gift_certificate_id, problem_details) + values + (ec_problem_id_sequence.nextval, sysdate, :gift_certificate_id, :prob_details) + ++ + ++ select i.item_id, i.product_id, u.offer_code + from ec_items i, (select * + from ec_user_session_offer_codes usoc + where usoc.user_session_id = :user_session_id) u + where i.product_id=u.product_id(+) + and i.order_id=:order_id + ++ + ++ select nvl(base_shipping_cost,0) + from ec_admin_settings + ++ + ++ select nvl(add_exp_base_shipping_cost,0) + from ec_admin_settings + ++ + ++ select ec_tax(0,:order_shipping_cost,:order_id) + from dual + ++ + + Index: openacs-4/packages/dotlrn-ecommerce/www/admin/ecommerce/checkout-one-form-2-postgresql.xql =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/dotlrn-ecommerce/www/admin/ecommerce/Attic/checkout-one-form-2-postgresql.xql,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs-4/packages/dotlrn-ecommerce/www/admin/ecommerce/checkout-one-form-2-postgresql.xql 4 Jun 2005 10:05:19 -0000 1.1 @@ -0,0 +1,70 @@ + + ++ select ec_gift_certificate_balance(:user_id) + from dual + ++ Index: openacs-4/packages/dotlrn-ecommerce/www/admin/ecommerce/checkout-one-form-2.tcl =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/dotlrn-ecommerce/www/admin/ecommerce/Attic/checkout-one-form-2.tcl,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs-4/packages/dotlrn-ecommerce/www/admin/ecommerce/checkout-one-form-2.tcl 4 Jun 2005 10:05:19 -0000 1.1 @@ -0,0 +1,788 @@ +ad_page_contract { + + @param billing_address_id + @param bill_to_first_names + @param bill_to_last_name + @param bill_to_phone + @param bill_to_phone_time:optional + @param bill_to_line1:notnull + @param bill_to_line2 + @param bill_to_city + @param bill_to_usps_abbrev:optional + @param bill_to_full_state_name:optional + @param bill_to_zip_code:optional + @param bill_to_country_code + + @param claim_check for gift certificate + @param creditcard_expire_1:optional + @param creditcard_expire_2:optional + @param creditcard_number:optional + @param creditcard_type:optional + @param creditcard_id:optional + @param customer_can_use_old_credit_cards:optional + @param old_cards_to_choose_from:optional + + @param certificate_amount:optional + @param order_total_price_pre_gift_certificate:optional + + @param shipping_address_id:optional,naturalnum + @param ship_to_first_names:optional + @param ship_to_last_name:optional + @param ship_to_phone:optional + @param ship_to_phone_time:optional + @param ship_to_line1:optional + @param ship_to_line2:optional + @param ship_to_city:optional + @param ship_to_usps_abbrev:optional + @param ship_to_full_state_name:optional + @param ship_to_zip_code:optional + @param ship_to_country_code:optional + + @param shipping_method:optional + @param shipping_options:optional + + @param tax_exempt_p:optional + @param usca_p:optional + @param value_currency_code:optional + + @author + @creation-date April 2002 + @author ported by Jerry Asher (jerry@theashergroup.com) + @author revised by Bart Teeuwisse+ + +postgresql +7.1 ++ + ++ insert into ec_problems_log + (problem_id, problem_date, problem_details) + values + (ec_problem_id_sequence.nextval, current_timestamp,:prob_details ) + ++ + ++ update ec_gift_certificates set user_id=:user_id, claimed_date=current_timestamp where gift_certificate_id=:gift_certificate_id + ++ + ++ insert into ec_problems_log + (problem_id, problem_date, gift_certificate_id, problem_details) + values + (ec_problem_id_sequence.nextval, current_timestamp, :gift_certificate_id, :prob_details) + ++ + ++ select i.item_id, i.product_id, u.offer_code + from ec_items i + left join (select * + from ec_user_session_offer_codes usoc + where usoc.user_session_id=:user_session_id) u on (i.product_id=u.product_id) + where i.order_id=:order_id + ++ + ++ select coalesce(base_shipping_cost,0) + from ec_admin_settings + ++ + ++ select coalesce(add_exp_base_shipping_cost,0) + from ec_admin_settings + ++ + ++ select ec_tax(0,:order_shipping_cost,:order_id) + ++ + ++ select ec_gift_certificate_balance(:user_id) + ++ @author combined by Torben Brosten + @creation-date March 2004 + +} { + + billing_address_id:optional,naturalnum + bill_to_first_names + bill_to_last_name + bill_to_phone + bill_to_phone_time:optional + bill_to_line1:notnull + bill_to_line2:optional + bill_to_city + bill_to_usps_abbrev:optional + bill_to_full_state_name:optional + bill_to_zip_code:optional + bill_to_country_code + + claim_check:optional + creditcard_expire_1:optional + creditcard_expire_2:optional + creditcard_number:optional + creditcard_type:optional + creditcard_id:optional + customer_can_use_old_credit_cards:optional + old_cards_to_choose_from:optional + + certificate_amount:optional + order_total_price_pre_gift_certificate:optional + + shipping_address_id:optional,naturalnum + ship_to_first_names:optional + ship_to_last_name:optional + ship_to_phone:optional + ship_to_phone_time:optional + ship_to_line1:optional + ship_to_line2:optional + ship_to_city:optional + ship_to_usps_abbrev:optional + ship_to_full_state_name:optional + ship_to_zip_code:optional + ship_to_country_code:optional + + shipping_method:optional + shipping_options:optional + + tax_exempt_p:optional + usca_p:optional + value_currency_code:optional + + user_id:integer,notnull + participant_id:integer,optional +} + +# We need them to be logged in + +#set user_id [ad_conn user_id] +if {$user_id == 0} { + ns_log Notice "checkout-one-form-2.tcl,ref(137): user_id is 0 which should never happen, redirecting user." + rp_form_put return_url "[ad_conn url]?[export_entire_form_as_url_vars]" + rp_internal_redirect "/register" + ad_script_abort +} + +# eventually evolve this so checks come first, then ad_return_complaints +# ie show complaints after all input has been checked, to provide thorough feedback to user + + +if {![info exists bill_to_country_code]} { + ad_return_complaint 1 [list [list bill_to_country_code "billing country"]] + ad_script_abort +} elseif { [string equal $bill_to_country_code "US"] } { + set possible_exception_list [list [list bill_to_first_names "billing first name"] [list bill_to_last_name "billing last name"] [list bill_to_line1 "billing street address"] [list bill_to_city "billing city"] [list bill_to_usps_abbrev "billing state"] [list bill_to_zip_code "billing zip code"] [list bill_to_phone "billing telephone number"]] +} else { + set possible_exception_list [list [list bill_to_first_names "billing first name"] [list bill_to_last_name "billing last name"] [list bill_to_line1 "billing street address"] [list bill_to_city "billing city"] [list bill_to_country_code "billing country"] [list bill_to_phone "billing telephone number"]] +} +set exception_count 0 +set exception_text "" + +foreach possible_exception $possible_exception_list { + if { ![info exists [lindex $possible_exception 0]] || [empty_string_p [set [lindex $possible_exception 0]]] } { + incr exception_count + append exception_text " A [lindex $possible_exception 1] is required. " + } +} + +if { $exception_count > 0 } { + ns_log Notice "checkout-one-form-2.tcl,ref(127): $exception_count form input exception(s) for user $user_id" + ad_return_complaint $exception_count $exception_text + ad_script_abort +} + + +# Make sure they have an in_basket order unless they are ordering a +# gift certificate, otherwise they've probably gotten here by pushing +# Back, so return them to index.tcl + +set user_session_id [ec_get_user_session_id] +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 ""] + +if { [empty_string_p $order_id] } { + + # They probably got here by pushing "Back", so just redirect + # them to index.tcl + ns_log Notice "checkout-one-form-2.tcl,ref(157): order_id is empty, redirecting user $user_id." + rp_internal_redirect index + ad_script_abort +} +ns_log Notice "checkout-one-form-2.tcl,ref(161): processing user_id: $user_id, order_id: $order_id" + +# start processing the info from checkout-one-form + + +# check addresses against existing addresses, if any (bill_to_address_id_exists_p, ship_to_address_id_exists_p +# if there's any difference, then assume it's a new address, otherwise, use existing address_id + +# for billing address + +regsub -all { +} $bill_to_first_names " " bill_to_first_names +regsub -all { +} $bill_to_last_name " " bill_to_last_name +set bill_to_attn "[string trim $bill_to_first_names] [string trim $bill_to_last_name]" + +if { [value_if_exists billing_address_id] > 0} { + + # This is an existing address that might have been edited + + set address_id $billing_address_id + + # retrieve a saved address + set billing_address_exists [db_0or1row select_address " + select attn, line1, line2, city, usps_abbrev, zip_code, phone, country_code, full_state_name, phone_time + from ec_addresses + where address_id=:address_id + and user_id=:user_id"] + + if { $billing_address_exists == 0 } { + # They probably got here by playing with the billing_address_id number + # have them login again, to make sure they should even have access to current session + + ec_user_session_logout + ns_log Notice "checkout-one-form-2.tcl,ref(193): billing_address_id mismatch. logging out user $user_id." + } + + # compare billing address with address from db + + set combined_billing_address "${bill_to_attn}${bill_to_line1}${bill_to_line2}${bill_to_city}${bill_to_usps_abbrev}${bill_to_zip_code}${bill_to_phone}${bill_to_country_code}${bill_to_full_state_name}${bill_to_phone_time}" + set combined_address "${attn}${line1}${line2}${city}${usps_abbrev}${zip_code}${phone}${country_code}${full_state_name}${phone_time}" + regsub -all { } $combined_billing_address "" combined_billing_address + regsub -all { } $combined_address "" combined_address + if { [string equal $combined_billing_address $combined_address] != 1 } { + set new_address "t" + } else { + # billing addresses same + set new_address "f" + } +} else { + # no billing address id exists + set new_address "t" +} + +if { [string equal $new_address "t"] } { + # This is a new address which requires a new address_id. + set address_type "billing" + set attn $bill_to_attn + set line1 $bill_to_line1 + set line2 $bill_to_line2 + set city $bill_to_city + if {[info exists bill_to_usps_abbrev]} { + set usps_abbrev $bill_to_usps_abbrev + } else { + # billing address, bill_to_usps_abbrev does not exist + set usps_abbrev "" + } + if {[info exists bill_to_zip_code]} { + set zip_code [string range $bill_to_zip_code 0 9] + } else { + set zip_code "" + } + set phone $bill_to_phone + set country_code $bill_to_country_code + set full_state_name $bill_to_full_state_name + set phone_time $bill_to_phone_time + set address_id [db_nextval ec_address_id_sequence] + db_transaction { + db_dml insert_new_address " + insert into ec_addresses + (address_id, user_id, address_type, attn, line1, line2, city, usps_abbrev, full_state_name, zip_code, country_code, phone, phone_time) + values + (:address_id, :user_id, :address_type, :attn,:line1,:line2,:city,:usps_abbrev,:full_state_name,:zip_code,:country_code,:phone,:phone_time)" + } + # ec_orders does not track billing address directly, so won't insert an address_id to it. +} + +set billing_address_id $address_id + +# Check if the order requires shipping + +if {[db_0or1row shipping_avail " + select p.no_shipping_avail_p + from ec_items i, ec_products p + where i.product_id = p.product_id + and p.no_shipping_avail_p = 'f' + and i.order_id = :order_id + group by no_shipping_avail_p"]} { + + set shipping_required "t" + +} else { + set shipping_required "f" +} + +set combined_shipping_address "" + +if { [string equal $shipping_required "t"] } { +# when ship_to_address info is empty, fill it with the bill_to address info and set ship_to_address_id_exists_p false + + # get the shipping_address_id used by checkout-one-form.tcl + set shipping_address_ids [db_list get_shipping_address_ids " + select address_id +` from ec_addresses + where user_id=:user_id + and address_type = 'shipping'" ] + set shipping_address_id [ec_max_of_list $shipping_address_ids] + + + # Update the shipping address of the order + regsub -all { +} $ship_to_first_names " " ship_to_first_names + regsub -all { +} $ship_to_last_name " " ship_to_last_name + set ship_to_attn "[string trim $ship_to_first_names] [string trim $ship_to_last_name]" + + # lets combine the shipping address, for comparison to any existing default, and to see if there is anything to work with + set combined_shipping_address "${ship_to_attn}${ship_to_line1}${ship_to_line2}${ship_to_city}${ship_to_usps_abbrev}${ship_to_zip_code}${ship_to_phone}${ship_to_country_code}${ship_to_full_state_name}${ship_to_phone_time}" + regsub -all { } $combined_shipping_address "" combined_shipping_address + + # check addresses against existing addresses, if any (bill_to_address_id_exists_p, ship_to_address_id_exists_p + # if there's any difference, then assume it's a new address, otherwise, use existing address_id + + if { $shipping_address_id > 0 } { + + # Shipping address was presented to user, the existing address info might have been edited + set address_id $shipping_address_id + + # retrieve a saved address + set shipping_address_exists [db_0or1row select_address " + select attn, line1, line2, city, usps_abbrev, zip_code, phone, country_code, full_state_name, phone_time + from ec_addresses + where address_id=:address_id + and user_id=:user_id"] + + if { $shipping_address_exists == 0 } { + # They probably got here by playing with the shipping_address_id number + # have them login again, to make sure they should even have access to current session + ns_log Notice "checkout-one-form-2.tcl,ref(305). shipping_address_id is 0 which should never happen. logging out user $user_id" + ec_user_session_logout + } + + # compare shipping address with address from db + + set combined_address "${attn}${line1}${line2}${city}${usps_abbrev}${zip_code}${phone}${country_code}${full_state_name}${phone_time}" + regsub -all { } $combined_address "" combined_address + + if { [string equal $combined_shipping_address $combined_address] != 1 } { + set new_address "t" + } else { + # addresses are the same + set new_address "f" + } + + } else { + # no previous shipping address, so address must be new + set new_address "t" + + } + + if { [string equal $new_address "t"] } { + + if { [string length $combined_shipping_address] < 15 } { + # shipping address must be blank, replace with billing address + + set ship_to_attn $bill_to_attn + set ship_to_line1 $bill_to_line1 + set ship_to_line2 $bill_to_line2 + set ship_to_city $bill_to_city + if {[info exists bill_to_usps_abbrev]} { + set ship_to_usps_abbrev $bill_to_usps_abbrev + } else { + set ship_to_usps_abbrev "" + } + if {[info exists bill_to_zip_code]} { + set ship_to_zip_code $bill_to_zip_code + } else { + set ship_to_zip_code "" + } + set ship_to_phone $bill_to_phone + set ship_to_country_code $bill_to_country_code + set ship_to_full_state_name $bill_to_full_state_name + set ship_to_phone_time $bill_to_phone_time + } + + # This is a new address which requires an address_id. + set address_type "shipping" + set attn $ship_to_attn + set line1 $ship_to_line1 + set line2 $ship_to_line2 + set city $ship_to_city + set usps_abbrev $ship_to_usps_abbrev + set zip_code [string range $ship_to_zip_code 0 9] + set phone $ship_to_phone + set country_code $ship_to_country_code + set full_state_name $ship_to_full_state_name + set phone_time $ship_to_phone_time + set address_id [db_nextval ec_address_id_sequence] + db_transaction { + db_dml insert_new_address " + insert into ec_addresses + (address_id, user_id, address_type, attn, line1, line2, city, usps_abbrev, full_state_name, zip_code, country_code, phone, phone_time) + values + (:address_id, :user_id, :address_type, :attn,:line1,:line2,:city,:usps_abbrev,:full_state_name,:zip_code,:country_code,:phone,:phone_time)" + } + } + + # Update the shipping address of the order + + db_dml set_shipping_on_order " + update ec_orders + set shipping_address = :address_id + where order_id = :order_id" +} + +# See if there's a gift certificate with a claim check + +if {[info exists claim_check] && ![empty_string_p $claim_check]} { + set gift_certificate_id [db_string get_gc_id " + select gift_certificate_id + from ec_gift_certificates + where claim_check=:claim_check" -default ""] + if { [empty_string_p $gift_certificate_id] } { + ad_return_complaint 1 " +The claim check you have entered is invalid. Please re-check it.
+The claim check is case sensitive; enter it exactly as shown on your gift certificate.
" + set prob_details " + Incorrect gift certificate claim check entered at [ad_conn url]. + Claim check entered: $claim_check by user ID: $user_id. + They may have just made a typo but if this happens repeatedly from the same IP address ([ns_conn peeraddr]) you may wish to look into this." + db_dml insert_error_failed_gc_claim " + insert into ec_problems_log + (problem_id, problem_date, problem_details) + values + (ec_problem_id_sequence.nextval, sysdate,:prob_details )" + ad_script_abort + } + + # There is a gift certificate with that claim check; + # now check whether it's already been claimed + # and, if so, whether it was claimed by this user + + db_1row get_gc_user_id " + select user_id as gift_certificate_user_id, amount + from ec_gift_certificates + where gift_certificate_id = :gift_certificate_id" + + if { [empty_string_p $gift_certificate_user_id ] } { + + # Then no one has claimed it, so go ahead and assign it to them + + db_dml update_ec_cert_set_user " + update ec_gift_certificates + set user_id=:user_id, claimed_date = sysdate + where gift_certificate_id = :gift_certificate_id" + set title "Gift Certificate Claimed" + set certificate_added_p "true" + } else { + + # It's already been claimed. See if it was claimed by a different + # user and, if so, record the problem + + if { $user_id != $gift_certificate_user_id } { + + set prob_details " + User ID $user_id tried to claim gift certificate $gift_certificate_id at [ad_conn url], but it had already been claimed by User ID $gift_certificate_id." + + db_dml insert_other_claim_prob " + insert into ec_problems_log + (problem_id, problem_date, gift_certificate_id, problem_details) + values + (ec_problem_id_sequence.nextval, sysdate, :gift_certificate_id, :prob_details)" + } + + set title "Gift Certificate Already Claimed" + set certificate_added_p "false" + } +} + + +# following mainly from process-order-quanity-shipping.tcl + +# update shipping method + +# 1. Update the shipping method and tax status + +if {[info exists shipping_gateway] && [string equal $shipping_gateway "true"]} { + + # A shipping gateway has been used. The shipping method contains + # both the shipping service level and the associated total + # charges. + + array set shipping_service_and_rate $shipping_method + set shipping_method $shipping_service_and_rate(service_description) + set order_shipping_cost $shipping_service_and_rate(total_charges) +} + +if {![info exists tax_exempt_p]} { + set tax_exempt_p "f" +} +if {[empty_string_p $tax_exempt_p]} { + set tax_exempt_p "f" +} + +if {![info exists shipping_method]} { + # shipping method does not exist + set shipping_method "" +} + +db_dml update_shipping_method " + update ec_orders + set shipping_method = :shipping_method, tax_exempt_p = :tax_exempt_p + where order_id = :order_id" + +# 2. Put the prices into ec_items + +# Set some things to use as arguments when setting prices + +if { [ad_parameter -package_id [ec_id] UserClassApproveP ecommerce] } { + set additional_user_class_restriction "and user_class_approved_p = 't'" +} else { + set additional_user_class_restriction "and (user_class_approved_p is null or user_class_approved_p='t')" +} + +set user_class_id_list [db_list get_list_user_classes " + select user_class_id + from ec_user_class_user_map + where user_id = :user_id $additional_user_class_restriction"] + +if {[info exists shipping_gateway] && [string equal $shipping_gateway "true"]} { + + # A shipping gateway has been used to calculate the total shipping + # charges so there is no to calculate the charges per item. + + set default_shipping_per_item 0 + set weight_shipping_cost 0 + set add_exp_amount_per_item 0 + set add_exp_amount_by_weight 0 +} else { + if {![info exists shipping_method]} { + # shipping method does not exist + set shipping_method "" + } + + if { $shipping_method != "pickup" && $shipping_method != "no shipping" } { + db_1row get_shipping_per_item " + select default_shipping_per_item, weight_shipping_cost + from ec_admin_settings" + db_1row get_exp_amt_peritem " + select add_exp_amount_per_item, add_exp_amount_by_weight + from ec_admin_settings" + } else { + set default_shipping_per_item 0 + set weight_shipping_cost 0 + set add_exp_amount_per_item 0 + set add_exp_amount_by_weight 0 + } +} +set usps_abbrev [db_string get_usps_abbrev " + select usps_abbrev + from ec_addresses + where address_id = :address_id" -default ""] +if { ![empty_string_p $usps_abbrev] && [string equal $tax_exempt_p "f"] } { + if { [db_0or1row get_tax_rate " + select tax_rate, shipping_p + from ec_sales_tax_by_state + where usps_abbrev = :usps_abbrev"] == 0 } { + set tax_rate 0 + set shipping_p f + } +} else { + set tax_rate 0 + set shipping_p f +} + +# These will be updated as we loop through the items + +set total_item_shipping_tax 0 +set total_item_price_tax 0 + +db_foreach get_items_in_cart " + select i.item_id, i.product_id, u.offer_code + from ec_items i, (select * + from ec_user_session_offer_codes usoc + where usoc.user_session_id = :user_session_id) u + where i.product_id=u.product_id(+) + and i.order_id=:order_id" { + + set everything [ec_price_price_name_shipping_price_tax_shipping_tax_for_one_item $product_id $offer_code $item_id $order_id $user_class_id_list \ + $shipping_method $default_shipping_per_item $weight_shipping_cost $add_exp_amount_per_item $add_exp_amount_by_weight $tax_rate $shipping_p] + set total_item_shipping_tax [expr $total_item_shipping_tax + [lindex $everything 4]] + set total_item_price_tax [expr $total_item_price_tax + [lindex $everything 3]] + set price_charged [lindex $everything 0] + set price_name [lindex $everything 1] + set shipping_charged [lindex $everything 2] + set tax_charged [lindex $everything 3] + set shipping_tax [lindex $everything 4] + + db_dml update_ec_items " + update ec_items + set price_charged = round(:price_charged,2), price_name = :price_name, shipping_charged = round(:shipping_charged,2), + price_tax_charged = round(:tax_charged,2), shipping_tax_charged = round(:shipping_tax,2) + where item_id = :item_id" +} + +# 3. Determine base shipping cost & put it into ec_orders + +if {![info exists shipping_gateway]} { + + if {![info exists shipping_method]} { + # shipping_method does not exist + set shipping_method "" + } + + if { $shipping_method != "pickup" && $shipping_method != "no shipping" } { + set order_shipping_cost [db_string get_base_ship_cost " + select nvl(base_shipping_cost,0) + from ec_admin_settings"] + } else { + set order_shipping_cost 0 + } + + # Add on the extra base cost for express shipping, if appropriate + + if { [string equal $shipping_method "express"] } { + set add_exp_base_shipping_cost [db_string get_exp_base_cost " + select nvl(add_exp_base_shipping_cost,0) + from ec_admin_settings"] + set order_shipping_cost [expr $order_shipping_cost + $add_exp_base_shipping_cost] + } +} + +set tax_on_order_shipping_cost [db_string get_shipping_tax " + select ec_tax(0,:order_shipping_cost,:order_id) + from dual"] + +db_dml set_shipping_charges " + update ec_orders + set shipping_charged = round(:order_shipping_cost,2), shipping_tax_charged = round(:tax_on_order_shipping_cost,2) + where order_id=:order_id" + +# following mainly from process-payment.tcl + +# Now do error checking; It is required that either +# (a) their gift_certificate_balance covers the total order price, or +# (b) they've selected a previous credit card (and creditcard_number is null, +# otherwise we assume they want to use a new credit card), or +# (c) *all* of the credit card information for a new card has been filled in + +# we only want price and shipping from this (to determine whether +# gift_certificate_balance covers cost) + +set price_shipping_gift_certificate_and_tax [ec_price_shipping_gift_certificate_and_tax_in_an_order $order_id] +set order_total_price_pre_gift_certificate [expr [lindex $price_shipping_gift_certificate_and_tax 0] + [lindex $price_shipping_gift_certificate_and_tax 1]] +set gift_certificate_balance [db_string get_gc_balance " + select ec_gift_certificate_balance(:user_id) + from dual"] +if { $gift_certificate_balance >= $order_total_price_pre_gift_certificate } { + set gift_certificate_covers_cost_p "t" +} else { + set gift_certificate_covers_cost_p "f" +} + +if { [info exists creditcard_number] } { + + # get rid of spaces and dashes + + regsub -all -- "-" $creditcard_number "" creditcard_number + regsub -all " " $creditcard_number "" creditcard_number +} + +if { [string equal $gift_certificate_covers_cost_p "f"] } { + + if { ![info exists creditcard_id] || ([info exists creditcard_number] && ![empty_string_p $creditcard_number]) } { + if { ![info exists creditcard_number] || [empty_string_p $creditcard_number] } { + + # Then they haven't selected a previous credit card nor + # have they entered new credit card info + + ad_return_complaint 1 "A credit card is required to complete this order." + ad_script_abort + } else { + + # Then they are using a new credit card and we just have + # to check that they got it all right + + set exception_count 0 + set exception_text "" + + if { [regexp {[^0-9]} $creditcard_number] } { + + # I've already removed spaces and dashes, so only + # numbers should remain + + incr exception_count + append exception_text " The credit card number contains invalid characters." + } + + if { ![info exists creditcard_type] || [empty_string_p $creditcard_type] } { + incr exception_count + append exception_text " The credit card type is unknown." + } + + # make sure the credit card type is right & that it has + # the right number of digits + + set additional_count_and_text [ec_creditcard_precheck $creditcard_number $creditcard_type] + set exception_count [expr $exception_count + [lindex $additional_count_and_text 0]] + append exception_text [lindex $additional_count_and_text 1] + + if { ![info exists creditcard_expire_1] || [empty_string_p $creditcard_expire_1] || ![info exists creditcard_expire_2] || [empty_string_p $creditcard_expire_2] } { + incr exception_count + append exception_text " A full credit card expiration date (month and year) is required." + } + + if { $exception_count > 0 } { + ns_log Notice "checkout-one-form-2.tcl,ref(683): $exception_count form input exception(s) for user $user_id" + ad_return_complaint $exception_count $exception_text + ad_script_abort + } + + # A valid credit card number has been provided and thus a + # billing address must exist. + + if {![info exists billing_address_id] || ([info exists billing_address_id] && [empty_string_p $billing_address_id])} { + ad_return_complaint 1 " A billing address is required. " + ad_script_abort + } + } + } else { + + # they're using an old credit card, although we should make + # sure they didn't submit to us someone else's creditcard_id + # or a blank creditcard_id + + if { [empty_string_p $creditcard_id] } { + + # Probably form surgery + + ad_returnredirect [export_vars -base checkout-2 { user_id participant_id }] + ad_script_abort + } + + set creditcard_owner [db_string get_cc_owner " + select user_id + from ec_creditcards + where creditcard_id=:creditcard_id" -default ""] + if { $user_id != $creditcard_owner } { + + # Probably form surgery + + ad_returnredirect [export_vars -base checkout-2 { user_id participant_id }] + ad_script_abort + } + + # A valid credit card number has been provided and thus a + # billing address must exist. + + if {![info exists billing_address_id] || ([info exists billing_address_id] && [empty_string_p $billing_address_id])} { + ad_return_complaint 1 "A billing address is required. " + ad_script_abort + } + + } +} + +# Everything is ok now; the user has a non-empty in_basket order and +# an address associated with it, so now insert credit card info if +# needed + +db_transaction { + # If gift_certificate doesn't cover cost, either insert or update + # credit card + if { [string equal $gift_certificate_covers_cost_p "f"] } { + if { ![info exists creditcard_number] || [empty_string_p $creditcard_number] } { + + # Using pre-existing credit card + + db_dml use_existing_cc_for_order " + update ec_orders + set creditcard_id=:creditcard_id + where order_id=:order_id" + db_dml update_cc_address " + update ec_creditcards + set billing_address = :billing_address_id + where creditcard_id = :creditcard_id" + } else { + + # Using new credit card + + set creditcard_id [db_nextval ec_creditcard_id_sequence] + set cc_no [string range $creditcard_number [expr [string length $creditcard_number] -4] [expr [string length $creditcard_number] -1]] + set expiry "$creditcard_expire_1/$creditcard_expire_2" + db_dml insert_new_cc " + insert into ec_creditcards + (creditcard_id, user_id, creditcard_number, creditcard_last_four, creditcard_type, creditcard_expire, billing_address) + values + (:creditcard_id, :user_id, :creditcard_number, :cc_no , :creditcard_type, :expiry, :billing_address_id)" + db_dml update_order_set_cc " + update ec_orders + set creditcard_id=:creditcard_id + where order_id=:order_id" + } + } else { + + # Make creditcard_id be null (which it might not be if this isn't + # their first time along this path) + + db_dml set_null_cc_in_order " + update ec_orders + set creditcard_id=null + where order_id=:order_id" + } +} + +db_release_unused_handles +#rp_form_put url checkout-one-form-2 +#rp_internal_redirect checkout-3.tcl +ad_returnredirect [export_vars -base checkout-3.tcl { {url checkout-one-form-2} user_id participant_id }] Index: openacs-4/packages/dotlrn-ecommerce/www/admin/ecommerce/checkout-one-form-2.xql =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/dotlrn-ecommerce/www/admin/ecommerce/Attic/checkout-one-form-2.xql,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs-4/packages/dotlrn-ecommerce/www/admin/ecommerce/checkout-one-form-2.xql 4 Jun 2005 10:05:19 -0000 1.1 @@ -0,0 +1,219 @@ + + ++ + Index: openacs-4/packages/dotlrn-ecommerce/www/admin/ecommerce/checkout-one-form-oracle.xql =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/dotlrn-ecommerce/www/admin/ecommerce/Attic/checkout-one-form-oracle.xql,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs-4/packages/dotlrn-ecommerce/www/admin/ecommerce/checkout-one-form-oracle.xql 4 Jun 2005 10:05:19 -0000 1.1 @@ -0,0 +1,55 @@ + + ++ + ++ select order_id + from ec_orders + where user_session_id=:user_session_id + and order_state='in_basket' + ++ + ++ select gift_certificate_id + from ec_gift_certificates + where claim_check=:claim_check + ++ + ++ select user_id as gift_certificate_user_id, amount + from ec_gift_certificates + where gift_certificate_id=:gift_certificate_id + ++ + ++ select user_id + from ec_creditcards + where creditcard_id=:creditcard_id + ++ + ++ select address_id + from ec_addresses + where user_id=:user_id + and address_type = 'shipping' + ++ + ++ update ec_orders + set creditcard_id=:creditcard_id + where order_id=:order_id + ++ + ++ insert into ec_creditcards + (creditcard_id, user_id, creditcard_number, creditcard_last_four, creditcard_type, creditcard_expire, billing_address) + values + (:creditcard_id, :user_id, :creditcard_number, :cc_no , :creditcard_type, :expiry, :billing_address_id) + ++ + ++ update ec_creditcards + set billing_address = :billing_address_id + where creditcard_id = :creditcard_id + ++ + ++ update ec_orders + set creditcard_id=:creditcard_id + where order_id=:order_id + ++ + ++ update ec_orders + set creditcard_id=null + where order_id=:order_id + ++ + ++ update ec_addresses + set attn=:attn, line1=:line1, line2=:line2, city=:city, usps_abbrev=:usps_abbrev, zip_code=:zip_code, phone=:phone, phone_time=:phone_time + where address_id=:address_id + ++ + ++ update ec_items + set price_charged=round(:price_charged,2), price_name=:price_name, shipping_charged=round(:shipping_charged,2), price_tax_charged=round(:tax_charged,2), shipping_tax_charged=round(:shipping_tax,2) + where item_id=:item_id + ++ + ++ update ec_orders + set shipping_address=:address_id + where order_id=:order_id + ++ + ++ update ec_orders + set shipping_method=:shipping_method, + tax_exempt_p=:tax_exempt_p + where order_id=:order_id + ++ + ++ select user_class_id + from ec_user_class_user_map + where user_id=:user_id $additional_user_class_restriction + ++ + ++ select order_id + from ec_orders + where user_session_id=:user_session_id + and order_state='in_basket' + ++ + ++ select attn, line1, line2, city, usps_abbrev, zip_code, phone, country_code, full_state_name, phone_time + from ec_addresses + where address_id=:address_id + and user_id=:user_id + ++ + ++ update ec_addresses + set attn = :attn, line1 = :line1, line2 = :line2, usps_abbrev = :usps_abbrev, + city = :city, full_state_name = :full_state_name, zip_code = :zip_code, country_code = :country_code, phone = :phone, phone_time = :phone_time + where address_id = :address_id + ++ + ++ select usps_abbrev + from ec_addresses + where address_id=:address_id + ++ + ++ select tax_rate, shipping_p + from ec_sales_tax_by_state + where usps_abbrev=:usps_abbrev + ++ + ++ update ec_orders + set shipping_address=:address_id + where order_id=:order_id + ++ + ++ insert into ec_addresses + (address_id, user_id, address_type, attn, line1, line2, city, usps_abbrev, full_state_name, zip_code, country_code, phone, phone_time) + values + (:address_id, :user_id, :address_type, :attn,:line1,:line2,:city,:usps_abbrev,:full_state_name,:zip_code,:country_code,:phone,:phone_time) + ++ + ++ update ec_orders + set shipping_address=:address_id + where order_id=:order_id + ++ + ++ select default_shipping_per_item, weight_shipping_cost + from ec_admin_settings + ++ + ++ select add_exp_amount_per_item, add_exp_amount_by_weight + from ec_admin_settings + ++ + ++ update ec_orders + set shipping_charged=round(:order_shipping_cost,2), shipping_tax_charged=round(:tax_on_order_shipping_cost,2) + where order_id=:order_id + ++ + + Index: openacs-4/packages/dotlrn-ecommerce/www/admin/ecommerce/checkout-one-form-postgresql.xql =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/dotlrn-ecommerce/www/admin/ecommerce/Attic/checkout-one-form-postgresql.xql,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs-4/packages/dotlrn-ecommerce/www/admin/ecommerce/checkout-one-form-postgresql.xql 4 Jun 2005 10:05:19 -0000 1.1 @@ -0,0 +1,57 @@ + + ++ + +oracle +8.1.6 ++ + ++ select i.product_id, i.color_choice, i.size_choice, i.style_choice, count(*) as item_count, u.offer_code + from ec_products p, ec_items i, ec_user_session_offer_codes u + where u.product_id(+)=i.product_id and (u.user_session_id is null or u.user_session_id=:user_session_id) + and i.product_id = p.product_id + and p.no_shipping_avail_p = 'f' + and i.order_id = :order_id + group by i.product_id, i.color_choice, i.size_choice, i.style_choice, u.offer_code + ++ + ++ select nvl(base_shipping_cost,0) as base_shipping_cost, + nvl(default_shipping_per_item,0) as default_shipping_per_item, + nvl(weight_shipping_cost,0) as weight_shipping_cost, + nvl(add_exp_base_shipping_cost,0) as add_exp_base_shipping_cost, + nvl(add_exp_amount_per_item,0) as add_exp_amount_per_item, + nvl(add_exp_amount_by_weight,0) as add_exp_amount_by_weight + from ec_admin_settings + ++ + ++ select i.item_id, i.product_id, u.offer_code + from ec_items i, (select * + from ec_user_session_offer_codes usoc + where usoc.user_session_id = :user_session_id) u + where i.product_id=u.product_id(+) + and i.order_id=:order_id + order by i.product_id + ++ + ++ select ec_order_cost(:order_id) as otppgc, + ec_gift_certificate_balance(:user_id) as user_gift_certificate_balance + from dual + ++ Index: openacs-4/packages/dotlrn-ecommerce/www/admin/ecommerce/checkout-one-form.adp =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/dotlrn-ecommerce/www/admin/ecommerce/Attic/checkout-one-form.adp,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs-4/packages/dotlrn-ecommerce/www/admin/ecommerce/checkout-one-form.adp 4 Jun 2005 10:05:19 -0000 1.1 @@ -0,0 +1,144 @@ ++ + +postgresql +7.1 ++ + ++ select ec_tax(0,:order_shipping_cost,:order_id) + ++ + ++ select coalesce(base_shipping_cost,0) as base_shipping_cost, + coalesce(default_shipping_per_item,0) as default_shipping_per_item, + coalesce(weight_shipping_cost,0) as weight_shipping_cost, + coalesce(add_exp_base_shipping_cost,0) as add_exp_base_shipping_cost, + coalesce(add_exp_amount_per_item,0) as add_exp_amount_per_item, + coalesce(add_exp_amount_by_weight,0) as add_exp_amount_by_weight + from ec_admin_settings + ++ + ++ select i.item_id, i.product_id, u.offer_code + from ec_items i + left join (select * + from ec_user_session_offer_codes usoc + where usoc.user_session_id=:user_session_id) u on (i.product_id=u.product_id) + where i.order_id=:order_id + order by i.product_id + ++ + ++ select i.product_id, i.color_choice, i.size_choice, i.style_choice, count(*) as item_count, u.offer_code + from ec_products p, ec_items i + left join ec_user_session_offer_codes u on (u.product_id = i.product_id and u.user_session_id = :user_session_id) + where i.product_id = p.product_id + and p.no_shipping_avail_p = 'f' + and i.order_id = :order_id + group by i.product_id, i.color_choice, i.size_choice, i.style_choice, u.offer_code + ++ + ++ select ec_order_cost(:order_id) as otppgc, ec_gift_certificate_balance(:user_id) as user_gift_certificate_balance + ++ + + + Completing Your Order + +To complete your order, submit this form, and confirm the information + on the following page.
+ ++ + + + +Alternately, you can use a multi-page order process, + if you prefer using some of your other addresses on file with us. +
+1. Please review your order list for accuracy.
+Order list
+ @items_ul;noquote@ +
+2. Complete this information.
+ ++
+ + + + + ++
+ + + Shipping information
+ + @shipping_options;noquote@ +Payment information
++ +
+ + @tax_exempt_options;noquote@ + ++ +Your gift certificate balance covers the total cost of your + order. No need to enter any payment information!
++ + ++ +Your gift certificate balance takes care of + @certificate_amount@ of your order! Please enter credit card + information to pay for the rest.
++ + + + + + + Index: openacs-4/packages/dotlrn-ecommerce/www/admin/ecommerce/checkout-one-form.tcl =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/dotlrn-ecommerce/www/admin/ecommerce/Attic/checkout-one-form.tcl,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs-4/packages/dotlrn-ecommerce/www/admin/ecommerce/checkout-one-form.tcl 4 Jun 2005 10:05:19 -0000 1.1 @@ -0,0 +1,665 @@ +ad_page_contract { + + This generates a custom single order fulfillment page + with options to interface with the sophisticated multi address fulfillment + processing, when enough address history exists to make it worthwhile + Essentially combines /ecommerce/www/checkout* address* select-shipping* billing* payment* + + @author ported by Jerry Asher (jerry@theashergroup.com) + @author revised by Bart Teeuwisse+ +Since we already have a credit card on file for you, you + can just click on the button next to it to use it for this + order.
+@old_cards_to_choose_from;noquote@
+Or enter a new credit card:
+If you're using a new card, please enter the full credit card number below.
++
++ ++ Credit card information
+ +Credit card number: ++ + +Type: ++ + +Expires: +@ec_expires_widget;noquote@ ++ @author combined by Torben Brosten + @creation-date March 2004 + + @param usca_p:optional User session if started + +} { + usca_p:optional + + user_id:integer,notnull + participant_id:integer,optional +} + +# security checks +# following from checkout.tcl + +ec_redirect_to_https_if_possible_and_necessary + +# Make sure they have an in_basket order, otherwise they've probably +# gotten here by pushing Back, so return them to index.tcl + +#set user_id [ad_conn user_id] +set user_session_id [ec_get_user_session_id] +ec_create_new_session_if_necessary + +ec_log_user_as_user_id_for_this_session + +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 "" ] + +if { [empty_string_p $order_id] } { + + # Then they probably got here by pushing "Back", so just redirect + # them to index.tcl + + rp_internal_redirect index + ad_script_abort +} else { + db_dml update_ec_order_set_uid " + update ec_orders + set user_id = :user_id + where order_id = :order_id" +} + + # end security check + + # useful references declared: order_id, user_id, user_session_id + + # Retrieve the user name, use as default + + db_0or1row get_names " + select first_names, last_name + from cc_users + where user_id=:user_id" + + # is there an existing shipping address? + + if { ![info exists address_id] } { + set address_id [db_string get_address_id " + select shipping_address + from ec_orders + where order_id=:order_id" -default ""] + set shipping_address_id $address_id + } + +# set initial conditions needed to build and process this form + + set form_action [ec_securelink checkout-one-form-2] + set hidden_vars "" + set show_item_detail_p "f" + + set gateway_shipping_default_price 0 + + set gift_certificate_covers_whole_order 0 + set gift_certificate_covers_part_of_order 0 + + set address_type "billing" + set billing_address_exists 0 + set more_addresses_available "f" + + set currency [ad_parameter -package_id [ec_id] Currency ecommerce] + set tax_exempt_status [ad_parameter -package_id [ec_id] OfferTaxExemptStatusP ecommerce 0] + set tax_exempt_options "" + if { $tax_exempt_status == "t" } { + append tax_exempt_options " + " + } + + # prepare the cart contents for display + # following mainly from ec_order_summary_for_customer + + set items_ul "" + set order_total 0 + set last_product_id 0 + + db_foreach order_details_select " + select i.price_name, i.price_charged, i.color_choice, i.size_choice, i.style_choice, + p.product_name, p.one_line_description, p.product_id, count(*) as quantity + from ec_items i, ec_products p + where i.order_id = :order_id + and i.product_id = p.product_id + group by p.product_name, p.one_line_description, p.product_id, i.price_name, i.price_charged, i.color_choice, i.size_choice, i.style_choice" { + if {$product_id != $last_product_id} { + set lowest_price [lindex [ec_lowest_price_and_price_name_for_an_item $product_id $user_id] 0] + } + set option_list [list] + if { ![empty_string_p $color_choice] } { + lappend option_list "Color: $color_choice" + } + if { ![empty_string_p $size_choice] } { + lappend option_list "Size: $size_choice" + } + if { ![empty_string_p $style_choice] } { + lappend option_list "Style: $style_choice" + } + set options [join $option_list ", "] + if { ![empty_string_p $options] } { + set options "$options; " + } + + append items_ul "
Is your organization tax exempt? (If so, we will ask you to + provide us with an exemption certificate.) + Yes
+ NoQuantity $quantity: $product_name; $options$price_name [ec_pretty_price $lowest_price $currency]" + if { $show_item_detail_p == "t" } { + append items_ul " " + + set order_total [expr $order_total + $quantity * $lowest_price] + + } + set order_total_price_pre_gift_certificate $order_total + + + # Check if the order requires shipping + + if {[db_0or1row shipping_avail " + select p.no_shipping_avail_p + from ec_items i, ec_products p + where i.product_id = p.product_id + and p.no_shipping_avail_p = 'f' + and i.order_id = :order_id + group by no_shipping_avail_p"]} { + + set shipping_required "t" + + } else { + set shipping_required "f" + } + + + # calculate shipping options + +# prepare shipping method choices (shipping rates determined previously) +# some of this from ec_price_price_name_shipping_price_tax_shipping_tax_for_one_item +# and from ec_shipping_price_for_one_item +# and select-shipping.tcl + + + # Check if a shipping gateway has been selected. + set shipping_gateway [ad_parameter ShippingGateway ecommerce] + set shipping_gateway_in_use [acs_sc_binding_exists_p ShippingGateway $shipping_gateway] + +# below was: if info exists no_shipping_avail_p && string equal $no_shipping_avail_p "f" +if { [exists_and_equal shipping_required "t"] } { + + if { $shipping_gateway_in_use} { + + if { $address_id != 0 } { + + # Replace the default ecommerce shipping calculations with the + # charges from the shipping gateway, which contains + # both the shipping service level and the associated total + # charges. Requries zipcode and country. + + db_1row select_shipping_address " + select country_code, zip_code + from ec_addresses + where address_id = :address_id" + + # Calculate the total value of the shipment. + set shipment_value 0 + + db_foreach select_hard_goods " + select i.product_id, i.color_choice, i.size_choice, i.style_choice, count(*) as item_count, u.offer_code + from ec_products p, ec_items i + left join ec_user_session_offer_codes u on (u.product_id = i.product_id and u.user_session_id = :user_session_id) + where i.product_id = p.product_id + and p.no_shipping_avail_p = 'f' + and i.order_id = :order_id + group by i.product_id, i.color_choice, i.size_choice, i.style_choice, u.offer_code" { + + # If the quantity was altered in the previous step then + # use the new quantity instead of the number of items in + # the database. + + if {[info exists quantity]} { + set item_price [lindex [ec_lowest_price_and_price_name_for_an_item $product_id $user_id $offer_code] 0] + foreach {item_name item_quantity} [array get quantity [list $product_id*]] { + set shipment_value [expr $shipment_value + ((($item_quantity != $item_count) ? $item_quantity : $item_count) * $item_price)] + } + } else { + set shipment_value [expr $shipment_value + [lindex [ec_lowest_price_and_price_name_for_an_item $product_id $user_id $offer_code] 0]] + } + } + + set value_currency_code [ad_parameter Currency ecommerce] + set weight_unit_of_measure [ad_parameter WeightUnits ecommerce] + + append shipping_options " +
+ [ec_shipment_summary_sub $product_id $color_choice $size_choice $style_choice $price_charged $price_name $order_id]" + } + append items_ul "Shipping method:
+" + + # Get the list of services and their charges sorted on + # charges. + + set rates_and_services [lsort -index 1 -real \ + [acs_sc_call "ShippingGateway" "RatesAndServicesSelection" \ + [list "" "" "$country_code" "$zip_code" "$shipment_value" "$value_currency_code" "" "$weight_unit_of_measure"] \ + "$shipping_gateway"]] + + # Present the available shipping services to the user with the + # cheapest service selected. + + set cheapest_service true + foreach service $rates_and_services { + array set rate_and_service $service + set total_charges $rate_and_service(total_charges) + set service_code $rate_and_service(service_code) + set service_description [acs_sc_call "ShippingGateway" "ServiceDescription" "$service_code" "$shipping_gateway"] + append shipping_options " +
" + + # Add a flag to the export parameters to indicate that a + # shipping gateway is in use. + + set shipping_gateway true + append shipping_options "[export_form_vars shipping_gateway]" + } else { set shipping_options "+ + + $service_description + ++ ++ [string map {USD $} $value_currency_code] + ++ $total_charges + +" + } + append shipping_options " " + } + } else { + # calculate shipping charge options when not using shipping-gateway, + # and then include the value with each option (for an informed choice) + + # mainly from process-order-quantity-shipping.tcl + set total_reg_shipping_price 0 + set total_exp_shipping_price 0 + set last_product_id 0 + + db_1row get_ec_admin_settings " + select nvl(base_shipping_cost,0) as base_shipping_cost, + nvl(default_shipping_per_item,0) as default_shipping_per_item, + nvl(weight_shipping_cost,0) as weight_shipping_cost, + nvl(add_exp_base_shipping_cost,0) as add_exp_base_shipping_cost, + nvl(add_exp_amount_per_item,0) as add_exp_amount_per_item, + nvl(add_exp_amount_by_weight,0) as add_exp_amount_by_weight + from ec_admin_settings" + + db_foreach get_items_in_cart " + select i.item_id, i.product_id, u.offer_code + from ec_items i, (select * + from ec_user_session_offer_codes usoc + where usoc.user_session_id = :user_session_id) u + where i.product_id=u.product_id(+) + and i.order_id=:order_id + order by i.product_id" { + # ordering by i.product_id so loop can identify first instance of a quantity + + if { $product_id != $last_product_id } { + set first_instance 1 + db_1row get_shipping_info " + select shipping, shipping_additional, weight, no_shipping_avail_p + from ec_products + where product_id=:product_id" + } else { + set first_instance 0 + } + # if no_shipping_avail_p, skip calculating shipping for this item + if { [string equal $no_shipping_avail_p "f"] } { + + set shipping_prices_for_one_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] + + set total_reg_shipping_price [expr $total_reg_shipping_price + [lindex $shipping_prices_for_one_item 0]] + set total_exp_shipping_price [expr $total_exp_shipping_price + [lindex $shipping_prices_for_one_item 1]] + set last_product_id $product_id + } + } + + +# 3. Determine base shipping costs that are separate from items + + # set base shipping charge + + set order_shipping_cost $base_shipping_cost + + set shipping_method_standard $order_shipping_cost + + # Add on the extra base cost for express shipping + + set shipping_method_express [expr $order_shipping_cost + $add_exp_base_shipping_cost] + +# 4. set total costs for each shipping option + set total_shipping_price_default $total_reg_shipping_price + set total_reg_shipping_price [ec_pretty_price [expr $total_reg_shipping_price + $shipping_method_standard] $currency "t"] + set total_exp_shipping_price [ec_pretty_price [expr $total_exp_shipping_price + $shipping_method_express] $currency "t"] + set shipping_method_pickup [ec_pretty_price 0 $currency "t"] + set shipping_method_no_shipping 0 + +# 5 prepare shipping options to present to user + + set shipping_options " +
We need your shipping address before we can quote a shipping price. You will be able to review your order and shipping charge before confirming the order.
Shipping method:
+Standard Shipping ($total_reg_shipping_price)
" + } + # bracket above ends if gateway not used + } else { + # shipping not available or required + set total_shipping_price_default 0 + } + + +# we want to present the most recent billing address, if there is one + + set billing_address_ids [db_list get_billing_address_ids " + select address_id + from ec_addresses + where user_id=:user_id + and address_type = 'billing'" ] + + # $more_billing_addresses_available can be used in the adp to notify the user + # to choose one of their other billing addresses, if any + if { [llength $billing_address_ids] > 1 } { + # the max valued id is most likely the newest id (no date_last_modified field available) + set billing_address_id [ec_max_of_list $billing_address_ids] + set more_billing_addresses_available "t" + } else { + set more_billing_addresses_available "f" + if { $billing_address_ids > 0 } { + set billing_address_id $billing_address_ids + } else { + # we assume that no valid address_id is ever 0 + set billing_address_id 0 + } + } + + # retrieve a saved address + set address_id $billing_address_id + if { [info exists address_id] } { + set billing_address_exists [db_0or1row select_address " + select attn, line1, line2, city, usps_abbrev, zip_code, phone, country_code, full_state_name, phone_time + from ec_addresses + where address_id=:address_id"] + } + if {$billing_address_exists == 1} { + set bill_to_attn $attn + # split attn for separate first_names, last_name processing, delimiter is triple space + # separate first_names, last_name is required for some payment gateway validation systems (such as EZIC) + set name_delim [string first " " $attn] + if {$name_delim < 0 } { + set name_delim 0 + } + set bill_to_first_names [string trim [string range $attn 0 $name_delim]] + set bill_to_last_name [string range $attn [expr $name_delim + 3 ] end] + + set bill_to_line1 $line1 + set bill_to_line2 $line2 + set bill_to_city $city + set bill_to_usps_abbrev $usps_abbrev + set bill_to_zip_code $zip_code + set bill_to_phone $phone + set bill_to_country_code [ec_country_widget $country_code "bill_to_country_code"] + set bill_to_full_state_name $full_state_name + set bill_to_phone_time $phone_time + set bill_to_state_widget [ec_state_widget $usps_abbrev "bill_to_usps_abbrev"] + } else { + set billing_address_id 0 + # no previous billing address, set defaults + set bill_to_first_names [value_if_exists first_names] + set bill_to_last_name [value_if_exists last_name] + + set bill_to_line1 "" + set bill_to_line2 "" + set bill_to_city "" + set bill_to_usps_abbrev "" + set bill_to_zip_code "" + set bill_to_phone "" + set bill_to_country_code [ec_country_widget "US" "bill_to_country_code"] + set bill_to_full_state_name "" + set bill_to_phone_time "" + set bill_to_state_widget [ec_state_widget "" "bill_to_usps_abbrev"] + } + +if { [exists_and_equal shipping_required "t"] } { +# prepare shipping address + + set address_type "shipping" + + set shipping_address_exists 0 + + # we want to present the most recent shipping address, if there is one + # alternately, we can always start with a blank shipping address for all cases, + # if we want to bias users to use their billing addresses. + set shipping_address_ids [db_list get_shipping_address_ids " + select address_id + from ec_addresses + where user_id=:user_id + and address_type = 'shipping'" ] + + # $more_shipping_addresses_available can be used to notify the user + # to choose one of their other shipping addresses, if any + # ("previous addresses shipped to" link?) + if { [llength $shipping_address_ids] > 1 } { + set more_shipping_addresses_available "t" + # the max valued id is most likely the newest id (no last used date field available) + set shipping_address_id [ec_max_of_list $shipping_address_ids] + } else { + set more_shipping_addresses_available "f" + if { $shipping_address_ids > 0 } { + set shipping_address_id $shipping_address_ids + } else { + set shipping_address_id 0 + } + } + if {$more_billing_addresses_available == "t" || $more_shipping_addresses_available == "t" } { + set more_addresses_available "t" + } else { + set more_addresses_available "f" + } + # retrieve a saved address + set address_id $shipping_address_id + if { [info exists address_id] } { + set shipping_address_exists [db_0or1row select_address " + select attn, line1, line2, city, usps_abbrev, zip_code, phone, country_code, full_state_name, phone_time + from ec_addresses + where address_id=:address_id"] + } + if {$shipping_address_exists == 1} { + set ship_to_attn $attn + # split attn for separate first_names, last_name processing, delimiter is triple space + # separate first_names, last_name is required for some payment gateway validation systems (such as EZIC) + # in some cases, shipping address can be used as the default for billing address + set name_delim [string first " " $attn] + if {$name_delim < 0 } { + set name_delim 0 + } + set ship_to_first_names [string trim [string range $attn 0 $name_delim]] + set ship_to_last_name [string range $attn [expr $name_delim + 3 ] end] + + set ship_to_line1 $line1 + set ship_to_line2 $line2 + set ship_to_city $city + set ship_to_usps_abbrev $usps_abbrev + set ship_to_zip_code $zip_code + set ship_to_phone $phone + set ship_to_country_code [ec_country_widget $country_code "ship_to_country_code"] + set ship_to_full_state_name $full_state_name + set ship_to_phone_time $phone_time + set ship_to_state_widget [ec_state_widget $usps_abbrev "ship_to_usps_abbrev"] + } else { + set shipping_address_id 0 + # no previous shipping address, set defaults + set ship_to_first_names "" + set ship_to_last_name "" + + set ship_to_line1 "" + set ship_to_line2 "" + set ship_to_city "" + set ship_to_usps_abbrev "" + set ship_to_zip_code "" + set ship_to_phone "" + set ship_to_country_code [ec_country_widget "US" "ship_to_country_code"] + set ship_to_full_state_name "" + set ship_to_phone_time "" + set ship_to_state_widget [ec_state_widget "" "ship_to_usps_abbrev"] + } + # next bracket ends prepare shipping +} + +# prepare payment information + + # ec_order_cost returns price + shipping + tax - gift_certificate BUT + # no gift certificates have been applied to in_basket orders, so this + # just returns price + shipping + tax + + db_1row get_order_cost " + select ec_order_cost(:order_id) as otppgc, + ec_gift_certificate_balance(:user_id) as user_gift_certificate_balance + from dual" + + # Had to do this because the variable name below is too long for + # Oracle. It should be changed, but not in this upgrade + # hbrock@arsdigita.com + + set order_total_price_pre_gift_certificate $otppgc + unset otppgc + +# ec_order_cost does not work here, except maybe in special circumstances, +# where it might actually be more accurate than the alternate calculation. + + if { $order_total_price_pre_gift_certificate == 0 } { + # building order_total_price_pre_gift_certificate from an above query + # shipping value uses default from previous calcs on this page + if { $shipping_gateway_in_use == 1 } { + # there might not be an address available yet, so regional taxes are in flux still + set order_total_price_pre_gift_certificate [expr $order_total + $gateway_shipping_default_price] + } else { + # note: this does not include taxes for total value of order + set order_total_price_pre_gift_certificate [expr $order_total + $total_shipping_price_default] + } + } + + # these variable names help clarify usage for non-programmers editing the ADP + # templates: + + set customer_can_use_old_credit_cards 0 + + set show_creditcard_form_p "t" + + if { $user_gift_certificate_balance >= $order_total_price_pre_gift_certificate } { + set gift_certificate_covers_whole_order 1 + set show_creditcard_form_p "f" + } elseif { $user_gift_certificate_balance > 0 } { + set gift_certificate_covers_part_of_order 1 + set certificate_amount [ec_pretty_price $user_gift_certificate_balance] + } + + if { $show_creditcard_form_p == "t" } { + set customer_can_use_old_credit_cards [ad_parameter -package_id [ec_id] SaveCreditCardDataP ecommerce] + + # See if the administrator lets customers reuse their credit cards + + if { $customer_can_use_old_credit_cards } { + + # Then see if we have any credit cards on file for this user + # for this shipping address only (for security purposes) + + set to_print_before_creditcards " +
" + + if { [ad_parameter -package_id [ec_id] ExpressShippingP ecommerce] } { + append shipping_options " + Express ($total_exp_shipping_price)
" + } + if { [ad_parameter -package_id [ec_id] PickupP ecommerce] } { + append shipping_options " + Pickup ($shipping_method_pickup)" + } + append shipping_options "+
" + } + + set gift_certificate_p [ad_parameter -package_id [ec_id] SellGiftCertificatesP ecommerce] + +# quoting is default behavior for openacs 5.x + +# set bill_to_first_names [ad_quotehtml $bill_to_first_names] +# set bill_to_last_name [ad_quotehtml $bill_to_last_name] + +# set bill_to_line1 [ad_quotehtml $bill_to_line1] +# set bill_to_line2 [ad_quotehtml $bill_to_line2] +# set bill_to_city [ad_quotehtml $bill_to_city] +# set bill_to_usps_abbrev [ad_quotehtml $bill_to_usps_abbrev] +# set bill_to_zip_code [ad_quotehtml $bill_to_zip_code] +# set bill_to_phone [ad_quotehtml $bill_to_phone] +# cannot quote bill_to_country_code [ad_quotehtml $country_code] +# set bill_to_full_state_name [ad_quotehtml $bill_to_full_state_name] +# set bill_to_phone_time [ad_quotehtml $bill_to_phone_time] +# cannot quote bill_to_state_widget [ad_quotehtml $state_widget] + +if { [exists_and_equal shipping_required "t"] } { +# set ship_to_first_names [ad_quotehtml $ship_to_first_names] +# set ship_to_last_name [ad_quotehtml $ship_to_last_name] + +# set ship_to_line1 [ad_quotehtml $ship_to_line1] +# set ship_to_line2 [ad_quotehtml $ship_to_line2] +# set ship_to_city [ad_quotehtml $ship_to_city] +# set ship_to_usps_abbrev [ad_quotehtml $ship_to_usps_abbrev] +# set ship_to_zip_code [ad_quotehtml $ship_to_zip_code] +# set ship_to_phone [ad_quotehtml $ship_to_phone] +# cannot quote ship_to_country_code [ad_quotehtml $ship_to_country_code] +# set ship_to_full_state_name [ad_quotehtml $ship_to_full_state_name] +# set ship_to_phone_time [ad_quotehtml $ship_to_phone_time] +# cannot quote ship_to_state_widget [ad_quotehtml $ship_to_state_widget] +} +append hidden_vars [export_form_vars billing_address_id shipping_address_id user_id participant_id] +db_release_unused_handles Index: openacs-4/packages/dotlrn-ecommerce/www/admin/ecommerce/checkout-one-form.xql =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/dotlrn-ecommerce/www/admin/ecommerce/Attic/checkout-one-form.xql,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs-4/packages/dotlrn-ecommerce/www/admin/ecommerce/checkout-one-form.xql 4 Jun 2005 10:05:19 -0000 1.1 @@ -0,0 +1,155 @@ + + ++ " + set card_counter 0 + set old_cards_to_choose_from "" + + db_foreach get_creditcards_onfile " + select c.creditcard_id, c.creditcard_type, c.creditcard_last_four, c.creditcard_expire + from ec_creditcards c + where c.user_id=:user_id + and c.creditcard_number is not null + and c.failed_p='f' + and 0 < (select count(*) from ec_orders o where o.creditcard_id = c.creditcard_id) + order by c.creditcard_id desc" { + + if { $card_counter == 0 } { + append old_cards_to_choose_from $to_print_before_creditcards + } + append old_cards_to_choose_from " ++ Card Type +Last 4 Digits +Expires ++ " + incr card_counter + } if_no_rows { + set customer_can_use_old_credit_cards 0 + } + } + + set ec_creditcard_widget [ec_creditcard_widget] + set ec_expires_widget "[ec_creditcard_expire_1_widget] [ec_creditcard_expire_2_widget]" + + # If customer_can_use_old_credit_cards is 0, we don't have to + # worry about what's in old_cards_to_choose_from because it won't + # get printed in the template anyway. + + append old_cards_to_choose_from "+ +[ec_pretty_creditcard_type $creditcard_type] +$creditcard_last_four +$creditcard_expire ++ + Index: openacs-4/packages/dotlrn-ecommerce/www/admin/ecommerce/checkout-oracle.xql =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/dotlrn-ecommerce/www/admin/ecommerce/Attic/checkout-oracle.xql,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs-4/packages/dotlrn-ecommerce/www/admin/ecommerce/checkout-oracle.xql 4 Jun 2005 10:05:19 -0000 1.1 @@ -0,0 +1,21 @@ + + ++ + ++ select order_id + from ec_orders + where user_session_id=:user_session_id + and order_state='in_basket' + ++ + ++ select order_id, user_id as order_owner + from ec_orders + where user_session_id=:user_session_id + and order_state='in_basket' + ++ + ++ select i.price_name, i.price_charged, i.color_choice, i.size_choice, i.style_choice, p.product_name, p.one_line_description, p.product_id, count(*) as quantity + from ec_items i, ec_products p + where i.order_id = :order_id + and i.product_id = p.product_id + group by p.product_name, p.one_line_description, p.product_id, i.price_name, i.price_charged, i.color_choice, i.size_choice, i.style_choice + ++ + ++ update ec_orders + set user_id=:user_id + where order_id=:order_id + ++ + ++ select count(*) + from ec_items + where order_id=:order_id + ++ + ++ select count(*) + from ec_addresses + where address_id = :address_id + and user_id = :user_id + ++ + ++ select shipping_address + from ec_orders + where order_id=:order_id + ++ + ++ select first_names, last_name + from cc_users + where user_id=:user_id + ++ + ++ select p.no_shipping_avail_p + from ec_items i, ec_products p + where i.product_id = p.product_id + and p.no_shipping_avail_p = 'f' + and i.order_id = :order_id + group by no_shipping_avail_p + ++ + ++ select attn, line1, line2, city, usps_abbrev, zip_code, phone, country_code, full_state_name, phone_time + from ec_addresses + where address_id=:address_id + ++ + ++ update ec_addresses + set attn=:attn, line1=:line1, line2=:line2, city=:city, usps_abbrev=:usps_abbrev, zip_code=:zip_code, phone=:phone, phone_time=:phone_time + where address_id=:address_id + ++ + ++ insert into ec_addresses + (address_id, user_id, address_type, attn, line1, line2, city, usps_abbrev, zip_code, country_code, phone, phone_time) + values + (:address_id, :user_id, :address_type, :attn, :line1,:line2,:city,:usps_abbrev,:zip_code,:country_code,:phone,:phone_time) + ++ + ++ select country_code, zip_code + from ec_addresses + where address_id = :address_id + ++ + ++ update ec_orders + set shipping_address=:address_id + where order_id=:order_id + ++ + ++ select address_id + from ec_addresses + where user_id=:user_id + and address_type = 'shipping' + ++ + ++ select shipping, shipping_additional, weight, no_shipping_avail_p + from ec_products + where product_id=:product_id + ++ + ++ select c.creditcard_id, c.creditcard_type, c.creditcard_last_four, c.creditcard_expire + from ec_creditcards c + where c.user_id=:user_id + and c.creditcard_number is not null + and c.failed_p='f' + and 0 < (select count(*) from ec_orders o where o.creditcard_id = c.creditcard_id) + order by c.creditcard_id desc + ++ Index: openacs-4/packages/dotlrn-ecommerce/www/admin/ecommerce/checkout-postgresql.xql =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/dotlrn-ecommerce/www/admin/ecommerce/Attic/checkout-postgresql.xql,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs-4/packages/dotlrn-ecommerce/www/admin/ecommerce/checkout-postgresql.xql 4 Jun 2005 10:05:19 -0000 1.1 @@ -0,0 +1,20 @@ + + ++ + +oracle +8.1.6 ++ + ++ select count(*) + from dual + where exists (select 1 + from ec_products p, ec_items i + where i.product_id = p.product_id + and i.order_id = :order_id + and no_shipping_avail_p = 't') + ++ Index: openacs-4/packages/dotlrn-ecommerce/www/admin/ecommerce/checkout-progress.adp =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/dotlrn-ecommerce/www/admin/ecommerce/Attic/checkout-progress.adp,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs-4/packages/dotlrn-ecommerce/www/admin/ecommerce/checkout-progress.adp 4 Jun 2005 10:05:19 -0000 1.1 @@ -0,0 +1,19 @@ ++ + +postgresql +7.1 ++ + ++ select count(*) + where exists (select 1 + from ec_products p, ec_items i + where i.product_id = p.product_id + and i.order_id = :order_id + and no_shipping_avail_p = 't') + ++ +
Index: openacs-4/packages/dotlrn-ecommerce/www/admin/ecommerce/checkout-progress.tcl =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/dotlrn-ecommerce/www/admin/ecommerce/Attic/checkout-progress.tcl,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs-4/packages/dotlrn-ecommerce/www/admin/ecommerce/checkout-progress.tcl 4 Jun 2005 10:05:19 -0000 1.1 @@ -0,0 +1 @@ +set express_shipping_avail_p [ad_parameter -package_id [ec_id] ExpressShippingP ecommerce] Index: openacs-4/packages/dotlrn-ecommerce/www/admin/ecommerce/checkout.adp =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/dotlrn-ecommerce/www/admin/ecommerce/Attic/checkout.adp,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs-4/packages/dotlrn-ecommerce/www/admin/ecommerce/checkout.adp 4 Jun 2005 10:05:19 -0000 1.1 @@ -0,0 +1,80 @@ ++ + +class="altback"> +Shipping address class="altback"> +--->
class="altback"> +Verify order class="altback"> +--->
+ +class="altback"> +Shipping method class="altback"> +--->
class="altback"> +Billing address class="altback"> +--->
class="altback"> +Payment info class="altback"> +--->
class="altback"> +Confirm order + Completing Your Order: Shipping Address +@context_bar;noquote@ +@ec_system_owner;noquote@ + ++ + + + +Index: openacs-4/packages/dotlrn-ecommerce/www/admin/ecommerce/checkout.tcl =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/dotlrn-ecommerce/www/admin/ecommerce/Attic/checkout.tcl,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs-4/packages/dotlrn-ecommerce/www/admin/ecommerce/checkout.tcl 4 Jun 2005 10:05:19 -0000 1.1 @@ -0,0 +1,103 @@ +ad_page_contract { + @param usca_p:optional + + @author + @creation-date + @author ported by Jerry Asher (jerry@theashergroup.com) + @author revised by Bart Teeuwisse (bart.teeuwisse@thecodemill.biz) + @revision-date April 2002 +} { + usca_p:optional +} + + ec_redirect_to_https_if_possible_and_necessary + +# Make sure they have an in_basket order, otherwise they've probably +# gotten here by pushing Back, so return them to index.tcl + +# We need them to be logged in +set user_id [ad_conn user_id] + +if {$user_id == 0} { + set return_url "[ad_conn url]?[export_entire_form_as_url_vars]" + ad_returnredirect "/register?[export_url_vars return_url]" + ad_script_abort +} + + +set user_session_id [ec_get_user_session_id] +ec_create_new_session_if_necessary + +ec_log_user_as_user_id_for_this_session + +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 "" ] + +if { [empty_string_p $order_id] } { + + # Then they probably got here by pushing "Back", so just redirect + # them to index.tcl + + rp_internal_redirect index + ad_script_abort +} else { + db_dml update_ec_order_set_uid " + update ec_orders + set user_id = :user_id + where order_id = :order_id" +} + +# See if there are any saved shipping addresses for this user + +set address_type "shipping" + +# Check if the order requires shipping + +if {[db_0or1row shipping_avail " + select p.no_shipping_avail_p + from ec_items i, ec_products p + where i.product_id = p.product_id + and p.no_shipping_avail_p = 'f' + and i.order_id = :order_id + group by no_shipping_avail_p"]} { + + set shipping_required true + + # Set the referer to the name of this page so that the user + # returns to this page when the changes to the address have been + # checked. + + set referer checkout + # Present all saved addresses + + template::query get_user_addresses addresses multirow " + select address_id, attn, line1, line2, city, usps_abbrev, zip_code, phone, country_code, full_state_name, phone_time, address_type + from ec_addresses + where user_id=:user_id + and address_type = 'shipping'" -eval { + + set row(formatted) [ec_display_as_html [ec_pretty_mailing_address_from_args $row(line1) $row(line2) $row(city) $row(usps_abbrev) $row(zip_code) $row(country_code) \ + $row(full_state_name) $row(attn) $row(phone) $row(phone_time)]] + set address_id $row(address_id) + set row(delete) "[export_form_vars address_id referer]" + set row(edit) "[export_form_vars address_id address_type referer]" + set row(use) "[export_form_vars address_id]" + } + set hidden_form_vars [export_form_vars address_type referer] + +} else { + set shipping_required false +} + +if { $shipping_required == "false" } { + set address_id "" + ad_returnredirect "checkout-2?[export_url_vars address_id address_type]" + ad_script_abort +} + +set context_bar [template::adp_parse [acs_root_dir]/packages/[ad_conn package_key]/www/contextbar [list context_addition [list "Completing Your Order"]]] +set ec_system_owner [ec_system_owner] +db_release_unused_handles Index: openacs-4/packages/dotlrn-ecommerce/www/admin/ecommerce/checkout.xql =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/dotlrn-ecommerce/www/admin/ecommerce/Attic/checkout.xql,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs-4/packages/dotlrn-ecommerce/www/admin/ecommerce/checkout.xql 4 Jun 2005 10:05:19 -0000 1.1 @@ -0,0 +1,42 @@ + + +++ ++
++ +Select an address listed below or enter a new address.
++ + + + + + + ++ @addresses.formatted;noquote@ + ++ ++
++ ++ + ++ + ++ + ++ + ++ + ++
+ ++ ++ + ++ or + ++ + ++ + Index: openacs-4/packages/dotlrn-ecommerce/www/admin/ecommerce/finalize-order-oracle.xql =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/dotlrn-ecommerce/www/admin/ecommerce/Attic/finalize-order-oracle.xql,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs-4/packages/dotlrn-ecommerce/www/admin/ecommerce/finalize-order-oracle.xql 4 Jun 2005 10:05:19 -0000 1.1 @@ -0,0 +1,109 @@ + + ++ + ++ select p.no_shipping_avail_p + from ec_items i, ec_products p + where i.product_id = p.product_id + and p.no_shipping_avail_p = 'f' + and i.order_id = :order_id + group by no_shipping_avail_p + ++ + ++ select order_id + from ec_orders + where user_session_id=:user_session_id + and order_state='in_basket' + ++ + ++ update ec_orders + set user_id=:user_id + where order_id=:order_id + ++ + ++ select address_id, attn, line1, line2, city, usps_abbrev, zip_code, phone, country_code, full_state_name, phone_time + from ec_addresses + where user_id=:user_id + and address_type='shipping' + ++ Index: openacs-4/packages/dotlrn-ecommerce/www/admin/ecommerce/finalize-order-postgresql.xql =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/dotlrn-ecommerce/www/admin/ecommerce/Attic/finalize-order-postgresql.xql,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs-4/packages/dotlrn-ecommerce/www/admin/ecommerce/finalize-order-postgresql.xql 4 Jun 2005 10:05:19 -0000 1.1 @@ -0,0 +1,109 @@ + + ++ + +oracle +8.1.6 ++ + ++ select ec_gift_certificate_balance(:user_id) from dual + ++ + ++ select ec_order_gift_cert_amount(:order_id) from dual + ++ + ++ select nvl(sum(i.price_charged),0) - nvl(sum(i.price_refunded),0) as soft_goods_cost, + nvl(sum(i.price_tax_charged),0) - nvl(sum(i.price_tax_refunded),0) as soft_goods_tax + from ec_items i, ec_products p + where i.order_id = :order_id + and i.item_state <> 'void' + and i.product_id = p.product_id + and p.no_shipping_avail_p = 't' + ++ + ++ select nvl(sum(i.price_charged),0) - nvl(sum(i.price_refunded),0) as hard_goods_cost, + nvl(sum(i.price_tax_charged),0) - nvl(sum(i.shipping_refunded),0) as hard_goods_tax, + nvl(sum(i.shipping_charged),0) - nvl(sum(i.shipping_refunded),0) as hard_goods_shipping, + nvl(sum(i.shipping_tax_charged),0) - nvl(sum(i.shipping_tax_refunded),0) as hard_goods_shipping_tax + from ec_items i, ec_products p + where i.order_id = :order_id + and i.item_state <> 'void' + and i.product_id = p.product_id + and p.no_shipping_avail_p = 'f' + ++ + ++ insert into ec_financial_transactions + (transaction_id, order_id, transaction_amount, transaction_type, inserted_date) + values + (:transaction_id, :order_id, :transaction_amount, 'charge', sysdate) + ++ + ++ update ec_financial_transactions + set authorized_date = sysdate + where transaction_id = :transaction_id + ++ + ++ update ec_financial_transactions + set authorized_date = sysdate, to_be_captured_p = 't', to_be_captured_date = sysdate + where transaction_id = :transaction_id + ++ + ++ update ec_financial_transactions + set to_be_captured_p = 't', to_be_captured_date = sysdate + where transaction_id = :transaction_id + ++ + ++ insert into ec_problems_log + (problem_id, problem_date, problem_details, order_id) + values + (ec_problem_id_sequence.nextval, sysdate, :problem_details, :order_id) + ++ + ++ update ec_financial_transactions + set marked_date = sysdate + where transaction_id = :pgw_transaction_id + ++ + ++ select nvl(shipping_charged, 0) from ec_orders where order_id = :order_id + ++ + ++ select ec_tax(0, :order_shipping, :order_id) from dual + ++ Index: openacs-4/packages/dotlrn-ecommerce/www/admin/ecommerce/finalize-order.tcl =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/dotlrn-ecommerce/www/admin/ecommerce/Attic/finalize-order.tcl,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs-4/packages/dotlrn-ecommerce/www/admin/ecommerce/finalize-order.tcl 4 Jun 2005 10:05:19 -0000 1.1 @@ -0,0 +1,873 @@ +ad_page_contract { + + This script will: + + (1) put this order into the 'confirmed' state + (2) try to authorize the user's credit card info and either + (a) redirect them to a thank you page, or + (b) redirect them to a "please fix your credit card info" + page + + @author + @creation-date + @author ported by Jerry Asher (jerry@theashergroup.com) + @author and Walter McGinnis (wtem@olywa.net) + @author revised by Bart Teeuwisse (bart.teeuwisse@thecodemill.biz) + @revision-date April 2002 + +} { + user_id:integer,notnull + participant_id:integer,optional +} + +# If they reload, we don't have to worry about the credit card +# authorization code being executed twice because the order has +# already been moved to the 'confirmed' state, which means that they +# will be redirected out of this page. We will redirect them to the +# thank you page which displays the order with the most recent +# confirmation date. The only potential problem is that maybe the +# first time the order got to this page it was confirmed but then +# execution of the page stopped before authorization of the order +# could occur. This problem is solved by the scheduled procedure, +# ec_query_for_payment_zombies, which will try to authorize any +# 'confirmed' orders over half an hour old. + +ec_redirect_to_https_if_possible_and_necessary + +# first do all the normal checks to make sure nobody is doing url +# or cookie surgery to get here + +# we need them to be logged in +#set user_id [ad_verify_and_get_user_id] + +if {$user_id == 0} { + + set return_url "[ad_conn url]" + + ad_returnredirect "/register?[export_url_vars return_url]" + ad_script_abort +} + +# make sure they have an in_basket order +# unlike previous pages, if they don't have an in_basket order +# it may be because they tried to execute this code twice and +# the order is already in the confirmed state +# In this case, they should be redirected to the thank you +# page for the most recently confirmed order, if one exists, +# otherwise redirect them to index.tcl + +# user session tracking +set user_session_id [ec_get_user_session_id] + +ec_log_user_as_user_id_for_this_session + +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 ""] + +if { [empty_string_p $order_id] } { + + # Find their most recently confirmed order + + set most_recently_confirmed_order [db_string get_mrc_order " + select order_id + from ec_orders + where user_id=:user_id + and confirmed_date is not null + and order_id = (select max(o2.order_id) + from ec_orders o2 + where o2.user_id=:user_id + and o2.confirmed_date is not null)" -default ""] + + if { [empty_string_p $most_recently_confirmed_order] } { + rp_internal_redirect "../index" + ns_log Notice "finalize-order.tcl ref(84): no confirmed order for user $user_id. Redirecting user." + } else { + # Redirect to course page + db_1row section { + select c.live_revision as course_id + from ec_items i, dotlrn_ecommerce_section s, cr_items c + where i.product_id = s.product_id + and s.course_id = c.item_id + and i.order_id = :order_id + limit 1 + } + set course_url [export_vars -base ../course-info { course_id }] + ad_returnredirect $course_url + } + ad_script_abort +} + +# Make sure there's something in their shopping cart, otherwise +# redirect them to their shopping cart which will tell them that it's +# empty. + +# We may want to make this a redirect to insecure location + +if { [db_string get_in_basket_count " + select count(*) + from ec_items + where order_id = :order_id"] == 0 } { + rp_form_put user_id $user_id + rp_internal_redirect shopping-cart + ad_script_abort +} + + +# Redirect to course page +db_1row section { + select c.live_revision as course_id + from ec_items i, dotlrn_ecommerce_section s, cr_items c + where i.product_id = s.product_id + and s.course_id = c.item_id + and i.order_id = :order_id + limit 1 +} +set course_url [export_vars -base ../course-info { course_id }] + + +# Make sure the order belongs to this user_id, otherwise they managed +# to skip past checkout.tcl, or they messed w/their user_session_id +# cookie + +set order_owner [db_string get_order_owner " + select user_id + from ec_orders + where order_id = :order_id"] +if { $order_owner != $user_id } { + rp_form_put user_id $user_id + rp_internal_redirect checkout + ad_script_abort +} + +# Make sure there is an address for this order, otherwise they've +# probably gotten here via url surgery, so redirect them to +# checkout.tcl + +set address_id [db_string get_a_shipping_address " + select shipping_address + from ec_orders + where order_id=:order_id" -default ""] +if { [empty_string_p $address_id] } { + + # No shipping address is needed if the order only consists of soft + # goods not requiring shipping. + + if {[db_0or1row shipping_avail " + select p.no_shipping_avail_p, count (*) + from ec_items i, ec_products p + where i.product_id = p.product_id + and p.no_shipping_avail_p = 'f' + and i.order_id = :order_id + group by no_shipping_avail_p"]} { + ad_returnredirect [ec_securelink checkout] + ad_script_abort + } +} + +# Make sure there is a credit card (or that the +# gift_certificate_balance covers the cost) and a shipping method for +# this order, otherwise they've probably gotten here via url surgery, +# so redirect them to checkout-2.tcl + +set creditcard_id [db_string get_creditcard_id " + select creditcard_id + from ec_orders + where order_id=:order_id" -default ""] + +if { [empty_string_p $creditcard_id] } { + + # We only want price and shipping from this (to determine whether + # gift_certificate covers cost) + + set price_shipping_gift_certificate_and_tax [ec_price_shipping_gift_certificate_and_tax_in_an_order $order_id] + set order_total_price_pre_gift_certificate [expr [lindex $price_shipping_gift_certificate_and_tax 0] + [lindex $price_shipping_gift_certificate_and_tax 1]] + set gift_certificate_balance [db_string get_gc_balance " + select ec_gift_certificate_balance(:user_id) + from dual"] + if { $gift_certificate_balance < $order_total_price_pre_gift_certificate } { + set gift_certificate_covers_cost_p "f" + } else { + set gift_certificate_covers_cost_p "t" + } +} + +# set shipping_method [db_string get_shipping_method " +# select shipping_method +# from ec_orders +# where order_id=:order_id" -default ""] +# if { [empty_string_p $shipping_method] || ([empty_string_p $creditcard_id] && (![info exists gift_certificate_covers_cost_p] || $gift_certificate_covers_cost_p == "f")) } { +# rp_internal_redirect checkout-2 +# ad_script_abort +# } + +# Done with all the checks! + +# (1) put this order into the 'confirmed' state + +db_transaction { + ec_update_state_to_confirmed $order_id + + # Call after-checkout callback + db_foreach products { + select product_id, price_charged + from ec_items + where order_id = :order_id + } { + if { [exists_and_not_null participant_id] } { + callback -- ecommerce::after-checkout -user_id $participant_id -patron_id $user_id -product_id $product_id -price $price_charged + } else { + callback -- ecommerce::after-checkout -user_id $user_id -product_id $product_id -price $price_charged + } + } +} + +# (2) Try to authorize the user's credit card info and either +# (a) send them email & redirect them to a thank you page, or +# (b) redirect them to a "please fix your credit card info" page + +set applied_certificate_amount [db_string get_applied_certificate_amount " + select ec_order_gift_cert_amount(:order_id)"] +db_1row get_soft_goods_costs " + select coalesce(sum(i.price_charged),0) - coalesce(sum(i.price_refunded),0) as soft_goods_cost, + coalesce(sum(i.price_tax_charged),0) - coalesce(sum(i.price_tax_refunded),0) as soft_goods_tax + from ec_items i, ec_products p + where i.order_id = :order_id + and i.item_state <> 'void' + and i.product_id = p.product_id + and p.no_shipping_avail_p = 't'" +db_1row get_hard_goods_costs " + select coalesce(sum(i.price_charged),0) - coalesce(sum(i.price_refunded),0) as hard_goods_cost, + coalesce(sum(i.price_tax_charged),0) - coalesce(sum(i.shipping_refunded),0) as hard_goods_tax, + coalesce(sum(i.shipping_charged),0) - coalesce(sum(i.shipping_refunded),0) as hard_goods_shipping, + coalesce(sum(i.shipping_tax_charged),0) - coalesce(sum(i.shipping_tax_refunded),0) as hard_goods_shipping_tax + from ec_items i, ec_products p + where i.order_id = :order_id + and i.item_state <> 'void' + and i.product_id = p.product_id + and p.no_shipping_avail_p = 'f'" +set order_shipping [db_string get_order_shipping " + select coalesce(shipping_charged, 0) + from ec_orders + where order_id = :order_id"] +set order_shipping_tax [db_string get_order_shipping_tax " + select ec_tax(0, :order_shipping, :order_id)"] + +# Charge soft goods seperately from hard goods as the hard goods +# transaction will not settled until the goods are shipped while soft +# goods can be settled right away. + +if {$hard_goods_cost > 0} { + + # The order contains hard goods that come at a cost. + + if {$soft_goods_cost > 0} { + + # The order contains both hard and soft goods that come at a + # cost. + + if {$applied_certificate_amount >= [expr $soft_goods_cost + $soft_goods_tax]} { + + # The applied certificates cover the cost of the soft + # goods. + + if {[expr $applied_certificate_amount - $soft_goods_cost - $soft_goods_tax] >= [expr $hard_goods_cost + $hard_goods_tax + $hard_goods_shipping + $hard_goods_shipping_tax + \ + $order_shipping + $order_shipping_tax]} { + + # The applied certificates cover the cost of the soft + # goods as well as the hard goods. No financial + # transactions required. Mail the confirmation e-mail + # to the user. + + ec_email_new_order $order_id + + # Change the order state from 'confirmed' to + # 'authorized'. + + ec_update_state_to_authorized $order_id + ad_returnredirect $course_url + + } else { + + # The applied certificates cover the cost of the soft + # goods but not of the hard goods. Create a new + # financial transaction + + set transaction_id [db_nextval ec_transaction_id_sequence] + set transaction_amount [expr $hard_goods_cost + $hard_goods_tax + $hard_goods_shipping + $hard_goods_shipping_tax + $order_shipping + $order_shipping_tax - \ + [expr $applied_certificate_amount - $soft_goods_cost - $soft_goods_tax]] + db_dml insert_financial_transaction " + insert into ec_financial_transactions + (transaction_id, order_id, transaction_amount, transaction_type, inserted_date) + values + (:transaction_id, :order_id, :transaction_amount, 'charge', sysdate)" + + array set response [ec_creditcard_authorization $order_id $transaction_id] + set result $response(response_code) + set transaction_id $response(transaction_id) + if { [string equal $result "authorized"] } { + ec_email_new_order $order_id + + # Change the order state from 'confirmed' to + # 'authorized'. + + ec_update_state_to_authorized $order_id + + # Record the date & time of the authorization. + + db_dml update_authorized_date " + update ec_financial_transactions + set authorized_date = sysdate + where transaction_id = :transaction_id" + } + + if { [string equal $result "authorized"] || [string equal $result "no_recommendation"] } { + ad_returnredirect $course_url + ad_script_abort + } elseif { [string equal $result "failed_authorization"] } { + + # Updates everything that needs to be updated if a + # confirmed order fails + + ec_update_state_to_in_basket $order_id + + # authorization error is not necessarily the fault of the user's card, so log it for identifying pattern for diagnostics + ns_log Notice "finalize-order.tcl ref(295): failed_authorization for order_id: $order_id. Redirecting user to credit-card-correction." + + rp_form_put user_id $user_id + rp_internal_redirect credit-card-correction + ad_script_abort + } else { + + # Then result is probably "invalid_input". This should never + # occur + + ns_log Notice "Order $order_id received a result of $result" + ad_return_error "Sorry" " ++ + +postgresql +7.1 ++ + ++ select ec_gift_certificate_balance(:user_id) + ++ + ++ select ec_order_gift_cert_amount(:order_id) + ++ + ++ select coalesce(sum(i.price_charged),0) - coalesce(sum(i.price_refunded),0) as soft_goods_cost, + coalesce(sum(i.price_tax_charged),0) - coalesce(sum(i.price_tax_refunded),0) as soft_goods_tax + from ec_items i, ec_products p + where i.order_id = :order_id + and i.item_state <> 'void' + and i.product_id = p.product_id + and p.no_shipping_avail_p = 't' + ++ + ++ select coalesce(sum(i.price_charged),0) - coalesce(sum(i.price_refunded),0) as hard_goods_cost, + coalesce(sum(i.price_tax_charged),0) - coalesce(sum(i.shipping_refunded),0) as hard_goods_tax, + coalesce(sum(i.shipping_charged),0) - coalesce(sum(i.shipping_refunded),0) as hard_goods_shipping, + coalesce(sum(i.shipping_tax_charged),0) - coalesce(sum(i.shipping_tax_refunded),0) as hard_goods_shipping_tax + from ec_items i, ec_products p + where i.order_id = :order_id + and i.item_state <> 'void' + and i.product_id = p.product_id + and p.no_shipping_avail_p = 'f' + ++ + ++ insert into ec_financial_transactions + (transaction_id, order_id, transaction_amount, transaction_type, inserted_date) + values + (:transaction_id, :order_id, :transaction_amount, 'charge', current_timestamp) + ++ + ++ update ec_financial_transactions + set authorized_date = current_timestamp + where transaction_id = :transaction_id + ++ + ++ update ec_financial_transactions + set authorized_date = current_timestamp, to_be_captured_p = 't', to_be_captured_date = current_timestamp + where transaction_id = :transaction_id + ++ + ++ update ec_financial_transactions + set to_be_captured_p = 't', to_be_captured_date = current_timestamp + where transaction_id = :transaction_id + ++ + ++ insert into ec_problems_log + (problem_id, problem_date, problem_details, order_id) + values + (ec_problem_id_sequence.nextval, current_timestamp, :problem_details, :order_id) + ++ + ++ update ec_financial_transactions + set marked_date = current_timestamp + where transaction_id = :pgw_transaction_id + ++ + ++ select coalesce(shipping_charged, 0) from ec_orders where order_id = :order_id + ++ + ++ select ec_tax(0, :order_shipping, :order_id) + +There has been an error in the processing of your credit card information. + Please contact [ec_system_owner] to report the error.
" + ad_script_abort + } + } + } else { + + # The applied certificates do no cover the cost of the + # soft goods. + + if {$applied_certificate_amount >= [expr $hard_goods_cost + $hard_goods_tax + $hard_goods_shipping + $hard_goods_shipping_tax + \ + $order_shipping + $order_shipping_tax]} { + + # The applied certificates cover the cost of the hard + # goods but not the soft goods. Create a new financial + # transaction. + + set transaction_id [db_nextval ec_transaction_id_sequence] + set transaction_amount [expr $soft_goods_cost + $soft_goods_tax - \ + [expr $applied_certificate_amount - [expr $hard_goods_cost + $hard_goods_tax + $hard_goods_shipping + $hard_goods_shipping_tax + \ + $order_shipping + $order_shipping_tax]]] + db_dml insert_financial_transaction " + insert into ec_financial_transactions + (transaction_id, order_id, transaction_amount, transaction_type, inserted_date) + values + (:transaction_id, :order_id, :transaction_amount, 'charge', sysdate)" + + array set response [ec_creditcard_authorization $order_id $transaction_id] + set result $response(response_code) + set transaction_id $response(transaction_id) + if { [string equal $result "authorized"] } { + ec_email_new_order $order_id + + # Change the order state from 'confirmed' to + # 'authorized'. + + ec_update_state_to_authorized $order_id + + # Record the date & time of the authorization and + # schedule the transaction for settlement. + + db_dml schedule_settlement " + update ec_financial_transactions + set authorized_date = sysdate, to_be_captured_p = 't', to_be_captured_date = sysdate + where transaction_id = :transaction_id" + + # Mark the transaction now, rather than waiting + # for the scheduled procedures to mark the + # transaction. + + array set response [ec_creditcard_marking $transaction_id] + set mark_result $response(response_code) + set pgw_transaction_id $response(transaction_id) + if { [string equal $mark_result "invalid_input"]} { + set problem_details " + When trying to mark the transaction for the items that don't require shipment (transaction $transaction_id) at [ad_conn url], the following result occurred: $mark_result" + db_dml record_marking_problem " + insert into ec_problems_log + (problem_id, problem_date, problem_details, order_id) + values + (ec_problem_id_sequence.nextval, sysdate, :problem_details, :order_id)" + } elseif {[string equal $mark_result "success"]} { + db_dml update_marked_date " + update ec_financial_transactions + set marked_date = sysdate + where transaction_id = :pgw_transaction_id" + } + + ad_returnredirect $course_url + + } elseif { [string equal $result "failed_authorization"] || [string equal $result "no_recommendation"] } { + + # If the gateway returns no recommendation then + # possibility remains that the card is invalid and + # that soft goods have been 'shipped' because the + # gateway was down and could not verify the soft + # goods transaction. The store owner then depends + # on the honesty of visitor to obtain a new valid + # credit card for the 'shipped' products. + + if {[string equal $result "no_recommendation"] } { + + # Therefor reject the transaction and ask for + # (a new credit card and ask) the visitor to + # retry. Most credit card gateways have + # uptimes close to 99% so this scenario should + # not happen often. Another reason for + # rejecting transactions without + # recommendation is that the scheduled + # procedures can't authorize soft goods + # transactions properly. + + db_dml set_transaction_failed " + update ec_financial_transactions + set failed_p = 't' + where transaction_id = :transaction_id" + + } + + # Updates everything that needs to be updated if a + # confirmed order fails + + ec_update_state_to_in_basket $order_id + ns_log Notice "finalize-order.tcl ref(411): updated creditcard check failed for order_id $order_id. Redirecting to credit-card-correction" + rp_form_put user_id $user_id + rp_internal_redirect credit-card-correction + ad_script_abort + } else { + + # Then result is probably "invalid_input". This should never + # occur + + ns_log Notice "Order $order_id received a result of $result" + ad_return_error "Sorry" " +There has been an error in the processing of your credit card information. + Please contact [ec_system_owner] to report the error.
" + } + } else { + + # The applied certificates cover neither the cost of + # the hard goods nor the soft goods. Create separate + # transactions for the soft goods and the hard goods. + + set transaction_id [db_nextval ec_transaction_id_sequence] + set transaction_amount [expr $soft_goods_cost + $soft_goods_tax - $applied_certificate_amount] + db_dml insert_financial_transaction " + insert into ec_financial_transactions + (transaction_id, order_id, transaction_amount, transaction_type, inserted_date) + values + (:transaction_id, :order_id, :transaction_amount, 'charge', sysdate)" + + array set response [ec_creditcard_authorization $order_id $transaction_id] + set result $response(response_code) + set soft_goods_transaction_id $response(transaction_id) + if { [string equal $result "authorized"] } { + ec_email_new_order $order_id + + # Record the date & time of the soft goods + # authorization. + + set transaction_id $soft_goods_transaction_id + db_dml update_authorized_date " + update ec_financial_transactions + set authorized_date = sysdate + where transaction_id = :transaction_id" + + # Calculate the transaction amount for the hard + # goods. + + set transaction_amount [expr $hard_goods_cost + $hard_goods_tax + $hard_goods_shipping + $hard_goods_shipping_tax + $order_shipping + $order_shipping_tax + \ + $soft_goods_cost + $soft_goods_tax - $transaction_amount] + set transaction_id [db_nextval ec_transaction_id_sequence] + db_dml insert_financial_transaction " + insert into ec_financial_transactions + (transaction_id, order_id, transaction_amount, transaction_type, inserted_date) + values + (:transaction_id, :order_id, :transaction_amount, 'charge', sysdate)" + + array set response [ec_creditcard_authorization $order_id $transaction_id] + set result $response(response_code) + set hard_goods_transaction_id $response(transaction_id) + if { [string equal $result "authorized"] } { + + # Both transactions are approved. Change the + # order state from 'confirmed' to + # 'authorized'. + + ec_update_state_to_authorized $order_id + + # Schedule the soft goods transaction for + # settlement. + + set transaction_id $soft_goods_transaction_id + db_dml schedule_settlement_soft_goods " + update ec_financial_transactions + set to_be_captured_p = 't', to_be_captured_date = sysdate + where transaction_id = :transaction_id" + + # Mark the transaction now, rather than + # waiting for the scheduled procedures to mark + # the transaction. + + array set response [ec_creditcard_marking $transaction_id] + set mark_result $response(response_code) + set pgw_transaction_id $response(transaction_id) + if { [string equal $mark_result "invalid_input"]} { + set problem_details " + When trying to mark the transaction for the items that don't require shipment (transaction $transaction_id) at [ad_conn url], the following result occurred: $mark_result" + db_dml record_marking_problem " + insert into ec_problems_log + (problem_id, problem_date, problem_details, order_id) + values + (ec_problem_id_sequence.nextval, sysdate, :problem_details, :order_id)" + } elseif {[string equal $mark_result "success"]} { + db_dml update_marked_date " + update ec_financial_transactions + set marked_date = sysdate + where transaction_id = :pgw_transaction_id" + } + + # Record the date & time of the hard goods + # authorization. + + set transaction_id $hard_goods_transaction_id + db_dml update_authorized_date " + update ec_financial_transactions + set authorized_date = sysdate + where transaction_id = :transaction_id" + + ad_returnredirect $course_url + + } elseif {[string equal $result "failed_authorization"] || [string equal $result "no_recommendation"] } { + + # Record both transactions as failed and ask + # for a new credit card number. The second + # transaction could have failed because it + # maxed out the card. Both transactions need + # to failed as the user might choose to use a + # different card and this procedure doesn't + # check for prior authorized transactions. + + set transaction_id $soft_goods_transaction_id + db_dml set_transaction_failed " + update ec_financial_transactions + set failed_p = 't' + where transaction_id = :transaction_id" + + set transaction_id $hard_goods_transaction_id + db_dml set_transaction_failed " + update ec_financial_transactions + set failed_p = 't' + where transaction_id = :transaction_id" + + # Updates everything that needs to be updated if a + # confirmed order fails + + ec_update_state_to_in_basket $order_id + ns_log Notice "finalize-order.tcl ref(544): creditcard check failed. Redirecting user to credit-card-correction." + rp_form_put user_id $user_id + rp_internal_redirect credit-card-correction + + } else { + + # Then result is probably + # "invalid_input". This should never occur + + ns_log Notice "Order $order_id received a result of $result" + ad_return_error "Sorry" " +There has been an error in the processing of your credit card information. + Please contact [ec_system_owner] to report the error.
" + } + } elseif { [string equal $result "failed_authorization"] || [string equal $result "no_recommendation"] } { + + set transaction_id $soft_goods_transaction_id + db_dml set_transaction_failed " + update ec_financial_transactions + set failed_p = 't' + where transaction_id = :transaction_id" + + # Updates everything that needs to be updated if a + # confirmed order fails + + ec_update_state_to_in_basket $order_id + + rp_form_put user_id $user_id + rp_internal_redirect credit-card-correction + ad_script_abort + } else { + + # Then result is probably "invalid_input". This should never + # occur + + ns_log Notice "Order $order_id received a result of $result" + ad_return_error "Sorry" " +There has been an error in the processing of your credit card information. + Please contact [ec_system_owner] to report the error.
" + } + } + } + } else { + + # The order contains only hard goods that come at a cost. + + if {$applied_certificate_amount >= [expr $hard_goods_cost + $hard_goods_tax + $hard_goods_shipping + $hard_goods_shipping_tax + $order_shipping + $order_shipping_tax]} { + + # The applied certificates cover the cost of the hard + # goods. No financial transaction required. + + # Mail the confirmation e-mail to the user. + + ec_email_new_order $order_id + + # Change the order state from 'confirmed' to + # 'authorized'. + + ec_update_state_to_authorized $order_id + ad_returnredirect $course_url + + } else { + + # The applied certificates only partially covered the cost + # of the hard goods. Create a new financial transaction. + + set transaction_id [db_nextval ec_transaction_id_sequence] + set transaction_amount [expr $hard_goods_cost + $hard_goods_tax + $hard_goods_shipping + $hard_goods_shipping_tax + $order_shipping + $order_shipping_tax - \ + [expr $applied_certificate_amount - $soft_goods_cost - $soft_goods_tax]] + db_dml insert_financial_transaction " + insert into ec_financial_transactions + (transaction_id, order_id, transaction_amount, transaction_type, inserted_date) + values + (:transaction_id, :order_id, :transaction_amount, 'charge', sysdate)" + + array set response [ec_creditcard_authorization $order_id $transaction_id] + set result $response(response_code) + set transaction_id $response(transaction_id) + if { [string equal $result "authorized"] } { + ec_email_new_order $order_id + + # Change the order state from 'confirmed' to + # 'authorized'. + + ec_update_state_to_authorized $order_id + + # Record the date & time of the authorization. + + db_dml update_authorized_date " + update ec_financial_transactions + set authorized_date = sysdate + where transaction_id = :transaction_id" + } + + if { [string equal $result "authorized"] || [string equal $result "no_recommendation"] } { + ad_returnredirect $course_url + ad_script_abort + } elseif { [string equal $result "failed_authorization"] } { + + # If the gateway returns no recommendation then + # possibility remains that the card is invalid and + # that soft goods have been 'shipped' because the + # gateway was down and could not verify the soft goods + # transaction. The store owner then depends on the + # honesty of visitor to obtain a new valid credit card + # for the 'shipped' products. + + if {[string equal $result "no_recommendation"] } { + + # Therefor reject the transaction and ask for (a + # new credit card and ask) the visitor to + # retry. Most credit card gateways have uptimes + # close to 99% so this scenario should not happen + # often. Another reason for rejecting transactions + # without recommendation is that the scheduled + # procedures can't authorize soft goods + # transactions properly. + + db_dml set_transaction_failed " + update ec_financial_transactions + set failed_p = 't' + where transaction_id = :transaction_id" + + } + + # Updates everything that needs to be updated if a + # confirmed order fails + + ec_update_state_to_in_basket $order_id + + # log this just in case this is a symptom of an extended gateway downtime + ns_log Notice "finalize-order.tcl, ref(671): creditcard check failed for order_id $order_id. Redirecting to credit-card-correction" + + rp_form_put user_id $user_id + rp_internal_redirect credit-card-correction + ad_script_abort + } else { + + # Then result is probably "invalid_input". This should never + # occur + + ns_log Notice "Order $order_id received a result of $result" + ad_return_error "Sorry" " +There has been an error in the processing of your credit card information. + Please contact [ec_system_owner] to report the error.
" + } + } + } +} else { + + # The order does not contain any hard goods that come at a cost. + + if {$soft_goods_cost > 0} { + + # The order contains only soft goods that come at a cost. + + if {$applied_certificate_amount >= [expr $soft_goods_cost + $soft_goods_tax]} { + + # The gift certificates cover the cost of the soft + # goods. No financial transaction required. Mail a + # confirmation e-mail to the user. + + ec_email_new_order $order_id + + # Change the order state from 'confirmed' to + # 'authorized'. + + ec_update_state_to_authorized $order_id + ad_returnredirect $course_url + + } else { + + # The certificates only partially cover the cost of the + # soft goods. Create a new financial transaction + + set transaction_id [db_nextval ec_transaction_id_sequence] + set transaction_amount [expr $soft_goods_cost + $soft_goods_tax - $applied_certificate_amount] + db_dml insert_financial_transaction " + insert into ec_financial_transactions + (transaction_id, order_id, transaction_amount, transaction_type, inserted_date) + values + (:transaction_id, :order_id, :transaction_amount, 'charge', sysdate)" + + array set response [ec_creditcard_authorization $order_id $transaction_id] + set result $response(response_code) + set transaction_id $response(transaction_id) + if { [string equal $result "authorized"] } { + ec_email_new_order $order_id + + # Change the order state from 'confirmed' to + # 'authorized'. + + ec_update_state_to_authorized $order_id + + # Record the date & time of the authorization and + # schedule the transaction for settlement. + + db_dml schedule_settlement " + update ec_financial_transactions + set authorized_date = sysdate, to_be_captured_p = 't', to_be_captured_date = sysdate + where transaction_id = :transaction_id" + + # Mark the transaction now, rather than waiting for + # the scheduled procedures to mark the transaction. + + array set response [ec_creditcard_marking $transaction_id] + set mark_result $response(response_code) + set pgw_transaction_id $response(transaction_id) + if { [string equal $mark_result "invalid_input"]} { + set problem_details " + When trying to mark the transaction for the items that don't require shipment (transaction $transaction_id) at [ad_conn url], the following result occurred: $mark_result" + db_dml record_marking_problem " + insert into ec_problems_log + (problem_id, problem_date, problem_details, order_id) + values + (ec_problem_id_sequence.nextval, sysdate, :problem_details, :order_id)" + } elseif {[string equal $mark_result "success"]} { + db_dml update_marked_date " + update ec_financial_transactions + set marked_date = sysdate + where transaction_id = :pgw_transaction_id" + } + ad_returnredirect $course_url + } + + if {[string equal $result "failed_authorization"] || [string equal $result "no_recommendation"] } { + + # If the gateway returns no recommendation then the + # possibility remains that the card is invalid and + # that soft goods have been 'shipped' because the + # gateway was down and could not verify the soft goods + # transaction. The store owner then depends on the + # honesty of visitor to obtain a new valid credit card + # for the 'shipped' products. + + if {[string equal $result "no_recommendation"] } { + + # Therefor reject the transaction and ask for (a + # new credit card and ask) the visitor to + # retry. Most credit card gateways have uptimes + # close to 99% so this scenario should not happen + # often. Another reason for rejecting transactions + # without recommendation is that the scheduled + # procedures can't authorize soft goods + # transactions properly. + + db_dml set_transaction_failed " + update ec_financial_transactions + set failed_p = 't' + where transaction_id = :transaction_id" + + } + + # Updates everything that needs to be updated if a + # confirmed order fails + + ec_update_state_to_in_basket $order_id + ns_log Notice "finalize-order.tcl ref(789): creditcard check failed. Redirecting to credit-card-correction" + rp_form_put user_id $user_id + rp_internal_redirect credit-card-correction + ad_script_abort + + } else { + + # Then result is probably "invalid_input". This should never + # occur + + ns_log Notice "Order $order_id received a result of $result" + ad_return_error "Sorry" " +There has been an error in the processing of your credit card information. + Please contact [ec_system_owner] to report the error.
" + } + } + } else { + + # The order contains neither hard nor soft goods that come at + # a cost. No financial transactions required. Mail the + # confirmation e-mail to the user. + + ec_email_new_order $order_id + + # Change the order state from 'confirmed' to + # 'authorized'. + + ec_update_state_to_authorized $order_id + ad_returnredirect $course_url + } +} Index: openacs-4/packages/dotlrn-ecommerce/www/admin/ecommerce/finalize-order.xql =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/dotlrn-ecommerce/www/admin/ecommerce/Attic/finalize-order.xql,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs-4/packages/dotlrn-ecommerce/www/admin/ecommerce/finalize-order.xql 4 Jun 2005 10:05:19 -0000 1.1 @@ -0,0 +1,83 @@ + + ++ + Index: openacs-4/packages/dotlrn-ecommerce/www/admin/ecommerce/shopping-cart-add-oracle.xql =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/dotlrn-ecommerce/www/admin/ecommerce/Attic/shopping-cart-add-oracle.xql,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs-4/packages/dotlrn-ecommerce/www/admin/ecommerce/shopping-cart-add-oracle.xql 4 Jun 2005 10:05:19 -0000 1.1 @@ -0,0 +1,47 @@ + + ++ + ++ select order_id + from ec_orders + where user_session_id=:user_session_id + and order_state='in_basket' + ++ + ++ select order_id + from ec_orders + where user_id=:user_id + and confirmed_date is not null + and order_id=(select max(o2.order_id) + from ec_orders o2 + where o2.user_id=:user_id + and o2.confirmed_date is not null) + ++ + ++ select count(*) + from ec_items + where order_id=:order_id + ++ + ++ select user_id + from ec_orders + where order_id=:order_id + ++ + ++ select shipping_address + from ec_orders + where order_id=:order_id + ++ + ++ select creditcard_id + from ec_orders + where order_id=:order_id + ++ + ++ select shipping_method + from ec_orders + where order_id=:order_id + ++ + ++ update ec_financial_transactions + set failed_p = 't' + where transaction_id = :transaction_id" + ++ + ++ update ec_financial_transactions + set failed_p = 't' + where transaction_id = :transaction_id + ++ Index: openacs-4/packages/dotlrn-ecommerce/www/admin/ecommerce/shopping-cart-add-postgresql.xql =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/dotlrn-ecommerce/www/admin/ecommerce/Attic/shopping-cart-add-postgresql.xql,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs-4/packages/dotlrn-ecommerce/www/admin/ecommerce/shopping-cart-add-postgresql.xql 4 Jun 2005 10:05:19 -0000 1.1 @@ -0,0 +1,36 @@ + + ++ + +oracle +8.1.6 ++ + ++ insert into ec_orders + (order_id, user_session_id, order_state, in_basket_date) + select :order_id, :user_session_id, 'in_basket', sysdate from dual + where not exists (select 1 + from ec_orders + where user_session_id=:user_session_id + and order_state='in_basket') + ++ + ++ insert into ec_problems_log + (problem_id, problem_date, problem_details) + values + (ec_problem_id_sequence.nextval, sysdate,:errormsg) + ++ + ++ insert into ec_items + (item_id, product_id, color_choice, size_choice, style_choice, order_id, in_cart_date) + (select ec_item_id_sequence.nextval, :product_id, :color_choice, :size_choice, :style_choice, :order_id, sysdate + from dual + where not exists (select 1 + from ec_items + where order_id=:order_id + and product_id=:product_id + and color_choice [ec_decode $color_choice "" "is null" "= :color_choice"] + and size_choice [ec_decode $size_choice "" "is null" "= :size_choice"] + and style_choice [ec_decode $style_choice "" "is null" "= :style_choice"] + and ((sysdate - in_cart_date) * 86400 < 5))) + ++ Index: openacs-4/packages/dotlrn-ecommerce/www/admin/ecommerce/shopping-cart-add.tcl =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/dotlrn-ecommerce/www/admin/ecommerce/Attic/shopping-cart-add.tcl,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs-4/packages/dotlrn-ecommerce/www/admin/ecommerce/shopping-cart-add.tcl 4 Jun 2005 10:05:19 -0000 1.1 @@ -0,0 +1,143 @@ +ad_page_contract { + + This adds an item to an 'in_basket' order, although if there + exists a 'confirmed' order for this user_session_id, the user is + told they have to wait because 'confirmed' orders can potentially + become 'in_basket' orders (if authorization fails), and we can + only have one 'in_basket' order for this user_session_id at a + time. Most orders are only in the 'confirmed' state for a few + seconds, except for those whose credit card authorizations are + inconclusive. Furthermore, it is unlikely for a user to start + adding things to their shopping cart right after they've made an + order. So this case is unlikely to occur often. I will include a + ns_log Notice so that any occurrences will be logged. + + @param product_id:integer + @param size_choice + @param color_choice + @param style_choice + @param usca_p:optional + + @author + @creation-date + @author ported by Jerry Asher (jerry@theashergroup.com) + @author revised by Bart Teeuwisse (bart.teeuwisse@thecodemill.biz) + @revision-date April 2002 + +} { + product_id:integer + {item_count 1} + {size_choice ""} + {color_choice ""} + {style_choice ""} + usca_p:optional + + user_id:integer,notnull + participant_id:integer,optional +} +# added default values to above params so that this page works +# when a post from a form to shopping-cart-add originates from another domain. + +# 1. get user_session_id +# 1.5 see if there exists a 'confirmed' order for this user_session_id +# 2. get order_id +# 3. get item_id +# 4. put item into ec_items, unless there is already an item with that product_id +# in that order (this is double click protection -- the only way they can increase +# the quantity of a product in their order is to click on "update quantities" on +# the shopping cart page (shopping-cart.tcl) +# 5. ad_returnredirect them to their shopping cart + +set user_session_id [ec_get_user_session_id] +ec_create_new_session_if_necessary [export_url_vars product_id] +set n_confirmed_orders [db_string get_n_confirmed_orders " + select count(*) + from ec_orders + where user_session_id = :user_session_id + and order_state = 'confirmed'"] +if { $n_confirmed_orders > 0 } { + ad_return_complaint 1 " ++ + +postgresql +7.1 ++ + ++ insert into ec_orders + (order_id, user_session_id, order_state, in_basket_date) + select :order_id, :user_session_id, 'in_basket', current_timestamp + where not exists (select 1 from ec_orders where user_session_id=:user_session_id and order_state='in_basket') + ++ + ++ insert into ec_problems_log + (problem_id, problem_date, problem_details) + values + (ec_problem_id_sequence.nextval, current_timestamp,:errormsg) + ++ + ++ insert into ec_items + (item_id, product_id, color_choice, size_choice, style_choice, order_id, in_cart_date) + select ec_item_id_sequence.nextval, :product_id, :color_choice, + :size_choice, :style_choice, :order_id, current_timestamp from dual + +Sorry, you have an order for which credit card authorization has not yet taken place. + Please wait for the authorization to complete before adding new items to your shopping cart.
+Thank you.
" + ns_log Warning "shopping-cart-add.tcl,line59: User tried to add an item to the shopping cart after making a purchase, but was rejected!" + ad_script_abort +} + +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 ""] + +# Here's the airtight way to do it: do the check on order_id, then +# insert a new order where there doesn't exist an old one, then set +# order_id again (because the correct order_id might not be the one +# set inside the if statement). It should now be impossible for +# order_id to be the empty string (if it is, log the error and +# redirect them to product.tcl). + +if { [value_if_exists order_id] < 1 || [ad_var_type_check_number_p $order_id] == 0 } { + set order_id [db_nextval ec_order_id_sequence] + + # Create the order (if an in_basket order *still* doesn't exist) + + db_dml insert_new_ec_order " + insert into ec_orders + (order_id, user_session_id, order_state, in_basket_date) + select :order_id, :user_session_id, 'in_basket', sysdate from dual + where not exists (select 1 from ec_orders where user_session_id = :user_session_id and order_state = 'in_basket')" + + # Now either an in_basket order should have been inserted by the + # above statement or it was inserted by a different thread + # milliseconds ago + + 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 ""] + if { [empty_string_p $order_id] } { + + # I don't expect this to ever happen, but just in case, I'll + # log the problem and redirect them to product.tcl + + set errormsg "Null order_id on shopping-cart-add.tcl for user_session_id :user_session_id. Please report this problem to [ec_package_maintainer]." + db_dml insert_problem_into_log " + insert into ec_problems_log + (problem_id, problem_date, problem_details) + values + (ec_problem_id_sequence.nextval, sysdate,:errormsg)" + ad_returnredirect "product?[export_url_vars product_id]" + ad_script_abort + } +} + +# Insert an item into that order if an identical item doesn't exist +# (this is double click protection). If they want to update +# quantities, they can do so from the shopping cart page. + +# Bart Teeuwisse: Fine tuned the postgresql version to only reject +# items that were added to the shopping cart in the last 5 seconds. +# That should be enough to protect from double clicks yet provides a +# more intuitive user experience. + +for {set i 0} {$i < $item_count} {incr i} { + ns_log notice "DEBUG:: Inserting [expr $i + 1] out of $item_count" + db_dml insert_new_item_in_order { + insert into ec_items + (item_id, product_id, color_choice, size_choice, style_choice, order_id, in_cart_date) + (select ec_item_id_sequence.nextval, :product_id, :color_choice, :size_choice, :style_choice, :order_id, current_timestamp + where not exists (select 1 + from ec_items + where order_id=:order_id + and product_id=:product_id + and color_choice [ec_decode $color_choice "" "is null" "= :color_choice"] + and size_choice [ec_decode $size_choice "" "is null" "= :size_choice"] + and style_choice [ec_decode $style_choice "" "is null" "= :style_choice"] + and (date_part('epoch', now()) - date_part('epoch', in_cart_date) < 5))) + } +} + +db_release_unused_handles +ad_returnredirect [export_vars -base checkout-one-form { user_id participant_id }] Index: openacs-4/packages/dotlrn-ecommerce/www/admin/ecommerce/shopping-cart-add.xql =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/dotlrn-ecommerce/www/admin/ecommerce/Attic/shopping-cart-add.xql,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs-4/packages/dotlrn-ecommerce/www/admin/ecommerce/shopping-cart-add.xql 4 Jun 2005 10:05:19 -0000 1.1 @@ -0,0 +1,23 @@ + + ++ + Index: openacs-4/packages/dotlrn-ecommerce/www/admin/ecommerce/shopping-cart-delete-from.tcl =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/dotlrn-ecommerce/www/admin/ecommerce/Attic/shopping-cart-delete-from.tcl,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs-4/packages/dotlrn-ecommerce/www/admin/ecommerce/shopping-cart-delete-from.tcl 4 Jun 2005 10:05:19 -0000 1.1 @@ -0,0 +1,37 @@ +# www/ecommerce/shopping-cart-delete-from.tcl +ad_page_contract { + @param product_id + @param color_choice + @param size_choice + @param style_choice + @author + @creation-date + @cvs-id $Id: shopping-cart-delete-from.tcl,v 1.1 2005/06/04 10:05:19 hamiltonc Exp $ + @author ported by Jerry Asher (jerry@theashergroup.com) +} { + product_id:integer + color_choice:optional + size_choice:optional + style_choice:optional + +} + + +set user_session_id [ec_get_user_session_id] + + + + +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 ""] + +if { [empty_string_p $order_id] } { + # then they probably got here by pushing "Back", so just redirect them + # into their empty shopping cart + rp_internal_redirect shopping-cart + ad_script_abort +} + +db_dml delete_item_from_cart "delete from ec_items where order_id=:order_id and product_id=:product_id and color_choice [ec_decode $color_choice "" "is null" "= :color_choice"] and size_choice [ec_decode $size_choice "" "is null" "= :size_choice"] and style_choice [ec_decode $style_choice "" "is null" "= :style_choice"]" +db_release_unused_handles + +rp_internal_redirect shopping-cart Index: openacs-4/packages/dotlrn-ecommerce/www/admin/ecommerce/shopping-cart-delete-from.xql =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/dotlrn-ecommerce/www/admin/ecommerce/Attic/shopping-cart-delete-from.xql,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs-4/packages/dotlrn-ecommerce/www/admin/ecommerce/shopping-cart-delete-from.xql 4 Jun 2005 10:05:19 -0000 1.1 @@ -0,0 +1,25 @@ + + ++ + ++ select count(*) + from ec_orders + where user_session_id=:user_session_id + and order_state='confirmed' + ++ + ++ select order_id + from ec_orders + where user_session_id=:user_session_id + and order_state='in_basket' + ++ + Index: openacs-4/packages/dotlrn-ecommerce/www/admin/ecommerce/shopping-cart-oracle.xql =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/dotlrn-ecommerce/www/admin/ecommerce/Attic/shopping-cart-oracle.xql,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs-4/packages/dotlrn-ecommerce/www/admin/ecommerce/shopping-cart-oracle.xql 4 Jun 2005 10:05:19 -0000 1.1 @@ -0,0 +1,46 @@ + + ++ + ++ select order_id + from ec_orders + where user_session_id=:user_session_id + and order_state='in_basket' + ++ + ++ delete from ec_items + where order_id=:order_id + and product_id=:product_id + and color_choice [ec_decode $color_choice "" "is null" "= :color_choice"] + and size_choice [ec_decode $size_choice "" "is null" "= :size_choice"] + and style_choice [ec_decode $style_choice "" "is null" "= :style_choice"] + ++ Index: openacs-4/packages/dotlrn-ecommerce/www/admin/ecommerce/shopping-cart-postgresql.xql =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/dotlrn-ecommerce/www/admin/ecommerce/Attic/shopping-cart-postgresql.xql,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs-4/packages/dotlrn-ecommerce/www/admin/ecommerce/shopping-cart-postgresql.xql 4 Jun 2005 10:05:19 -0000 1.1 @@ -0,0 +1,48 @@ + + ++ + +oracle +8.1.6 ++ + ++ select nvl(base_shipping_cost,0) as base_shipping_cost, + nvl(default_shipping_per_item,0) as default_shipping_per_item, + nvl(weight_shipping_cost,0) as weight_shipping_cost, + nvl(add_exp_base_shipping_cost,0) as add_exp_base_shipping_cost, + nvl(add_exp_amount_per_item,0) as add_exp_amount_per_item, + nvl(add_exp_amount_by_weight,0) as add_exp_amount_by_weight + from ec_admin_settings + ++ + ++ 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 + from ec_orders o, ec_items i, ec_products p, + (select product_id, offer_code from ec_user_session_offer_codes usoc where usoc.user_session_id=:user_session_id) u + where i.product_id=p.product_id + and o.order_id=i.order_id + and p.product_id=u.product_id(+) + and o.user_session_id=:user_session_id and o.order_state='in_basket' + group by p.product_name, p.one_line_description, p.no_shipping_avail_p, p.shipping, p.shipping_additonal, p.weight, p.product_id, u.offer_code, i.color_choice, i.size_choice, i.style_choice + ++ + ++ select i.product_id, i.color_choice, i.size_choice, i.style_choice, count(*) as item_count, u.offer_code + from ec_products p, ec_items i, ec_user_session_offer_codes u + where u.product_id(+)=i.product_id and (u.user_session_id is null or u.user_session_id=:user_session_id) + and i.product_id = p.product_id + and p.no_shipping_avail_p = 'f' + and i.order_id = :order_id + group by i.product_id, i.color_choice, i.size_choice, i.style_choice, u.offer_code + ++ Index: openacs-4/packages/dotlrn-ecommerce/www/admin/ecommerce/shopping-cart-quantities-change-oracle.xql =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/dotlrn-ecommerce/www/admin/ecommerce/Attic/shopping-cart-quantities-change-oracle.xql,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs-4/packages/dotlrn-ecommerce/www/admin/ecommerce/shopping-cart-quantities-change-oracle.xql 4 Jun 2005 10:05:19 -0000 1.1 @@ -0,0 +1,18 @@ + + ++ + +postgresql +7.1 ++ + ++ select coalesce(base_shipping_cost,0) as base_shipping_cost, + coalesce(default_shipping_per_item,0) as default_shipping_per_item, + coalesce(weight_shipping_cost,0) as weight_shipping_cost, + coalesce(add_exp_base_shipping_cost,0) as add_exp_base_shipping_cost, + coalesce(add_exp_amount_per_item,0) as add_exp_amount_per_item, + coalesce(add_exp_amount_by_weight,0) as add_exp_amount_by_weight + from ec_admin_settings + ++ + ++ select p.product_name, p.one_line_description, p.no_shipping_avail_p, p.shipping, p.shipping_additional, p.weight, p.product_id, 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) + left join (select product_id, offer_code + from ec_user_session_offer_codes usoc + where usoc.user_session_id=:user_session_id) u on (p.product_id=u.product_id) + where o.user_session_id=:user_session_id + and o.order_state='in_basket' + 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 + ++ + ++ select i.product_id, i.color_choice, i.size_choice, i.style_choice, count(*) as item_count, u.offer_code + from ec_products p, ec_items i + left join ec_user_session_offer_codes u on (u.product_id = i.product_id and u.user_session_id = :user_session_id) + where i.product_id = p.product_id + and p.no_shipping_avail_p = 'f' + and i.order_id = :order_id + group by i.product_id, i.color_choice, i.size_choice, i.style_choice, u.offer_code + ++ Index: openacs-4/packages/dotlrn-ecommerce/www/admin/ecommerce/shopping-cart-quantities-change-postgresql.xql =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/dotlrn-ecommerce/www/admin/ecommerce/Attic/shopping-cart-quantities-change-postgresql.xql,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs-4/packages/dotlrn-ecommerce/www/admin/ecommerce/shopping-cart-quantities-change-postgresql.xql 4 Jun 2005 10:05:19 -0000 1.1 @@ -0,0 +1,18 @@ + + ++ + +oracle +8.1.6 ++ + ++ insert into ec_items + (item_id, product_id, color_choice, size_choice, style_choice, order_id, in_cart_date) + values + (ec_item_id_sequence.nextval, :product_id, :color_choice, :size_choice, :style_choice, :order_id, sysdate) + ++ Index: openacs-4/packages/dotlrn-ecommerce/www/admin/ecommerce/shopping-cart-quantities-change.tcl =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/dotlrn-ecommerce/www/admin/ecommerce/Attic/shopping-cart-quantities-change.tcl,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs-4/packages/dotlrn-ecommerce/www/admin/ecommerce/shopping-cart-quantities-change.tcl 4 Jun 2005 10:05:19 -0000 1.1 @@ -0,0 +1,164 @@ +# www/ecommerce/shopping-cart-quantities-change.tcl +ad_page_contract { + + Changes the quantity of an item in an order. An item is a unique + combination of product_id, Color, Size, and Style. In addition, + each item is represented by a row in the database, so changing + quantities involves inserting and deleting rows. + + @quantity -- an array whose keys are tcl lists of product_id, color, size, and style + @param return_url -- optional, probably will take the user back to process_order_quantity_shipping.tcl + @author original author unknown (eveander@arsdigita.com?) + @author heavily modified by jgoler@arsdigita.com + @author hbrock@arsdigita.com + @creation-date + @cvs-id $Id: shopping-cart-quantities-change.tcl,v 1.1 2005/06/04 10:05:19 hamiltonc Exp $ + @author ported by Jerry Asher (jerry@theashergroup.com) +} { + return_url:optional + quantity:array,naturalnum +} + + +set user_session_id [ec_get_user_session_id] + + + +if { $user_session_id == 0 } { + doc_return 200 text/html "[ad_header "No Cart Found"]+ + +postgresql +7.1 ++ + ++ insert into ec_items + (item_id, product_id, color_choice, size_choice, style_choice, order_id, in_cart_date) + values + (ec_item_id_sequence.nextval, :product_id, :color_choice, :size_choice, :style_choice, :order_id, current_timestamp) + +No Shopping Cart Found
++ We could not find any shopping cart for you. This may be because you have cookies + turned off on your browser. Cookies are necessary in order to have a shopping cart + system so that we can tell which items are yours. + +
+ In Netscape 4.0, you can enable cookies from Edit -> Preferences -> Advanced.
+ + In Microsoft Internet Explorer 4.0, you can enable cookies from View -> + Internet Options -> Advanced -> Security. + ++ + [ec_continue_shopping_options] + " + ad_script_abort +} + +set order_id [db_string get_order_id "select order_id from ec_orders where order_state='in_basket' and user_session_id=:user_session_id" -default ""] + +# if order_id is null, this probably means that they got to this page by pushing back +# so just return them to their empty cart + +if { [empty_string_p $order_id] } { + rp_internal_redirect "shopping-cart" + ad_script_abort +} + +db_foreach get_products_w_attribs " + select i.product_id, + i.color_choice, + i.size_choice, + i.style_choice, + count(*) as r_quantity + from ec_orders o, + ec_items i + where o.order_id=i.order_id + and o.user_session_id=:user_session_id + and o.order_state='in_basket' + group by i.product_id, + i.color_choice, + i.size_choice, + i.style_choice + " { + + set pid_bak $product_id + + set array_value [list $product_id $color_choice $size_choice $style_choice] + regsub -all "{" $array_value {} array_value + regsub -all "}" $array_value {} array_value + + set real_quantity($array_value) $r_quantity +} + +# quantity_to_add might be negative +# also there are two special cases that may come about, for instace, +# when a user pushes "Back" to get here after having altered their cart +# (1) if quantity($product_id) exists but real_quantity($product_id) +# doesn't exist, then ignore it (we're going to miss that +# product_id anyway when looping through product_id_list) +# (2) if real_quantity($product_id) exists but quantity($product_id) +# doesn't exist then quantity_to_add will be 0 + +# set product_id [lindex $product_color_size_style 0] +# set color_choice [lindex $product_color_size_style 1] +# set size_choice [lindex $product_color_size_style 2] +# set style_choice [lindex $product_color_size_style 3] + +set max_quantity_to_add [parameter::get -parameter CartMaxToAdd] + +db_transaction { + + foreach product_color_size_style [array names quantity] { + + set product_lookup $product_color_size_style + + regsub -all "{" $product_lookup {} product_lookup + regsub -all "}" $product_lookup {} product_lookup + + if { [info exists real_quantity($product_lookup)] } { + + set quantity_to_add "[expr $quantity($product_color_size_style) - $real_quantity($product_lookup)]" + + set product_id [lindex $product_color_size_style 0] + set color_choice [lindex $product_color_size_style 1] + set size_choice [lindex $product_color_size_style 2] + set style_choice [lindex $product_color_size_style 3] + + if { $quantity_to_add > 0 } { + set remaining_quantity [min $quantity_to_add $max_quantity_to_add] + while { $remaining_quantity > 0 } { + + db_dml insert_new_quantity_to_add "insert into ec_items + (item_id, product_id, color_choice, size_choice, style_choice, order_id, in_cart_date) + values + (ec_item_id_sequence.nextval, :product_id, :color_choice, :size_choice, :style_choice, :order_id, sysdate)" + set remaining_quantity [expr $remaining_quantity - 1] + } + } elseif { $quantity_to_add < 0 } { + set remaining_quantity [expr abs($quantity_to_add)] + + set rows_to_delete [list] + while { $remaining_quantity > 0 } { + # determine the rows to delete in ec_items (the last instance of this product within this order) + if { [llength $rows_to_delete] > 0 } { + set extra_condition "and item_id not in ([join $rows_to_delete ", "])" + } else { + set extra_condition "" + } + lappend rows_to_delete [db_string get_rows_to_delete " + select max(item_id) + from ec_items + where product_id=:product_id + and color_choice [ec_decode $color_choice "" "is null" "= :color_choice"] + and size_choice [ec_decode $size_choice "" "is null" "= :size_choice"] + and style_choice [ec_decode $style_choice "" "is null" "= :style_choice"] + and order_id=:order_id $extra_condition"] + + set remaining_quantity [expr $remaining_quantity - 1] + } + db_dml delete_from_ec_items "delete from ec_items where item_id in ([join $rows_to_delete ", "])" + } + # otherwise, do nothing + } + } +} + +db_release_unused_handles + +if { [info exists return_url] } { + ad_returnredirect $return_url +} else { + rp_internal_redirect shopping-cart +} + + Index: openacs-4/packages/dotlrn-ecommerce/www/admin/ecommerce/shopping-cart-quantities-change.xql =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/dotlrn-ecommerce/www/admin/ecommerce/Attic/shopping-cart-quantities-change.xql,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs-4/packages/dotlrn-ecommerce/www/admin/ecommerce/shopping-cart-quantities-change.xql 4 Jun 2005 10:05:19 -0000 1.1 @@ -0,0 +1,41 @@ + + +
+ + + + ++ select order_id from ec_orders where order_state='in_basket' and user_session_id=:user_session_id + ++ + ++ select i.product_id, i.color_choice, i.size_choice, i.style_choice, count(*) as r_quantity + from ec_orders o, ec_items i + where o.order_id=i.order_id + and o.user_session_id=:user_session_id + and o.order_state='in_basket' + group by i.product_id, i.color_choice, i.size_choice, i.style_choice + ++ + ++ select max(item_id) + from ec_items + where product_id=:product_id + and color_choice [ec_decode $color_choice "" "is null" "= :color_choice"] + and size_choice [ec_decode $size_choice "" "is null" "= :size_choice"] + and style_choice [ec_decode $style_choice "" "is null" "= :style_choice"] + and order_id=:order_id $extra_condition + ++ + ++ delete from ec_items + where item_id in ([join $rows_to_delete ", "]) + +