Index: openacs-4/packages/ecommerce/ecommerce.info =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/ecommerce/ecommerce.info,v diff -u -r1.19 -r1.20 --- openacs-4/packages/ecommerce/ecommerce.info 9 Mar 2002 02:00:02 -0000 1.19 +++ openacs-4/packages/ecommerce/ecommerce.info 26 May 2002 04:36:49 -0000 1.20 @@ -7,17 +7,17 @@ f f - + oracle postgresql Janine Sisk - Jerry Asher - The goal of this release was to bring the ACS 3x ecommerce module's features to an ACS 4x package. - 2001-04-08 + Bart Teeuwisse + ACS 3.x based e-commerce solution. This version represents a major overhaul of the prior version (4.2a). See the documentation for more information. + 2002-05-13 furfly.net, LLC - This module implements all that IT needs for a standard business-to-consumer Web service. You can find a feature summary in the www/doc/ecommerce-features document. + This module implements all that IT needs for a standard business-to-consumer Web service. You can find a feature summary in the documentaion. @@ -32,11 +32,8 @@ - - - @@ -50,14 +47,12 @@ - + - - @@ -87,8 +82,6 @@ - - @@ -103,9 +96,21 @@ + - + + + + + + + + + + + + @@ -314,7 +319,6 @@ - @@ -382,6 +386,7 @@ + @@ -400,7 +405,6 @@ - @@ -426,6 +430,7 @@ + @@ -547,7 +552,6 @@ - @@ -702,70 +706,96 @@ + + + + + + + + + - - + + + + + + + - + + + - + + + - - - + + + + + + + + + + + @@ -777,17 +807,23 @@ + + + + + + @@ -803,8 +839,10 @@ + + @@ -855,23 +893,19 @@ + + + + - - - - - - - - @@ -886,71 +920,47 @@ + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + - @@ -963,9 +973,6 @@ - - - @@ -990,16 +997,13 @@ - - - - - - - - + + + + + Index: openacs-4/packages/ecommerce/sql/oracle/ecommerce-create.sql =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/ecommerce/sql/oracle/ecommerce-create.sql,v diff -u -r1.5 -r1.6 --- openacs-4/packages/ecommerce/sql/oracle/ecommerce-create.sql 22 Oct 2001 06:48:49 -0000 1.5 +++ openacs-4/packages/ecommerce/sql/oracle/ecommerce-create.sql 26 May 2002 04:36:49 -0000 1.6 @@ -24,7 +24,6 @@ -- gilbertw: acs-references is not complete yet. use old acs-geo-tables until -- acs-references is done -@@ acs-geo-tables-create.sql -- product display templates create sequence ec_template_id_sequence start with 2; @@ -546,18 +545,17 @@ create table ec_creditcards ( creditcard_id integer not null primary key, user_id not null references users, - -- Cybercash does not ask for this but we'll store it anyway + -- Some credit card gateways do not ask for this but we'll store it anyway creditcard_type char(1), -- no spaces; always 16 digits (oops; except for AMEX, which is 15) - -- depending on admin settings, after we get success from Cybercash, + -- depending on admin settings, after we get success from the credit card gateway, -- we may bash this to NULL -- we make this a VARCHAR so it doesn't get padded by Oracle creditcard_number varchar(16), -- just the last four digits for subsequent UI creditcard_last_four char(4), -- ##/## creditcard_expire char(5), - billing_zip_code varchar(80), -- if it ever failed (conclusively), set this to 't' so we -- won't give them the option of using it again failed_p char(1) default 'f' check (failed_p in ('t','f')) @@ -1265,7 +1263,7 @@ as select * from ec_orders -where order_state in ('authorized_plus_avs','authorized_minus_avs','partially_fulfilled'); +where order_state in ('authorized','partially_fulfilled'); -- this is needed because orders might be only partially shipped @@ -1278,7 +1276,7 @@ -- in ec_orders because a customer may change their address between -- shipments. -- a trigger fills address_id in automatically if it's null - address_id not null references ec_addresses, + address_id references ec_addresses, shipment_date date not null, expected_arrival_date date, carrier varchar(50), -- e.g., 'fedex' @@ -1995,13 +1993,13 @@ as select * from ec_gift_certificates -where gift_certificate_state in ('authorized','authorized_plus_avs','authorized_minus_avs'); +where gift_certificate_state in ('authorized'); create or replace view ec_gift_certificates_purchased as select * from ec_gift_certificates -where gift_certificate_state in ('authorized_plus_avs','authorized_minus_avs'); +where gift_certificate_state in ('authorized'); create or replace view ec_gift_certificates_issued as @@ -2393,7 +2391,9 @@ create sequence ec_transaction_id_sequence start with 4000000; create table ec_financial_transactions ( - transaction_id integer not null primary key, + transaction_id varchar(20) not null primary key, + -- The charge transaction that a refund transaction refunded. + refunded_transaction_id varchar(20) references ec_financial_transactions, -- order_id or gift_certificate_id must be filled in order_id references ec_orders, -- The following two rows were added 1999-08-11. They're @@ -2409,6 +2409,7 @@ -- a trigger fills the creditcard_id in if it's not specified creditcard_id not null references ec_creditcards, transaction_amount number not null, + refunded_amount number, -- charge doesn't imply that a charge will actually occur; it's just -- an authorization to charge -- in the case of a refund, there's no such thing as an authorization @@ -2424,15 +2425,7 @@ -- set when to_be_captured_p becomes 't'; used in cron jobs to_be_captured_date date, marked_date date, - settled_date date, refunded_date date, - refund_settled_date date, - -- generated by us talking to Cybercash - disputed_p char(1) check (disputed_p in ('t','f')), - -- date on which we discovered the dispute - dispute_discovery_date date, - -- if the consumer's bank got his money back from us forcibly - charged_back_p char(1) check (charged_back_p in ('t','f')), -- if the transaction failed, this will keep the cron jobs from continuing -- to retry it failed_p char(1) default 'f' check (failed_p in ('t','f')), @@ -2470,42 +2463,6 @@ / show errors -create table ec_cybercash_log ( - transaction_id not null references ec_financial_transactions, - -- The types of transactions that will be logged here are - -- mauthonly, postauth, return, void, retry, query - txn_attempted_type varchar(25), - txn_attempted_time date, - -- Everything below this line is returned by CyberCash. Note - -- that not all columns will have values (for instance, cc_time - -- is only returned when doing a query, aux_msg is not returned - -- when doing a query, ref-code never seems to be returned, - -- batch-id is only returned when querying for settled or setlret). - -- Note: when doing a non-query, there is no txn_type returned - -- by CyberCash, so this value will be inserted by talk_to_cybercash - -- procedure. The reason for doing this is consistency; for - -- example the attempted transaction type may be mauthonly, but later - -- when querying for this authorization, the txn_type is auth. So, - -- auth will be inserted into txn_type when doing an mauthonly. - txn_type varchar(25), - -- we take the time returned by CyberCash and chop off the - -- sub-second precision - cc_time date, - merch_txn varchar(25), - cust_txn varchar(25), - origin char(1), - txn_status varchar(25), - errloc varchar(25), - errmsg varchar(200), - aux_msg varchar(200), - auth_code varchar(25), - action_code varchar(25), - avs_code varchar(3), - ref_code varchar(25), - batch_id varchar(25), - amount number -); - -- END CREDIT CARD STUFF ---------------------------- ----------------------------------------------------- @@ -2678,7 +2635,12 @@ min_shipment_id ec_shipments.shipment_id%TYPE; BEGIN SELECT order_id into v_order_id FROM ec_shipments where shipment_id=v_shipment_id; - SELECT min(shipment_id) into min_shipment_id FROM ec_shipments where order_id=v_order_id; + SELECT min(s.shipment_id) into min_shipment_id + FROM ec_shipments s, ec_items i, ec_products p + WHERE s.order_id=v_order_id + AND s.shipment_id = i.shipment_id + AND i.product_id = p.product_id + AND p.no_shipping_avail_p = 'f'; IF v_shipment_id=min_shipment_id THEN SELECT nvl(shipping_charged,0) - nvl(shipping_refunded,0) into base_shipping FROM ec_orders where order_id=v_order_id; ELSE @@ -2703,7 +2665,12 @@ min_shipment_id ec_shipments.shipment_id%TYPE; BEGIN SELECT order_id into v_order_id FROM ec_shipments where shipment_id=v_shipment_id; - SELECT min(shipment_id) into min_shipment_id FROM ec_shipments where order_id=v_order_id; + SELECT min(s.shipment_id) into min_shipment_id + FROM ec_shipments s, ec_items i, ec_products p + WHERE s.order_id=v_order_id + AND s.shipment_id = i.shipment_id + AND i.product_id = p.product_id + AND p.no_shipping_avail_p = 'f'; IF v_shipment_id=min_shipment_id THEN SELECT nvl(shipping_tax_charged,0) - nvl(shipping_tax_refunded,0) into base_shipping_tax FROM ec_orders where order_id=v_order_id; ELSE Index: openacs-4/packages/ecommerce/sql/oracle/ecommerce-defaults.sql =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/ecommerce/sql/oracle/ecommerce-defaults.sql,v diff -u -r1.1 -r1.2 --- openacs-4/packages/ecommerce/sql/oracle/ecommerce-defaults.sql 20 Apr 2001 20:51:12 -0000 1.1 +++ openacs-4/packages/ecommerce/sql/oracle/ecommerce-defaults.sql 26 May 2002 04:36:49 -0000 1.2 @@ -27,10 +27,7 @@ last_modified, last_modifying_user, modified_ip_address ) values ( 1,'Default', - '' || CHR(10) || '<%= $product_name %>' || CHR(10) || '' || CHR(10) - || '' || CHR(10) || CHR(10) - || '$category_id' || CHR(10) - || '

<%= $product_name %>

' || CHR(10) || CHR(10) + '

<%= $product_name %>

' || CHR(10) || CHR(10) || '' || CHR(10) || '' || CHR(10) || ' + + + + " } +if {[string equal $recommendations "
' || CHR(10) @@ -55,10 +52,7 @@ || '<%= [ec_professional_reviews_if_they_exist $product_id] %>' || CHR(10) || CHR(10) || '<%= [ec_customer_comments $product_id $comments_sort_by] %>' || CHR(10) || CHR(10) || '

' || CHR(10) || CHR(10) - || '<%= [ec_mailing_list_link_for_a_product $product_id] %>' || CHR(10) || CHR(10) - || '<%= [ec_footer] %>' || CHR(10) - || '' || CHR(10) - || '', + || '<%= [ec_mailing_list_link_for_a_product $product_id] %>', sysdate, (select grantee_id from acs_permissions where object_id = acs.magic_object_id('security_context_root') @@ -254,7 +248,7 @@ || 'Sincerely,' || CHR(10) || 'customer_service_signature_here', 'system_name_here, system_url_here, recipient_email_here, amount_and_message_summary_here, customer_service_signature_here', -'This is sent to customers who tried to purchase a gift certificate but got no immediate response from CyberCash and we found out later the auth failed.', +'This is sent to customers who tried to purchase a gift certificate but got no immediate response from the credit card gateway and we found out later the authorization failed.', '{gift certificate}', sysdate, (select grantee_id from acs_permissions Index: openacs-4/packages/ecommerce/sql/oracle/ecommerce-drop.sql =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/ecommerce/sql/oracle/ecommerce-drop.sql,v diff -u -r1.2 -r1.3 --- openacs-4/packages/ecommerce/sql/oracle/ecommerce-drop.sql 20 Aug 2001 04:12:17 -0000 1.2 +++ openacs-4/packages/ecommerce/sql/oracle/ecommerce-drop.sql 26 May 2002 04:36:49 -0000 1.3 @@ -97,7 +97,6 @@ drop table ec_cat_mailing_lists; drop table ec_spam_log; drop view ec_fin_transactions_reportable; -drop table ec_cybercash_log; drop table ec_problems_log; drop table ec_automatic_email_log; begin @@ -128,15 +127,15 @@ drop sequence ec_category_id_sequence; drop sequence ec_subcategory_id_sequence; drop sequence ec_subsubcategory_id_sequence; --- drop sequence ec_product_id_sequence; +drop sequence ec_product_id_sequence; drop sequence ec_sale_price_id_sequence; drop sequence ec_address_id_sequence; drop sequence ec_creditcard_id_sequence; drop sequence ec_user_class_id_sequence; drop sequence ec_recommendation_id_sequence; drop sequence ec_product_comment_id_sequence; drop sequence ec_product_review_id_sequence; --- drop sequence ec_user_session_sequence; +drop sequence ec_user_session_sequence; drop sequence ec_order_id_sequence; drop sequence ec_shipment_id_sequence; drop sequence refund_id_sequence; Index: openacs-4/packages/ecommerce/sql/postgresql/ecommerce-create.sql =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/ecommerce/sql/postgresql/ecommerce-create.sql,v diff -u -r1.14 -r1.15 --- openacs-4/packages/ecommerce/sql/postgresql/ecommerce-create.sql 7 Jan 2002 02:02:16 -0000 1.14 +++ openacs-4/packages/ecommerce/sql/postgresql/ecommerce-create.sql 26 May 2002 04:36:49 -0000 1.15 @@ -28,7 +28,6 @@ -- gilbertw: acs-references is not complete yet. use old acs-geo-tables until -- acs-references is done -\i acs-geo-tables-create.sql -- product display templates create sequence ec_template_id_seq start 2; @@ -628,18 +627,17 @@ create table ec_creditcards ( creditcard_id integer not null primary key, user_id integer not null references users, - -- Cybercash does not ask for this but we'll store it anyway + -- Some credit card gateways do not ask for this but we'll store it anyway creditcard_type char(1), -- no spaces; always 16 digits (oops; except for AMEX, which is 15) - -- depending on admin settings, after we get success from Cybercash, + -- depending on admin settings, after we get success from the credit card gateway, -- we may bash this to NULL - -- we make this a VARCHAR so it doesn't get padded by Oracle creditcard_number varchar(16), -- just the last four digits for subsequent UI creditcard_last_four char(4), -- ##/## creditcard_expire char(5), - billing_zip_code varchar(80), + billing_address integer references ec_addresses(address_id), -- if it ever failed (conclusively), set this to 't' so we -- won't give them the option of using it again failed_p boolean default 'f' @@ -1386,7 +1384,7 @@ as select * from ec_orders -where order_state in ('authorized_plus_avs','authorized_minus_avs','partially_fulfilled'); +where order_state in ('authorized','partially_fulfilled'); -- this is needed because orders might be only partially shipped @@ -1400,7 +1398,7 @@ -- in ec_orders because a customer may change their address between -- shipments. -- a trigger fills address_id in automatically if it's null - address_id integer not null references ec_addresses, + address_id integer references ec_addresses, shipment_date timestamp not null, expected_arrival_date timestamp, carrier varchar(50), -- e.g., 'fedex' @@ -2155,13 +2153,13 @@ as select * from ec_gift_certificates -where gift_certificate_state in ('authorized','authorized_plus_avs','authorized_minus_avs'); +where gift_certificate_state in ('authorized'); create view ec_gift_certificates_purchased as select * from ec_gift_certificates -where gift_certificate_state in ('authorized_plus_avs','authorized_minus_avs'); +where gift_certificate_state in ('authorized'); create view ec_gift_certificates_issued as @@ -2579,7 +2577,9 @@ create view ec_transaction_id_sequence as select nextval('ec_transaction_id_seq') as nextval; create table ec_financial_transactions ( - transaction_id integer not null primary key, + transaction_id varchar(20) not null primary key, + -- The charge transaction that a refund transaction refunded. + refunded_transaction_id varchar(20) references ec_financial_transactions, -- order_id or gift_certificate_id must be filled in order_id integer references ec_orders, -- The following two rows were added 1999-08-11. They re @@ -2595,7 +2595,8 @@ -- a trigger fills the creditcard_id in if it s not specified creditcard_id integer not null references ec_creditcards, transaction_amount numeric not null, - -- charge doesn t imply that a charge will actually occur; it s just + refunded_amount numeric, + -- charge doesn't imply that a charge will actually occur; it s just -- an authorization to charge -- in the case of a refund, theres no such thing as an authorization -- to refund, so the refund really will occur @@ -2610,15 +2611,7 @@ -- set when to_be_captured_p becomes 't'; used in cron jobs to_be_captured_date timestamp, marked_date timestamp, - settled_date timestamp, refunded_date timestamp, - refund_settled_date timestamp, - -- generated by us talking to Cybercash - disputed_p boolean, - -- date on which we discovered the dispute - dispute_discovery_date timestamp, - -- if the consumer's bank got his money back from us forcibly - charged_back_p boolean, -- if the transaction failed, this will keep the cron jobs from continuing -- to retry it failed_p boolean default 'f', @@ -2659,42 +2652,6 @@ before insert on ec_financial_transactions for each row execute procedure fin_trans_ccard_update_tr (); -create table ec_cybercash_log ( - transaction_id integer not null references ec_financial_transactions, - -- The types of transactions that will be logged here are - -- mauthonly, postauth, return, void, retry, query - txn_attempted_type varchar(25), - txn_attempted_time timestamp, - -- Everything below this line is returned by CyberCash. Note - -- that not all columns will have values (for instance, cc_time - -- is only returned when doing a query, aux_msg is not returned - -- when doing a query, ref-code never seems to be returned, - -- batch-id is only returned when querying for settled or setlret). - -- Note: when doing a non-query, there is no txn_type returned - -- by CyberCash, so this value will be inserted by talk_to_cybercash - -- procedure. The reason for doing this is consistency; for - -- example the attempted transaction type may be mauthonly, but later - -- when querying for this authorization, the txn_type is auth. So, - -- auth will be inserted into txn_type when doing an mauthonly. - txn_type varchar(25), - -- we take the time returned by CyberCash and chop off the - -- sub-second precision - cc_time timestamp, - merch_txn varchar(25), - cust_txn varchar(25), - origin char(1), - txn_status varchar(25), - errloc varchar(25), - errmsg varchar(200), - aux_msg varchar(200), - auth_code varchar(25), - action_code varchar(25), - avs_code varchar(3), - ref_code varchar(25), - batch_id varchar(25), - amount numeric -); - -- END CREDIT CARD STUFF ---------------------------- ----------------------------------------------------- @@ -2840,16 +2797,20 @@ create function ec_shipment_shipping (integer) returns numeric as ' DECLARE - v_shipment_id alias for $1; + v_shipment_id alias for $1; item_shipping numeric; base_shipping numeric; v_order_id ec_orders.order_id%TYPE; min_shipment_id ec_shipments.shipment_id%TYPE; BEGIN SELECT into v_order_id order_id FROM ec_shipments where shipment_id=v_shipment_id; - SELECT into min_shipment_id min(shipment_id) - FROM ec_shipments where order_id=v_order_id; + SELECT into min_shipment_id min(s.shipment_id) + from ec_shipments s, ec_items i, ec_products p + where s.order_id = v_order_id + and s.shipment_id = i.shipment_id + and i.product_id = p.product_id + and p.no_shipping_avail_p = ''f''; IF v_shipment_id=min_shipment_id THEN SELECT into base_shipping coalesce(shipping_charged,0) - coalesce(shipping_refunded,0) @@ -2871,7 +2832,7 @@ create function ec_shipment_tax (integer) returns numeric as ' DECLARE - v_shipment_id alias for $1; + v_shipment_id alias for $1; item_price_tax numeric; item_shipping_tax numeric; base_shipping_tax numeric; @@ -2880,8 +2841,12 @@ BEGIN SELECT into v_order_id order_id FROM ec_shipments where shipment_id=v_shipment_id; - SELECT into min_shipment_id min(shipment_id) - FROM ec_shipments where order_id=v_order_id; + SELECT into min_shipment_id min(s.shipment_id) + from ec_shipments s, ec_items i, ec_products p + where s.order_id = v_order_id + and s.shipment_id = i.shipment_id + and i.product_id = p.product_id + and p.no_shipping_avail_p = ''f''; IF v_shipment_id=min_shipment_id THEN SELECT into base_shipping_tax coalesce(shipping_tax_charged,0) - coalesce(shipping_tax_refunded,0) @@ -3143,12 +3108,12 @@ create function gift_certificate_amount_left (integer) returns numeric as ' DECLARE - v_gift_certificate_id alias for $1; + v_gift_certificate_id alias for $1; original_amount numeric; - amount_used numeric; + total_amount_used numeric; BEGIN SELECT coalesce(sum(amount_used),0) - coalesce(sum(amount_reinstated),0) - into amount_used + into total_amount_used FROM ec_gift_certificate_usage WHERE gift_certificate_id = v_gift_certificate_id; @@ -3157,7 +3122,7 @@ FROM ec_gift_certificates WHERE gift_certificate_id = v_gift_certificate_id; - RETURN original_amount - amount_used; + RETURN original_amount - total_amount_used; END;' language 'plpgsql'; -- I DON'T USE THIS PROCEDURE ANYMORE BECAUSE THERE'S A MORE Index: openacs-4/packages/ecommerce/sql/postgresql/ecommerce-defaults.sql =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/ecommerce/sql/postgresql/ecommerce-defaults.sql,v diff -u -r1.1 -r1.2 --- openacs-4/packages/ecommerce/sql/postgresql/ecommerce-defaults.sql 9 Jul 2001 23:44:19 -0000 1.1 +++ openacs-4/packages/ecommerce/sql/postgresql/ecommerce-defaults.sql 26 May 2002 04:36:49 -0000 1.2 @@ -27,10 +27,7 @@ last_modified, last_modifying_user, modified_ip_address ) values ( 1,'Default', - '' || '\n' || '<%= $product_name %>' || '\n' || '' || '\n' - || '' || '\n' || '\n' - || '$category_id' || '\n' - || '

<%= $product_name %>

' || '\n' || '\n' + '

<%= $product_name %>

' || '\n' || '\n' || '' || '\n' || '' || '\n' || ' + + + + + + + +
' || '\n' @@ -55,10 +52,7 @@ || '<%= [ec_professional_reviews_if_they_exist $product_id] %>' || '\n' || '\n' || '<%= [ec_customer_comments $product_id $comments_sort_by] %>' || '\n' || '\n' || '

' || '\n' || '\n' - || '<%= [ec_mailing_list_link_for_a_product $product_id] %>' || '\n' || '\n' - || '<%= [ec_footer] %>' || '\n' - || '' || '\n' - || '', + || '<%= [ec_mailing_list_link_for_a_product $product_id] %>' || '\n' || '\n', now(), (select grantee_id from acs_permissions where object_id = acs__magic_object_id('security_context_root') @@ -254,7 +248,7 @@ || 'Sincerely,' || '\n' || 'customer_service_signature_here', 'system_name_here, system_url_here, recipient_email_here, amount_and_message_summary_here, customer_service_signature_here', -'This is sent to customers who tried to purchase a gift certificate but got no immediate response from CyberCash and we found out later the auth failed.', +'This is sent to customers who tried to purchase a gift certificate but got no immediate response from the credit card gateway and we found out later the authorization failed.', '{gift certificate}', now(), (select grantee_id from acs_permissions Index: openacs-4/packages/ecommerce/sql/postgresql/ecommerce-drop.sql =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/ecommerce/sql/postgresql/ecommerce-drop.sql,v diff -u -r1.7 -r1.8 --- openacs-4/packages/ecommerce/sql/postgresql/ecommerce-drop.sql 31 Jan 2002 06:41:59 -0000 1.7 +++ openacs-4/packages/ecommerce/sql/postgresql/ecommerce-drop.sql 26 May 2002 04:36:49 -0000 1.8 @@ -26,7 +26,6 @@ drop table ec_problems_log; drop view ec_problem_id_sequence; drop sequence ec_problem_id_seq; -drop table ec_cybercash_log; drop trigger fin_trans_ccard_update_tr on ec_financial_transactions; drop function fin_trans_ccard_update_tr(); drop view ec_fin_transactions_reportable; @@ -221,11 +220,12 @@ drop view ec_products_searchable; drop view ec_products_displayable; \i ec-product-sc-drop.sql +\i ec-product-package-drop.sql drop table ec_products; -- nuke all created objects -- need to do this before nuking the type --- delete from acs_objects where object_type = 'ec_product'; +delete from acs_objects where object_type = 'ec_product'; create function inline_0 () returns integer as ' begin @@ -235,7 +235,6 @@ select inline_0 (); drop function inline_0 (); -\i ec-product-package-drop.sql drop view ec_subsubcategories_augmented; drop trigger ec_subsubcategories_audit_tr on ec_subsubcategories; Index: openacs-4/packages/ecommerce/sql/postgresql/pl-sql-utilities.sql =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/ecommerce/sql/postgresql/pl-sql-utilities.sql,v diff -u -r1.2 -r1.3 --- openacs-4/packages/ecommerce/sql/postgresql/pl-sql-utilities.sql 22 Jul 2001 05:20:32 -0000 1.2 +++ openacs-4/packages/ecommerce/sql/postgresql/pl-sql-utilities.sql 26 May 2002 04:36:49 -0000 1.3 @@ -6,23 +6,6 @@ -- useful pl/sql utility procedures -- --- gilbertw - logical_negation is defined in utilities-create.sql in acs-kernel --- create function logical_negation (boolean) --- returns boolean as ' --- DECLARE --- true_or_false alias for $1; --- BEGIN --- IF true_or_false is null THEN --- return null; --- ELSE --- IF true_or_false = ''f'' THEN --- return ''t''; --- ELSE --- return ''f''; --- END IF; --- END IF; --- END;' language 'plpgsql'; - -- useful for ecommerce and other situations where you want to -- know whether something happened within last N days (assumes query_date -- is in the past) @@ -33,45 +16,44 @@ query_date alias for $1; n_days alias for $2; begin - IF current_timestamp - query_date <= timespan_days(n_days) THEN + if current_timestamp - query_date <= timespan_days(n_days) then return 1; - ELSE + else return 0; - END IF; + end if; end;' language 'plpgsql'; create function pseudo_contains (varchar, varchar) returns integer as ' -DECLARE - indexed_stuff alias for $1; - space_sep_list_untrimmed alias for $2; +declare + indexed_stuff alias for $1; + space_sep_list_untrimmed alias for $2; space_sep_list text; upper_indexed_stuff text; - -- if you call this var START you get hosed royally + -- if you call this var start you get hosed royally first_space integer; score integer; -BEGIN +begin space_sep_list := upper(ltrim(rtrim(space_sep_list_untrimmed))); upper_indexed_stuff := upper(indexed_stuff); score := 0; - IF space_sep_list is null or indexed_stuff is null THEN - RETURN score; - END IF; - LOOP + if space_sep_list is null or indexed_stuff is null then + return score; + end if; + loop first_space := position('' '' in space_sep_list); - IF first_space = 0 THEN + if first_space = 0 then -- one token or maybe end of list - IF position(space_sep_list in upper_indexed_stuff) <> 0 THEN - RETURN score+10; - END IF; - RETURN score; - ELSE - -- first_space <> 0 - IF position(substring(space_sep_list from 1 to first_space-1) in upper_indexed_stuff) <> 0 THEN + if position(space_sep_list in upper_indexed_stuff) <> 0 then + return score+10; + end if; + return score; + else + -- first_space <> 0 + if position(substring(space_sep_list from 1 for first_space-1) in upper_indexed_stuff) <> 0 then score := score + 10; - END IF; - END IF; + end if; + end if; space_sep_list := substring(space_sep_list from first_space+1); - END LOOP; -END;' language 'plpgsql'; - + end loop; +end;' language 'plpgsql'; Index: openacs-4/packages/ecommerce/tcl/ec-audit-trail-procs-postgresql.xql =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/ecommerce/tcl/ec-audit-trail-procs-postgresql.xql,v diff -u -r1.3 -r1.4 --- openacs-4/packages/ecommerce/tcl/ec-audit-trail-procs-postgresql.xql 25 Aug 2001 06:14:48 -0000 1.3 +++ openacs-4/packages/ecommerce/tcl/ec-audit-trail-procs-postgresql.xql 26 May 2002 04:36:49 -0000 1.4 @@ -1,36 +1,28 @@ - postgresql7.1 + + postgresql + 7.1 + - - - - insert into $audit_table_name - ($id_column_join last_modified, - last_modifying_user, modified_ip_address, delete_p) - values ($id_column_bind_join current_timestamp, - :last_modifying_user, :modified_ip_address, :delete_p) - - - + + + insert into $audit_table_name + ($id_column_join last_modified, last_modifying_user, modified_ip_address, delete_p) + values + ($id_column_bind_join current_timestamp, :last_modifying_user, :modified_ip_address, :delete_p) + + - - - - select $audit_table_name.*, - $audit_table_name.oid as rowid, - to_char($audit_table_name.last_modified, - 'Mon DD, YYYY HH12:MI AM') as last_modified, - users.first_names || ' ' || users.last_name - as modifying_user_name + + + select $audit_table_name.*, $audit_table_name.oid as rowid, to_char($audit_table_name.last_modified, 'Mon DD, YYYY HH12:MI AM') as last_modified, + users.first_names || ' ' || users.last_name as modifying_user_name from $audit_table_name, cc_users users - where users.user_id = $audit_table_name.last_modifying_user $audit_table_id_clause $date_clause - order by $audit_table_name.last_modified asc - - - - - - + where users.user_id = $audit_table_name.last_modifying_user $audit_table_id_clause $date_clause + order by $audit_table_name.last_modified asc + + + Index: openacs-4/packages/ecommerce/tcl/ec-audit-trail-procs.xql =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/ecommerce/tcl/ec-audit-trail-procs.xql,v diff -u -r1.1 -r1.2 --- openacs-4/packages/ecommerce/tcl/ec-audit-trail-procs.xql 10 Jul 2001 20:38:43 -0000 1.1 +++ openacs-4/packages/ecommerce/tcl/ec-audit-trail-procs.xql 26 May 2002 04:36:49 -0000 1.2 @@ -1,26 +1,21 @@ + - - - - select distinct $id_column - from $main_table_name - where [join $date_clause_list "\nand "] - - - + + + select distinct $id_column + from $main_table_name + where [join $date_clause_list "\nand "] + + - - - - - select distinct $id_column - from $main_table_name - where [join $date_clause_list "\nand "] - - - + + + select distinct $id_column + from $main_table_name + where [join $date_clause_list "\nand "] + + - Index: openacs-4/packages/ecommerce/tcl/ecommerce-credit-procs-oracle.xql =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/ecommerce/tcl/ecommerce-credit-procs-oracle.xql,v diff -u -r1.2 -r1.3 --- openacs-4/packages/ecommerce/tcl/ecommerce-credit-procs-oracle.xql 18 Jul 2001 23:46:14 -0000 1.2 +++ openacs-4/packages/ecommerce/tcl/ecommerce-credit-procs-oracle.xql 26 May 2002 04:36:49 -0000 1.3 @@ -1,51 +1,46 @@ - oracle8.1.6 + oracle8.1.6 - - - - select ec_order_cost(:order_id) as total_amount, - creditcard_id, - case when sign(sysdate - confirmed_date - .95) = -1 then 1 else 0 end as youth - from ec_orders - where order_id = :order_id - - - + + + select ec_order_cost(:order_id) as total_amount, creditcard_id, case when sign(sysdate - confirmed_date - .95) = -1 then 1 else 0 end as youth + from ec_orders + where order_id = :order_id + + + + + + select transaction_amount as total_amount, creditcard_id, case when sign(sysdate-inserted_date-.95) = -1 then 1 else 0 end as youth + from ec_financial_transactions + where transaction_id = :transaction_id + + + + + + insert into ec_cybercash_log + ([join [ad_ns_set_keys -exclude "cc_time" $bind_vars] ", "], cc_time, txn_attempted_time) + values + ([join [ad_ns_set_keys -exclude "cc_time" -colon $bind_vars] ", "], to_date(:cc_time, 'YYYYMMDDHH24MISS'), sysdate) + + + + + + select to_char(:n_hours_to_add / 24 + to_date(:the_date, 'YYYY-MM-DD HH24:MI:SS'), 'YYYYMMDDHH24MISS') + from dual + + - - - - - select transaction_amount as total_amount, - creditcard_id, - case when sign(sysdate-inserted_date-.95) = -1 then 1 else 0 end as youth - from ec_financial_transactions - where transaction_id = :transaction_id - - - - - - - - - insert into ec_cybercash_log ([join [ad_ns_set_keys -exclude "cc_time" $bind_vars] ", "], cc_time, txn_attempted_time) - values ([join [ad_ns_set_keys -exclude "cc_time" -colon $bind_vars] ", "], to_date(:cc_time, 'YYYYMMDDHH24MISS'), sysdate) - - - - - - - - - select to_char(:n_hours_to_add / 24 + to_date(:the_date, 'YYYY-MM-DD HH24:MI:SS'), 'YYYYMMDDHH24MISS') from dual - - - - - + + + update ec_financial_transactions + set transaction_id = :pgw_transaction_id, refunded_date = sysdate + where transaction_id = :transaction_id + + + Index: openacs-4/packages/ecommerce/tcl/ecommerce-credit-procs-postgresql.xql =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/ecommerce/tcl/ecommerce-credit-procs-postgresql.xql,v diff -u -r1.4 -r1.5 --- openacs-4/packages/ecommerce/tcl/ecommerce-credit-procs-postgresql.xql 18 Jul 2001 23:46:14 -0000 1.4 +++ openacs-4/packages/ecommerce/tcl/ecommerce-credit-procs-postgresql.xql 26 May 2002 04:36:49 -0000 1.5 @@ -1,51 +1,48 @@ - postgresql7.1 + + postgresql + 7.1 + - - - - select ec_order_cost(:order_id) as total_amount, - creditcard_id, - case when now() - confirmed_date < timespan_days(0.95) then 1 else 0 end as youth - from ec_orders - where order_id = :order_id - - - + + + select ec_order_cost(:order_id) as total_amount, creditcard_id, case when now() - confirmed_date < timespan_days(0.95) then 1 else 0 end as youth + from ec_orders + where order_id = :order_id + + - - - - - select transaction_amount as total_amount, - creditcard_id, - case when now() - inserted_date < timespan_days(0.95) then 1 else 0 end as youth - from ec_financial_transactions - where transaction_id = :transaction_id - - - + + + select transaction_amount as total_amount, creditcard_id, case when now() - inserted_date < timespan_days(0.95) then 1 else 0 end as youth + from ec_financial_transactions + where transaction_id = :transaction_id + + + + + + insert into ec_cybercash_log + ([join [ad_ns_set_keys -exclude "cc_time" $bind_vars] ", "], cc_time, txn_attempted_time) + values + ([join [ad_ns_set_keys -exclude "cc_time" -colon $bind_vars] ", "], to_date(:cc_time, 'YYYYMMDDHH24MISS'), current_timestamp) + + + + + + select to_char(timespan_days(:n_hours_to_add/24::float) + to_date(:the_date, 'YYYY-MM-DD HH24:MI:SS'), 'YYYYMMDDHH24MISS') + + + + + + update ec_financial_transactions + set transaction_id = :pgw_transaction_id, refunded_date = current_timestamp + where transaction_id = :transaction_id + + - - - - - insert into ec_cybercash_log ([join [ad_ns_set_keys -exclude "cc_time" $bind_vars] ", "], cc_time, txn_attempted_time) - values ([join [ad_ns_set_keys -exclude "cc_time" -colon $bind_vars] ", "], to_date(:cc_time, 'YYYYMMDDHH24MISS'), current_timestamp) - - - - - - - - - select to_char(timespan_days(:n_hours_to_add/24::float) + to_date(:the_date, 'YYYY-MM-DD HH24:MI:SS'), 'YYYYMMDDHH24MISS') - - - - - Index: openacs-4/packages/ecommerce/tcl/ecommerce-credit-procs.tcl =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/ecommerce/tcl/ecommerce-credit-procs.tcl,v diff -u -r1.3 -r1.4 --- openacs-4/packages/ecommerce/tcl/ecommerce-credit-procs.tcl 31 Jan 2002 22:43:54 -0000 1.3 +++ openacs-4/packages/ecommerce/tcl/ecommerce-credit-procs.tcl 26 May 2002 04:36:49 -0000 1.4 @@ -1,784 +1,837 @@ -# /tcl/ecommerce-credit.tcl ad_library { Procedures related to credit card transactions for the ecommerce module @author Eve Andersson (eveander@arsdigita.com) @date 1 April 1999 - @cvs-id ecommerce-credit.tcl,v 3.3.2.3 2000/08/17 17:37:13 seb Exp @author ported by Jerry Asher (jerry@theashergroup.com) + @author revised by Bart Teeuwisse + @revision-date April 2002 } -ad_proc ec_creditcard_authorization { order_id {transaction_id ""} } { - does a credit card auth +ad_proc -public ec_creditcard_authorization { + order_id + {transaction_id ""} +} { + + Authorizes the credit card for use with an order. Gets info it + needs from database. Connects to the payment gateway to + authorize card. Outputs one of the following strings, + corresponding to the level of authorization: + + (a) failed_authorization When the payment gateway declined + authorization of the transaction. Or when no payment gateway has + been selected. + + (b) authorized When the transaction is successfully authorized + and passed the address verification. + + (c) no_recommendation When the payment gateway gives an error + that is unrelated to the credit card used, such as timeout or + failure-retry. + + (d) invalid_input When there are no orders with the given + order_id or with no billing_zip. This case shouldn't + happen, since this proc is called from a tcl script with a known + order_id, and billing_zip shouldn't be null. + } { - # Gets info it needs from database. - # Calls ec_talk_to_cybercash to authorize card (which in turn writes a line - # to the ec_cybercash_log table). - # Outputs one of the following strings, corresponding to the level of - # authorization: - # (a) failed_authorization - # (b) authorized_plus_avs - # (c) authorized_minus_avs - # (d) no_recommendation - # (e) invalid_input - # Case (d) occurs when CyberCash gives an error that is unrelated to - # the credit card used, such as timeout or failure-q-or-cancel. - # Case (e) occurs when there are no orders with the given order_id - # or with no billing_zip_code. This case shouldn't - # happen, since this proc is called from a tcl script with known - # order_id, and billing_zip_code shouldn't be null. - # If transaction_id is null, it tries to do an auth for the entire - # order; otherwise it tries to do an auth for the tranaction_amount. - # You can leave order_id blank if you're using a transaction_id - # (useful for gift certificates). + # Lookup the selected currency. - if { [empty_string_p $transaction_id] } { + set currency [ad_parameter Currency ecommerce] - db_1row order_data_select { - select ec_order_cost(:order_id) as total_amount, - creditcard_id, - decode(sign(sysdate - confirmed_date - .95), -1, 1, 0) as youth - from ec_orders - where order_id = :order_id - } + # Lookup the selected payment gateway - } else { + set payment_gateway [ad_parameter PaymentGateway -default [ad_parameter -package_id [ec_id] PaymentGateway]] - db_1row transaction_data_select { - select transaction_amount as total_amount, - creditcard_id, - decode(sign(sysdate-inserted_date-.95),-1,1,0) as youth - from ec_financial_transactions - where transaction_id = :transaction_id - } + # Return an error when no payment gateway has been selected or if + # there is no binding between the selected gateway and the + # PaymentGateway. + if {[empty_string_p $payment_gateway] || ![acs_sc_binding_exists_p "PaymentGateway" $payment_gateway]} { + set outcome(response_code) "failure" + set outcome(transaction_id) "$transaction_id" + return [array get outcome] } - # Check immediately if the total amount is 0, - # and, if so, just authorize it. + # Authorize the entire order when the transaction_id is null, + # otherwise authorize the tranaction_amount. + + # Leave order_id blank if you're using a transaction_id (useful + # for gift certificates). + + if { [empty_string_p $transaction_id] } { + db_1row order_data_select " + select ec_order_cost(:order_id) as total_amount, + creditcard_id from ec_orders + where order_id = :order_id" + } else { + db_1row transaction_data_select " + select transaction_amount as total_amount, creditcard_id + from ec_financial_transactions + where transaction_id = :transaction_id" + } + + # The order amount is 0 (zero) and there is thus no need + # to contact the payment gateway. Record an instant + # success. + if {$total_amount == 0} { - return "authorized_plus_avs" + set outcome(response_code) "authorized" + set outcome(transaction_id) "$transaction_id" + return [array get outcome] } - set currency [ad_parameter -package_id [ec_id] Currency ecommerce] + # Lookup the credit card for the transaction. Record an + # invalid_input error if there isn't one. - # The above decode, "youth", gives a 1 is the order is younger than 95% of - # a day old and a 0 otherwise. It is used to determine whether the - # error message "Invalid Credit Card Number" should be believed. - # Sometimes CyberCash gives the message "Invalid Credit Card Number" - # to cover up its own incompetency. But if it gives this message - # repeatedly throughout the day, then we'll decide to believe it - # because CyberCash has never been down for more than a few hours - # at a time in my (Eve's) experience. I chose 95% of a day instead - # of a whole day because, if we're going to fail the order anyway, it - # should be done before the ecommerce administrator is notified that we couldn't - # determine whether the order was authorizable (which occurs after - # 1 day of trying). + if {![db_0or1row creditcard_data_select " + select c.creditcard_number as card_number, substring(creditcard_expire for 2) as card_exp_month, substring(creditcard_expire from 4 for 2) as card_exp_year, + c.creditcard_type, p.first_names || ' ' || p.last_name as card_name, + a.zip_code as billing_zip, + a.line1 as billing_address, + a.city as billing_city, + coalesce(a.usps_abbrev, a.full_state_name) as billing_state, + a.country_code as billing_country + from ec_creditcards c, persons p, ec_addresses a + where c.user_id=p.person_id + and c.creditcard_id = :creditcard_id + and c.billing_address = a.address_id"]} { + set outcome(response_code) "invalid_input" + set outcome(transaction_id) "$transaction_id" + return [array get outcome] + } - if { - ![db_0or1row creditcard_data_select { - select creditcard_number, creditcard_expire, - billing_zip_code - from ec_creditcards - where creditcard_id = :creditcard_id - }] - } { + # Generate a transaction_id if none has been provided. - set level "invalid_input" + if { [empty_string_p $transaction_id] } { + set transaction_id [db_string latest_transaction_select " + select max(transaction_id) + from ec_financial_transactions + where order_id = :order_id"] + } - } else { + # Convert the one digit creditcard abbreviation to the + # standardized name of the card. + + set card_type [ec_pretty_creditcard_type $creditcard_type] + + # Connect to the payment gateway to authorize the transaction. + + array set response [acs_sc_call "PaymentGateway" "Authorize" \ + [list $transaction_id \ + $total_amount \ + $card_type \ + $card_number \ + $card_exp_month \ + $card_exp_year \ + $card_name \ + $billing_address \ + $billing_city \ + $billing_state \ + $billing_zip \ + $billing_country] \ + $payment_gateway] + + # Extract response_code, reason and the gateway transaction id + # from the response. The response_code values are defined in + # payment-gateway/tcl/payment-gateway-init.tcl. The reason is a + # human readable description of the response and the + # transaction id is the ID as returned by the payment gateway. + + set response_code $response(response_code) + set reason $response(reason) + set pgw_transaction_id $response(transaction_id) + + # Interpret the response_code. + + switch -exact $response_code { - if { [empty_string_p $transaction_id] } { - set transaction_id [db_string latest_transaction_select { - select max(transaction_id) from ec_financial_transactions where order_id = :order_id - }] + "failure" - + "not_supported" - + "not_implemented" { + + # The payment gateway rejected to authorize the + # transaction. Or is not cable of authorizing + # transactions. + + set outcome(response_code) "failed_authorization" + set outcome(transaction_id) "$transaction_id" + return [array get outcome] } + + "failure-retry" { - set cc_args [ns_set new] + # If the response_code is failure-retry, it means there was a + # temporary failure that can be retried. The order will be + # retried the next time the scheduled procedure + # ec_sweep_for_payment_zombies is run. + + set outcome(response_code) "no_recommendation" + set outcome(transaction_id) "$transaction_id" + return [array get outcome] + } - ns_set put $cc_args "amount" "$currency $total_amount" - ns_set put $cc_args "card-number" "$creditcard_number" - ns_set put $cc_args "card-exp" "$creditcard_expire" - ns_set put $cc_args "card-zip" "$billing_zip_code" - ns_set put $cc_args "order-id" "$transaction_id" - - set ttcc_output [ec_talk_to_cybercash "mauthonly" $cc_args] - - # We're interested in the txn_status, errmsg (if any) and avs_code - set txn_status [ns_set get $ttcc_output "txn_status"] - set errmsg [ns_set get $ttcc_output "errmsg"] - set avs_code [ns_set get $ttcc_output "avs_code"] - - # If we get a txn_status of failure-q-or-cancel, it means there was a communications - # failure and we can retry it (right away). - # Actually, I might as well let ec_sweep_for_cybercash_zombies take care of it. - - if { $txn_status == "failure-bad-money" } { - # failed by the financial institution - set level "failed_authorization" - } elseif { $txn_status == "failure-q-or-cancel" || $txn_status == "failure-swversion" } { - # failed because of a communications or software problem - set level "no_recommendation" - } elseif { $txn_status == "success" || $txn_status == "success-duplicate" } { - # succeeded; use ec_avs_acceptable_p to determine plus_avs or minus_avs + "success" { - if { [ ec_avs_acceptable_p $avs_code ] == 1 } { - set level "authorized_plus_avs" - } else { - set level "authorized_minus_avs" - } - } elseif { $txn_status == "failure-hard" } { - if { [regexp {fails LUHN} $errmsg] } { - # they must have mistyped credit card number - set level "failed_authorization" - } elseif { [regexp {not configured to accept the card type used} $errmsg] } { - # they've used an invalid credit card type - set level "failed_authorization" - } elseif { [regexp {Financial Institution} $errmsg] } { - # authorization declined by financial institution - set level "failed_authorization" - } elseif { [regexp {contains illegal characters} $errmsg] } { - # they mistyped their credit card number (we've taken out - # the spaces and dashes, so they've put in some other - # illegal character) - set level "failed_authorization" - } elseif { [regexp {Invalid credit card number} $errmsg] } { - # This is the error message CyberCash uses to cover up - # its own incompetecy, as explained above. - if { $youth == 1 } { - set level "no_recommendation" - } else { - set level "failed_authorization" - } - } elseif { [regexp {DataBase error} $errmsg] } { - # CyberCash database problem - set level "no_recommendation" - } elseif { [regexp {Could not connect to Merchant Payment Server} $errmsg] } { - # CyberCash communications problem - set level "no_recommendation" - } elseif { [regexp {failed to respond} $errmsg] } { - # CyberCash communications problem - set level "no_recommendation" - } elseif { [regexp {Error while reading message} $errmsg] } { - # yet another CyberCash communications problem - set level "no_recommendation" - } elseif { [regexp -nocase {expiration} $errmsg] } { - # problem with the expiration date (prob. it has passed) - set level "failed_authorization" - } else { - # problem is one that Eve is not familiar with, so the customer is - # given the benefit of the doubt. - set level "no_recommendation" - } - } else { - # The above status codes (success, success-duplicate, failure-hard, - # failure-q-or-cancel, failure-swversion and failure-bad-money) are - # the only ones returned according to the CyberCash development guide. - # If there's a different status code, it will have to be handled - # specially. - set level "no_recommendation" + # The payment gateway authorized the transaction. + + db_dml update_transaction_id " + update ec_financial_transactions + set transaction_id = :pgw_transaction_id + where transaction_id = :transaction_id" + + set outcome(response_code) "authorized" + set outcome(transaction_id) "$pgw_transaction_id" + return [array get outcome] } + + default { + + # Unknown response_code, fail the authorization to be on + # the safe side. + + set outcome(response_code) "failured_authorization" + set outcome(transaction_id) "$transaction_id" + return [array get outcome] + } } - return $level } -ad_proc ec_creditcard_marking { transaction_id } { performs credit card marking +ad_proc -public ec_creditcard_marking { + transaction_id +} { + + Connect to the payment gateway to charge a previously authorized + credit card for a transaction. This marks the transaction for + settlement by the credit card gateway at the end of the day (or + what ever time the gateway uses). + + Returns one of the following strings corresponding to whether or + not the post authorization was successful: + + (a) success The outcome in most cases because there are few + chances for failure + + (b) failure May occure when there is a communications failure + with the payment gateway. Also, most payment gateways will fail + a post authorization if the transaction has already been marked + or if the post authorization amount is higher than the original + authorized amount. Of course, the .tcl script that calls this + proc shouldn't be trying to mark an transaction that's already + been marked and, because the transaction amount is stored in the + database , there should be no discrepancy in the authorized + amount and the post authorization amount. + + (c) invalid_input Occurs if there is no transaction with the + given transaction_id. If case (c) occurs, then there is + probably an error in the .tcl script that called this proc. + + (d) unknown This proc returns "unknown" if cases (a), (b) and + (c) do not apply. And when a temporary error at the payment + gateway failed the post authorization. + } { - # Gets info it needs from database. - # Calls ec_talk_to_cybercash to mark transaction for batching (which in turn - # writes a line to the ec_cybercash_log table). - # Outputs one of the following strings corresponding to whether or - # not the marking was successful: - # (a) success - # (b) failure - # (c) invalid_input - # (d) unknown - # In most instances, case (a) will occur because there are few - # chances for failure; CyberCash is not contacting the processor, - # and the card number has already been determined to be valid. - # Case (b) may occur, for instance, if there is a communications - # failure with CyberCash. Also, CyberCash will fail a postauth - # if the transaction has already been marked or if the postauth amount - # is higher than the original authorized amount. Of course, the - # .tcl script that calls this proc shouldn't be trying to mark an - # transaction that's already been marked and, because the transaction - # amount is stored in the database , there should be no - # discrepancy in the auth amount and the postauth amount. - # Case (c) occurs if there is no transaction with the given transaction_id. - # If case (c) occurs, then there is probably an error in - # the .tcl script that called this proc. - # Case (d) is not expected to occur. This proc outputs "unknown" - # if cases (a), (b) and (c) do not apply. - ns_log Notice "begin ec_creditcard_marking on transaction $transaction_id" + # Lookup the selected currency. - set transaction_amount [db_string transaction_amount_select { - select transaction_amount from ec_financial_transactions where transaction_id = :transaction_id - } -default ""] + set currency [ad_parameter Currency ecommerce] - if { [empty_string_p $transaction_amount] } { - ns_log Notice "Eve debug 1" - set mark_status "invalid_input" - } else { - if {$transaction_amount == 0 } { - ns_log Notice "Eve debug 2" - return "success" - } else { - ns_log Notice "Eve debug 3" - set cc_args [ns_set new] + # Lookup the selected payment gateway - set currency [ad_parameter -package_id [ec_id] Currency ecommerce] + set payment_gateway [ad_parameter PaymentGateway] - ns_set put $cc_args "amount" "$currency $transaction_amount" - ns_set put $cc_args "order-id" "$transaction_id" - - set ttcc_output [ec_talk_to_cybercash "postauth" $cc_args] - - ns_log Notice "Eve debug 4" - # We're only (for the purposes of this proc) interested in - # the txn_status (if you want to see error messages, query - # the cybercash_log). - - set txn_status [ns_set get $ttcc_output "txn_status"] - - if { [regexp {success} $txn_status] } { - set mark_status "success" - } elseif { [regexp {failure} $txn_status] } { - set mark_status "failure" - } else { - set mark_status "unknown" - } - } + # Return an error when no payment gateway has been selected or if + # there is no binding between the selected gateway and the + # PaymentGateway. + + if {[empty_string_p $payment_gateway] || ![acs_sc_binding_exists_p "PaymentGateway" $payment_gateway]} { + set outcome(response_code) "failure" + set outcome(transaction_id) "$transaction_id" + return [array get outcome] } - ns_log Notice "end ec_creditcard_marking on transaction $transaction_id" - return $mark_status -} -ad_proc ec_creditcard_return { transaction_id } { marks order for return } { - # Calls ec_talk_to_cybercash to mark order for return (which in turn - # writes a line to the ec_cybercash_log table). - # Outputs one of the following strings corresponding to whether or - # not the marking was successful: - # (a) success - # (b) failure - # (c) invalid_input - # (d) unknown - # In most instances, case (a) will occur because there are few - # chances for failure; CyberCash is not contacting the processor, - # and the card number has already been determined to be valid. - # Case (b) may occur, for instance, if there is a communications - # failure with CyberCash. Also, CyberCash will fail a return - # if the order has already been marked for return, if the return - # has been settled, or if the return - # amount is higher than the settled amount. Of course, the - # .tcl script that calls this proc shouldn't be trying to mark an - # transaction for return that's has already had a return marked or settled. - # Case (c) occurs if there is no transaction with the given transaction_id, or - # if the transaction_amount column is empty for that transaction - # If case (c) occurs, then there is probably an error in - # the .tcl script that called this proc. - # Case (d) is not expected to occur. This proc outputs "unknown" - # if cases (a), (b) and (c) do not apply. + # Retrieve the transaction amount from the database. NOTE The + # transaction_id needed to charge the card is the transaction ID + # returned by the payment gateway at the time of authorizing the + # transaction. + + db_1row transaction_select " + select f.transaction_amount, f.transaction_id, c.creditcard_type, p.first_names || ' ' || p.last_name as card_name, + c.creditcard_number as card_number, substring(creditcard_expire for 2) as card_exp_month, substring(creditcard_expire from 4 for 2) as card_exp_year, c.creditcard_type, + a.zip_code as billing_zip, + a.line1 as billing_address, + a.city as billing_city, + coalesce(a.usps_abbrev, a.full_state_name) as billing_state, + a.country_code as billing_country + from ec_financial_transactions f, ec_creditcards c, persons p, ec_addresses a + where transaction_id = :transaction_id + and f.creditcard_id = c.creditcard_id + and c.user_id = p.person_id + and c.billing_address = a.address_id" - if { - ![db_0or1row transaction_info_select { - select t.transaction_amount, - c.creditcard_number, - c.creditcard_expire, - c.billing_zip_code - from ec_financial_transactions t, - ec_creditcards c - where t.transaction_id = :transaction_id - and c.creditcard_id = t.creditcard_id - }] - } { + # Fail the post authorization no transaction amount has been retrieved. - set return_status "invalid_input" + if { [empty_string_p $transaction_amount] } { + set outcome(response_code) "invalid_input" + set outcome(transaction_id) "$transaction_id" + return [array get outcome] + } - } else { + # The order amount is 0 (zero) and there is thus no need + # to contact the payment gateway. Record an instant + # success. + if {$transaction_amount == 0 } { + set outcome(response_code) "success" + set outcome(transaction_id) "$transaction_id" + return [array get outcome] + } + + # Convert the one digit creditcard abbreviation to the + # standardized name of the card. + + set card_type [ec_pretty_creditcard_type $creditcard_type] + + # Connect to the payment gateway to authorize the transaction. + + array set response [acs_sc_call "PaymentGateway" "ChargeCard" \ + [list $transaction_id \ + $transaction_amount \ + $card_type \ + $card_number \ + $card_exp_month \ + $card_exp_year \ + $card_name \ + $billing_address \ + $billing_city \ + $billing_state \ + $billing_zip \ + $billing_country] \ + $payment_gateway] + + # Extract response_code, reason and the gateway transaction id + # from the response. The response_code values are defined in + # payment-gateway/tcl/payment-gateway-init.tcl. The reason is a + # human readable description of the response and the + # transaction id is the ID as returned by the payment gateway. + + set response_code $response(response_code) + set reason $response(reason) + set pgw_transaction_id $response(transaction_id) + + # Interpret the response_code. + + switch -exact $response_code { + + "failure" - + default { + + # The payment gateway rejected to post authorize the + # transaction or returned an unknown response_code, fail the + # post authorization to be on the safe side. + + set outcome(response_code) "failure" + set outcome(transaction_id) "$transaction_id" + return [array get outcome] + } + + "failure-retry" - + "not_supported" - + "not_implemented" { + + # If the response_code is failure-retry, it means there was a + # temporary failure that can be retried. The order will be + # retried the next time the scheduled procedure + # ec_sweep_for_payment_zombies is run. Treat not_supported and + # not_implemented responses the same. - if { $transaction_amount == 0 } { - return "success" - } else { + set outcome(response_code) "unknown" + set outcome(transaction_id) "$transaction_id" + return [array get outcome] + } - set cc_args [ns_set new] - - ns_set put $cc_args "amount" "[ad_parameter -package_id [ec_id] Currency ecommerce] $transaction_amount" - ns_set put $cc_args "order-id" "$transaction_id" - ns_set put $cc_args "card-number" "$creditcard_number" - ns_set put $cc_args "card-exp" "$creditcard_expire" - ns_set put $cc_args "card-zip" "$billing_zip_code" + "success" { - set ttcc_output [ec_talk_to_cybercash "return" $cc_args] - - # We're only (for the purposes of this proc) interested in - # the txn_status (if you want to see error messages, query - # the ec_cybercash_log). - - set txn_status [ns_set get $ttcc_output "txn_status"] - - if { [regexp {success} $txn_status] } { - set return_status "success" - } elseif { [regexp {failure} $txn_status] } { - set return_status "failure" - } else { - set return_status "unknown" - } + # The payment gateway approved the transaction. + if { ![empty_string_p $pgw_transaction_id] } { + db_dml update_transaction_id " + update ec_financial_transactions + set transaction_id = :pgw_transaction_id + where transaction_id = :transaction_id" + } + set outcome(response_code) "success" + set outcome(transaction_id) "$pgw_transaction_id" + return [array get outcome] } - return $return_status } } -ad_proc ec_get_from_quasi_form {quasi_form key} "CyberCash sometimes gives us a value back that is itself key/value pairs but in standard HTTP request form (e.g., \"foo=5&bar=7\"). We couldn't find an AOLserver API call that pulls this apart (though obviously the code is there somewhere, presumably in C)." { - if [regexp "$key=(\[^&\]*)" $quasi_form match the_value] { - return $the_value - } else { - return "" - } -} +ad_proc -public ec_creditcard_return { + transaction_id +} { -ad_proc ec_talk_to_cybercash { txn_attempted_type cc_args } "This procedure talks to CyberCash to do whatever transaction is specified, adds a row to the ec_cybercash_log table, and returns all of CyberCash's output in an ns_set" { + Refunds a transaction back to the credit card used for that + transaction. - # Possible values of txn_attempted_type are listed below and - # in the data model (in the ec_cybercash_log table). - # cc_args should be an ns_set containing the key/value - # pairs to be sent to CyberCash, as follows: - # - # txn_attempted_type mandatory keys in cc_args - # ------------------ ------------------------- - # mauthonly amount (containing currency & price), - # order-id, card-number, card-exp, - # [card-zip, card-country and - # card-name are optional] - # postauth amount (currency & price), order-id - # return amount (currency & price), order-id - # void txn-type (value should be marked or - # markret), order-id - # retry order-id, txn-type (value in auth, - # postauth, return, voidmark, voidreturn) - # query order-id, txn-type (value in auth, marked, - # settled, markret, setlret, voidmark, - # voidreturn) - # - # (September 5, 1999, eveander) When performing queries, the - # following sentence is no longer true as of sometime in 1999: - # "Note that this proc assumes we're querying by order-id and - # txn-type which means that only 0 or 1 relevant row will be - # returned." I'm still going to assume that we're querying by - # order-id and txn-type, but due to CyberCash's unannounced and - # undocumented changes in the results of the API call "query", - # any number of rows may be returned and they may or may not - # contain information about the specified transaction type. So - # I've had to fix ec_talk_to_cybercash to make it dig through all - # the irrelevant rows returned when querying. The output of - # ec_talk_to_cybercash will remain the same, so you don't need - # to change any code that uses this procedure. - # - # If you want to query by, say, order-id and txn-status, do not use - # this proc. You'll need to specially handle all the rows of data - # returned by CyberCash. - # - # This proc returns the info that CyberCash returns, except that - # variables are slightly renamed to stick with legal tcl variable - # names and our own naming conventions. + Returns one of the following strings corresponding to whether or + not the marking was successful: - set currency [ad_parameter -package_id [ec_id] Currency ecommerce] + (a) success The outcome in most cases because there are few + chances for failure - if { [ns_set get $cc_args "amount"] != "" } { - # This is to take care of cases where the tax table has output an - # amount that contains a fraction of a cent, which CyberCash - # dislikes - set smart_amount [ns_set get $cc_args "amount"] - regsub -all {[^0-9\.]} $smart_amount "" smart_amount - - ns_set update $cc_args "amount" "$currency [format "%0.2f" $smart_amount]" - } + (b) failure May occure when there is a communications failure + with the payment gateway. Also, most payment gateways will fail + a return if the transaction has already been marked or if the + return amount is higher than the original authorized amount. Of + course, the .tcl script that calls this proc shouldn't be trying + to mark an transaction that's already been marked and, because + the transaction amount is stored in the database , there should + be no discrepancy in the authorized amount and the return + amount. - if { ![ec_use_cybercash_p] } { - # ignore cybercash and assume success on any operation - # This will hold what this proc (ec_talk_to_cybercash) outputs - set ttcc_output [ns_set new] + (c) invalid_input Occurs if there is no transaction with the + given transaction_id. If case (c) occurs, then there is + probably an error in the .tcl script that called this proc. - ns_set put $ttcc_output "txn_status" "success" - ns_set put $ttcc_output "errloc" "" - ns_set put $ttcc_output "errmsg" "" - ns_set put $ttcc_output "merch_txn" "" - ns_set put $ttcc_output "cust_txn" "" - ns_set put $ttcc_output "aux_msg" "" - ns_set put $ttcc_output "auth_code" "" - ns_set put $ttcc_output "action_code" "" - ns_set put $ttcc_output "avs_code" "A" - ns_set put $ttcc_output "ref_code" "" + (d) unknown This proc returns "unknown" if cases (a), (b) and + (c) do not apply. And when a temporary error at the payment + gateway failed the return. - # Figure out what to stick into txn_type - if { $txn_attempted_type == "mauthonly" } { - set txn_type "auth" - } elseif { $txn_attempted_type == "postauth" } { - set txn_type "postauth" - } elseif { $txn_attempted_type == "return" } { - set txn_type "markret" - } elseif { $txn_attempted_type == "void" && [ns_set get $cc_args "txn-type"] == "marked" } { - set txn_type "voidmark" - } elseif { $txn_attempted_type == "void" && [ns_set get $cc_args "txn-type"] == "markret" } { - set txn_type "voidreturn" - } elseif { $txn_attempted_type == "retry" && [ns_set get $cc_args "txn-type"] == "auth" } { - set txn_type "auth" - } elseif { $txn_attempted_type == "retry" && [ns_set get $cc_args "txn-type"] == "postauth" } { - set txn_type "marked" - } elseif { $txn_attempted_type == "retry" && [ns_set get $cc_args "txn-type"] == "return" } { - set txn_type "markret" - } elseif { $txn_attempted_type == "retry" && [ns_set get $cc_args "txn-type"] == "voidmark" } { - set txn_type "voidmark" - } elseif { $txn_attempted_type == "retry" && [ns_set get $cc_args "txn-type"] == "voidreturn" } { - set txn_type "voidreturn" - } else { - set txn_type "unknown" - } +} { - ns_set put $ttcc_output "txn_type" $txn_type - return $ttcc_output + # Lookup the selected currency. + + set currency [ad_parameter Currency ecommerce] + + # Lookup the selected payment gateway + + set payment_gateway [ad_parameter PaymentGateway] + + # Return an error when no payment gateway has been selected or if + # there is no binding between the selected gateway and the + # PaymentGateway. + + if {[empty_string_p $payment_gateway] || ![acs_sc_binding_exists_p "PaymentGateway" $payment_gateway]} { + set outcome(response_code) "failure" + set outcome(transaction_id) "$transaction_id" + return [array get outcome] } - # This will hold what CyberCash outputs - set cc_output [ns_set new] + # Retrieve the transaction amount and the credit card information + # of the card used for the transaction from the database. NOTE The + # transaction_id needed to charge the card is the transaction ID + # returned by the payment gateway at the time of authorizing the + # transaction. - # This will hold what this proc (ec_talk_to_cybercash) outputs - set ttcc_output [ns_set new] + if {![db_0or1row transaction_info_select " + select t.refunded_transaction_id, t.transaction_amount, + c.creditcard_number as card_number, substring(creditcard_expire for 2) as card_exp_month, substring(creditcard_expire from 4 for 2) as card_exp_year, c.creditcard_type, + p.first_names || ' ' || p.last_name as card_name, + a.zip_code as billing_zip, + a.line1 as billing_address, + a.city as billing_city, + coalesce(a.usps_abbrev, a.full_state_name) as billing_state, + a.country_code as billing_country + from ec_financial_transactions t, ec_creditcards c, persons p, ec_addresses a + where t.transaction_id = :transaction_id + and c.creditcard_id = t.creditcard_id + and c.user_id = p.person_id + and c.billing_address = a.address_id"]} { + set outcome(response_code) "invalid_input" + set outcome(transaction_id) "$transaction_id" + return [array get outcome] + } - cc_send_to_server_21 "$txn_attempted_type" $cc_args $cc_output + # The order amount is 0 (zero) and there is thus no need + # to contact the payment gateway. Record an instant + # success. - # For non-queries, just grab the info in $cc_output and put - # it into $ttcc_output with the keys renamed (and also stick in - # txn_type, which isn't returned in non-queries; we want to - # insert the txn_type that *would* have been returned if it had - # been a query, for consistency). Note that some (many) of - # the values will be the empty string because no single - # transaction returns values for every key. + if { $transaction_amount == 0 } { + set outcome(response_code) "success" + set outcome(transaction_id) "$transaction_id" + return [array get outcome] + } - if { $txn_attempted_type != "query" } { - ns_set put $ttcc_output "txn_status" "[ns_set get $cc_output "MStatus"]" - ns_set put $ttcc_output "errloc" "[ns_set get $cc_output "MErrLoc"]" - ns_set put $ttcc_output "errmsg" "[ns_set get $cc_output "MErrMsg"]" - ns_set put $ttcc_output "merch_txn" "[ns_set get $cc_output "merch-txn"]" - ns_set put $ttcc_output "cust_txn" "[ns_set get $cc_output "cust-txn"]" - ns_set put $ttcc_output "aux_msg" "[ns_set get $cc_output "aux-msg"]" - ns_set put $ttcc_output "auth_code" "[ns_set get $cc_output "auth-code"]" - ns_set put $ttcc_output "action_code" "[ns_set get $cc_output "action-code"]" - ns_set put $ttcc_output "avs_code" "[ns_set get $cc_output "avs-code"]" - ns_set put $ttcc_output "ref_code" "[ns_set get $cc_output "ref-code"]" + # Convert the one digit creditcard abbreviation to the + # standardized name of the card. - # Figure out what to stick into txn_type - if { $txn_attempted_type == "mauthonly" } { - set txn_type "auth" - } elseif { $txn_attempted_type == "postauth" } { - set txn_type "postauth" - } elseif { $txn_attempted_type == "return" } { - set txn_type "markret" - } elseif { $txn_attempted_type == "void" && [ns_set get $cc_args "txn-type"] == "marked" } { - set txn_type "voidmark" - } elseif { $txn_attempted_type == "void" && [ns_set get $cc_args "txn-type"] == "markret" } { - set txn_type "voidreturn" - } elseif { $txn_attempted_type == "retry" && [ns_set get $cc_args "txn-type"] == "auth" } { - set txn_type "auth" - } elseif { $txn_attempted_type == "retry" && [ns_set get $cc_args "txn-type"] == "postauth" } { - set txn_type "marked" - } elseif { $txn_attempted_type == "retry" && [ns_set get $cc_args "txn-type"] == "return" } { - set txn_type "markret" - } elseif { $txn_attempted_type == "retry" && [ns_set get $cc_args "txn-type"] == "voidmark" } { - set txn_type "voidmark" - } elseif { $txn_attempted_type == "retry" && [ns_set get $cc_args "txn-type"] == "voidreturn" } { - set txn_type "voidreturn" - } else { - set txn_type "unknown" - } + set card_type [ec_pretty_creditcard_type $creditcard_type] - ns_set put $ttcc_output "txn_type" $txn_type - - } elseif { $txn_attempted_type == "query" } { + # Connect to the payment gateway to authorize the transaction. - set cc_output_size [ns_set size $cc_output] + array set response [acs_sc_call "PaymentGateway" "Return" \ + [list $refunded_transaction_id \ + $transaction_amount \ + $card_type \ + $card_number \ + $card_exp_month \ + $card_exp_year \ + $card_name \ + $billing_address \ + $billing_city \ + $billing_state \ + $billing_zip \ + $billing_country] \ + $payment_gateway] - set relevant_cc_data "" - - for {set i 0} {$i < $cc_output_size} {incr i} { - set one_row_of_cc_data [ns_set value $cc_output $i] - set cc_txn_type [ec_get_from_quasi_form $one_row_of_cc_data txn-type] - if { $cc_txn_type == [ns_set get $cc_args "txn-type"] } { - set relevant_cc_data $one_row_of_cc_data - } - } + # Extract response_code, reason and the gateway transaction id + # from the response. The response_code values are defined in + # payment-gateway/tcl/payment-gateway-init.tcl. The reason is a + # human readable description of the response and the + # transaction id is the ID as returned by the payment gateway. - if {![empty_string_p $relevant_cc_data]} { - # If it's a query, we have to do some regexping because - # ns_sets of non-ns_set key/value pairs are returned. - # It's the 2nd value of $cc_output that's of interest - # (no longer true as of September 5, 1999; see comment - # at top of this procedure; so we've set relevant_cc_data - # above). - # Note that the cc_time returned isn't a date as far - # as Oracle is concerned (it's a string, so you'll have - # to do a to_date('$cc_time','YYYYMMDDHH24MISS') when inserting). - - ns_set put $ttcc_output "txn_type" [ec_get_from_quasi_form $relevant_cc_data txn-type] - ns_set put $ttcc_output "cust_txn" [ec_get_from_quasi_form $relevant_cc_data cust-txn] - ns_set put $ttcc_output "merch_txn" [ec_get_from_quasi_form $relevant_cc_data merch-txn] - ns_set put $ttcc_output "origin" [ec_get_from_quasi_form $relevant_cc_data origin] - ns_set put $ttcc_output "txn_status" [ec_get_from_quasi_form $relevant_cc_data txn-status] - # we have to handle date specially so as not to confuse Oracle with - # subsecond precision - regexp {time=([^.]*)\.} $relevant_cc_data garbage ugly_date - if { ![info exists ugly_date] } { - set ugly_date "" - } - ns_set put $ttcc_output "cc_time" $ugly_date - ns_set put $ttcc_output "auth_code" [ec_get_from_quasi_form $relevant_cc_data auth-code] - ns_set put $ttcc_output "action_code" [ec_get_from_quasi_form $relevant_cc_data action-code] - ns_set put $ttcc_output "avs_code" [ec_get_from_quasi_form $relevant_cc_data avs-code] - ns_set put $ttcc_output "ref_code" [ec_get_from_quasi_form $relevant_cc_data ref-code] - ns_set put $ttcc_output "batch_id" [ec_get_from_quasi_form $relevant_cc_data batch-id] - set long_amount [ec_get_from_quasi_form $relevant_cc_data amount] - regsub -all {[^0-9\.]} $long_amount "" numeric_amount - # regexp {^[ad_parameter -package_id [ec_id] Currency ecommerce] (.*)} $long_amount garbage numeric_amount - if { [info exists numeric_amount] } { - ns_set put $ttcc_output "amount" $numeric_amount - } else { - ns_set put $ttcc_output "amount" "" - } + set response_code $response(response_code) + set reason $response(reason) + set pgw_transaction_id $response(transaction_id) + + # Interpret the response_code. + + switch -exact $response_code { + + "failure" - + default { + + # The payment gateway rejected to refund the transaction or + # returned an unknown response_code. Fail the post + # authorization to be on the safe side. + + db_dml transaction_failure_update " + update ec_financial_transactions + set failed_p = 't' + where transaction_id = :transaction_id" + + set outcome(response_code) "failure" + set outcome(transaction_id) "$transaction_id" + return [array get outcome] } + + "failure-retry" - + "not_supported" - + "not_implemented" { - } - - # Add a row to cybercash_log + # If the response_code is failure-retry, it means there was a + # temporary failure that can be retried. The order will be + # retried the next time the scheduled procedure + # ec_sweep_for_payment_zombies is run. Treat not_supported and + # not_implemented responses the same. + + set outcome(response_code) "unknown" + set outcome(transaction_id) "$transaction_id" + return [array get outcome] + } - set bind_vars [ad_tcl_list_list_to_ns_set [list \ - [list transaction_id [ns_set get $cc_args "order-id"]] \ - [list txn_attempted_type $txn_attempted_type] \ - [list txn_type [ns_set get $ttcc_output "txn_type"]] \ - [list cc_time [ns_set get $ttcc_output "cc_time"]] \ - [list merch_txn [ns_set get $ttcc_output "merch_txn"]] \ - [list cust_txn [ns_set get $ttcc_output "cust_txn"]] \ - [list origin [ns_set get $ttcc_output "origin"]] \ - [list txn_status [ns_set get $ttcc_output "txn_status"]] \ - [list errloc [ns_set get $ttcc_output "errloc"]] \ - [list errmsg [ns_set get $ttcc_output "errmsg"]] \ - [list aux_msg [ns_set get $ttcc_output "aux_msg"]] \ - [list auth_code [ns_set get $ttcc_output "auth_code"]] \ - [list action_code [ns_set get $ttcc_output "action_code"]] \ - [list avs_code [ns_set get $ttcc_output "avs_code"]] \ - [list ref_code [ns_set get $ttcc_output "ref_code"]] \ - [list batch_id [ns_set get $ttcc_output "batch_id"]] \ - [list amount [ns_set get $ttcc_output "amount"]]]] + "success" { - db_dml cybercash_log_insert " - insert into ec_cybercash_log ([join [ad_ns_set_keys -exclude "cc_time" $bind_vars] ", "], cc_time, txn_attempted_time) - values ([join [ad_ns_set_keys -exclude "cc_time" -colon $bind_vars] ", "], to_date(:cc_time, 'YYYYMMDDHH24MISS'), sysdate) - " -bind $bind_vars + # The payment gateway authorized the transaction. - # Finally, return the ns_set - return $ttcc_output -} + db_dml transaction_success_update " + update ec_financial_transactions + set transaction_id = :pgw_transaction_id, refunded_date = sysdate + where transaction_id = :transaction_id" -ad_proc ec_avs_acceptable_p {avs_code_from_cybercash} "Returns 1 if the AVS code is acceptable (implying that the consumer address sufficiently matches the creditor's records), or 0 otherwise" { - set acceptable_codes [list A W X Y Z] - if { [lsearch $acceptable_codes $avs_code_from_cybercash] != -1 } { - # code was valid - return 1 - } else { - return 0 + set outcome(response_code) "success" + set outcome(transaction_id) "$pgw_transaction_id" + return [array get outcome] + } } } -ad_proc ec_date_to_cybercash_date_for_query { the_date n_hours_to_add } "turns date in the format YYYY-MM-DD HH24:MI:SS into CyberCash's format yyyymmddhhmmss with n_hours_to_add hours added because CyberCash uses GMT" { - return [db_string cybercash_date_create { - select to_char(:n_hours_to_add / 24 + to_date(:the_date, 'YYYY-MM-DD HH24:MI:SS'), 'YYYYMMDDHH24MISS') from dual - }] -} +ad_proc -public ec_creditcard_precheck { + creditcard_number + creditcard_type +} { -# If you're going to accept cards other than MasterCard, Visa, or -# American Express, you'll have to modify this proc to recognize -# them. It should be easy; just look at the proc ec_creditcard_validation -# (below) to see how different card numbers are formed. -# This script does some basic checks on the credit card and -# returns a list containing exception_count, exception_text. -# The creditcard_number shouldn't contain any special characters; -# numbers only. -# The check to see whether the creditcard_number or creditcard_type -# is the empty string should be done separately. -# m=mastercard, v=visa, a=american express + Prechecks credit card numbers. If you're going to accept cards + other than MasterCard, Visa, or American Express, you'll have to + modify this proc to recognize them. It should be easy; just + look at the proc ec_creditcard_validation to see how different + card numbers are formed. -# ec_check_creditcard_type_number_match -ad_proc ec_creditcard_precheck { creditcard_number creditcard_type } { prechecks credit card numbers } { + This script does some basic checks on the credit card and + returns a list containing exception_count, exception_text. + The creditcard_number shouldn't contain any special characters; + numbers only. The check to see whether the creditcard_number or + creditcard_type is the empty string should be done separately. + + m = mastercard, + v = visa, + a = american express + +} { + set exception_count 0 set exception_text "" - if {[string index $creditcard_number 0] == 5} { - if {[info exists creditcard_type] && ![empty_string_p $creditcard_type] && [string compare $creditcard_type "m"] != 0 } { - incr exception_count - append exception_text "

  • Either your credit card type or your credit card number is incorrect (they don't match)." + if {![empty_string_p $creditcard_type]} { + switch -exact $creditcard_type { + + "m" { + if {[string index $creditcard_number 0] != 5} { + incr exception_count + append exception_text "
  • The credit card number is not a MasterCard number.
  • " + } + if {[string length $creditcard_number] != 16} { + incr exception_count + append exception_text "
  • The credit card number does not have the right number of digits.
  • " + } + } + + "v" { + if {[string index $creditcard_number 0] != 4} { + incr exception_count + append exception_text "
  • The credit card number is not a VISA number.
  • " + } + if {[string length $creditcard_number] != 16 && [string length $creditcard_number] != 13} { + incr exception_count + append exception_text "
  • The credit card number does not have the right number of digits.
  • " + } + } + + "a" { + if {[string index $creditcard_number 0] != 3} { + incr exception_count + append exception_text "
  • The credit card number is not an American Express number.
  • " + } + if {[string length $creditcard_number] != 15} { + incr exception_count + append exception_text "
  • The credit card number does not have the right number of digits.
  • " + } + } + + default { + incr exception_count + append exception_text "
  • Sorry, the credit card type is of an unknown type: [ec_pretty_creditcard_type $creditcard_type].
  • " + } } - if { [string length $creditcard_number] != 16 } { - incr exception_count - append exception_text "
  • Your credit card number doesn't have the right number of digits." - } - } elseif {[string index $creditcard_number 0] == 4} { - if {[info exists creditcard_type] && ![empty_string_p $creditcard_type] && [string compare $creditcard_type "v"] != 0 } { - incr exception_count - append exception_text "
  • Either your credit card type or your credit card number is incorrect (they don't match)." - } - if { [string length $creditcard_number] != 16 } { - incr exception_count - append exception_text "
  • Your credit card number doesn't have the right number of digits." - } - } elseif {[string index $creditcard_number 0] == 3} { - if {[info exists creditcard_type] && ![empty_string_p $creditcard_type] && [string compare $creditcard_type "a"] != 0 } { - incr exception_count - append exception_text "
  • Either your credit card type or your credit card number is incorrect (they don't match)." - } - if { [string length $creditcard_number] != 15 } { - incr exception_count - append exception_text "
  • Your credit card number doesn't have the right number of digits." - } - } else { - if {[info exists creditcard_type] && ![empty_string_p $creditcard_type]} { - incr exception_count - append exception_text "
  • Sorry, the credit card number you input is not a Mastercard, Visa, or American Express card number." - } } - # only if there haven't been any problems so far should we do LUHN-10 error - # checking which the customer is less likely to understand + # Only if there haven't been any problems so far should we do + # LUHN-10 error checking which the customer is less likely to + # understand + if { $exception_count == 0 } { - set vallas_creditcard_type [ec_decode [ec_creditcard_validation $creditcard_number] "MasterCard" "m" "VISA" "v" "American Express" "a" "other"] - if { $vallas_creditcard_type != $creditcard_type } { + set decoded_creditcard_type [ec_creditcard_validation $creditcard_number] + set vallas_creditcard_type [ec_pretty_creditcard_type $creditcard_type] + + if {$decoded_creditcard_type == "unknown" } { incr exception_count - append exception_text "
  • There's something wrong with the credit card number you entered. Please check whether you have any transposed digits, missing digits, or similar errors." + append exception_text " +
  • + The credit card number is of an unknown credit card type while the card is a(n) [ec_pretty_creditcard_type $creditcard_type] credit card. +
  • " + } else { + if { $vallas_creditcard_type != $vallas_creditcard_type } { + incr exception_count + append exception_text " +
  • + The credit card number is a(n) $decoded_creditcard_type number while the card is a(n) [ec_pretty_creditcard_type $creditcard_type] credit card. +
  • " + } } } return [list $exception_count $exception_text] } -# This procedure, originally called valCC, by Horace Vallas was -# found at http://www.hav.com/valCC/nph-src.htm?valCC.nws -# (with an HTML demo at https://enterprise.neosoft.com/secureforms/hav/default.htm). -# It has been left unchanged except for the name. -- eveander@arsdigita.com - -# H.V.'s comments: +ad_proc -private ec_creditcard_validation { + numIn +} { -# This is a demo NeoWebScript by Horace Vallas - 3-7-97 according to some info -# I found on the web that was attibuted to ICVERIFY by Hal Stiles hstiles@beachnet.com -# http://www.beachnet.com/~hstiles/cardtype.html -# -# You are welcome to use it; however, I make no warranty whatsoever about the -# accuracy or usefullness of this script. By using this script, you are agreeing that -# I am not responsible for any damage, of any kind whatsoever, to you or to any of -# your customers, clients, partners, friends, relatives, children born or unborne, -# pets, invisible friends, etc. etc. etc. -#=============================================================== + This procedure validates a credit card number. It was originally + called valCC, and was written by Horace Vallas. The original was + found at http://www.hav.com/valCC/nph-src.htm?valCC.nws (with an + HTML demo at + https://enterprise.neosoft.com/secureforms/hav/default.htm). It + has been left unchanged except for the name. + eveander@arsdigita.com + + H.V.'s comments: -# The valCC proc can be used to validate a credit card number as -# being legally formed. -# -# input is the entered card number -# return is the type of card (if validated) -# or "- unknown-" if it is an unknown or invalid number -# -# The validation applied (last known date 3/96) is the so called -# LUHN Formula (Mod 10) for Validation of Primary Account Number -# Validation criteria are: -# -# 1. number prefix -# 2. number of digits -# 3. mod10 (for all but enRoute which uses only 1 & 2) -# -# ... according to the following list of criteria requirements: -# -# Card Type Prefix Length Check-Digit Algoritm -# -# MC 51 - 55 16 mod 10 -# -# VISA 4 13, 16 mod 10 -# -# AMX 34, 37 15 mod 10 -# -# Diners Club / 300 - 305, 36, 38 14 mod 10 -# Carte Blanche -# -# Discover 6011 16 mod 10 -# -# enRoute 2014, 2149 16 - any - -# -# JCB 3 16 mod 10 -# JCB 2131, 1800 15 mod 10 -# + This is a demo NeoWebScript by Horace Vallas (3-7-97) according + to some info I found on the web that was attibuted to ICVERIFY + by Hal Stiles hstiles@beachnet.com + http://www.beachnet.com/~hstiles/cardtype.html. You are welcome + to use it; however, I make no warranty whatsoever about the + accuracy or usefullness of this script. By using this script, + you are agreeing that I am not responsible for any damage, of + any kind whatsoever, to you or to any of your customers, + clients, partners, friends, relatives, children born or unborne, + pets, invisible friends, etc. etc. etc. -# Original name: valCC -ad_proc ec_creditcard_validation {numIn} { validates credit card number } { + The valCC proc can be used to validate a credit card number as + being legally formed. + + Input is the entered card number. + + Return is the type of card (if validated) or "- unknown-" if it + is an unknown or invalid number + + The validation applied (last known date 3/96) is the so called + LUHN Formula (Mod 10) for Validation of Primary Account Number. + + Validation criteria are: + 1. number prefix + 2. number of digits + 3. mod10 (for all but enRoute which uses only 1 & 2) + + Each card type has the following criteria requirements: + + Card Type Prefix Length Check-Digit Algoritm + + MC 51 - 55 16 mod 10 + + VISA 4 13, 16 mod 10 + + AMX 34, 37 15 mod 10 + + Diners Club / 300 - 305, 36, 38 14 mod 10 + Carte Blanche + + Discover 6011 16 mod 10 + + enRoute 2014, 2149 16 - any - + + JCB 3 16 mod 10 + JCB 2131, 1800 15 mod 10 + +} { + + # Remove all spaces from the credit card number. + regsub -all { } $numIn {} entered_number - set num [split $entered_number {}] ; # a list form of the number - set numLen [llength $num] ; # the number of digits in the entered number + + # Convert the credit card number to list of the digits in the + # number. + + set num [split $entered_number {}] + + # Get the number of digits in the credit card number. + + set numLen [llength $num] + + # Set the default card type to unknown. + set type "-unknown-" - # first determine the type of card: MC, VISA, AMX, etc. - # i.e. test prefix and then number of digits + # First determine the type of card: MC, VISA, AMX, etc. by testing + # the first 4 digits of the credit card number and then the total + # number of digits of the credit number. switch -glob [string range $entered_number 0 3] { - "51??" - "52??" - "53??" - "54??" - "55??" - {if {$numLen == 16} {set type "MasterCard"}} - "4???" - {if {$numLen == 13 || $numLen == 16} {set type "VISA"}} - "34??" - "37??" - {if {$numLen == 15} {set type "American Express"}} - "300?" - "301?" - "302?" - "303?" - "304?" - "305?" - "36??" - "38??" - {if {$numLen == 14} {set type "Diner's Club / Carte Blanche"}} - "6011" - {if {$numLen == 16} {set type "Discover"}} - "2014" - "2149" - {if {$numLen == 15} {set type "enRoute"}; return $type ; # early exit for enRoute} - "3???" - {if {$numLen == 16} {set type "JCB"}} - "2131" - "1800" - {if {$numLen == 15} {set type "JCB"}} - default - {set type "-unknown-"} + "51??" - + "52??" - + "53??" - + "54??" - + "55??" { + if {$numLen == 16} { + set type "MasterCard" + } + } + + "4???" { + if {$numLen == 13 || $numLen == 16} { + set type "VISA" + } + } + + "34??" - + "37??" { + if {$numLen == 15} { + set type "American Express" + } + } + + "300?" - + "301?" - + "302?" - + "303?" - + "304?" - + "305?" - + "36??" - + "38??" { + if {$numLen == 14} { + set type "Diners Club" + } + } + + "6011" { + if {$numLen == 16} { + set type "Discover/Novus" + } + } + + "2014" - + "2149" { + if {$numLen == 15} { + set type "enRoute" + } + + # early exit for enRoute + + return $type + } + + "3???" { + if {$numLen == 16} { + set type "JCB" + } + } + + "2131" - + "1800" { + if {$numLen == 15} { + set type "JCB" + } + } + + default { + set type "-unknown-" + } } + + # Early exit if card type is unknown. + if {$type == "-unknown-"} { - return $type} ; #early exit if we already know it is bad + return $type + } - # if prefix and number of digits are ok, - # then apply the mod10 check + # If prefix and number of digits are ok, then apply the mod10 + # check. Initialize the running sum - set sum 0 ; # initialize the running sum + set sum 0 - # sum every digit starting with the RIGHT-MOST digit - # on alternate digits (starting with the NEXT-TO-THE-RIGHT-MOST digit) - # sum all digits in the result of TWO TIMES the alternate digit - # RATHER than the original digit itself + # Sum every digit starting with the RIGHT-MOST digit on alternate + # digits (starting with the NEXT-TO-THE-RIGHT-MOST digit). Then + # sum all digits in the result of TWO TIMES the alternate digit + # RATHER than the original digit itself. Catch this summing loop + # in case there are non-digit values in the credit card number. - if {[catch { ; # CATCH this summing loop in case there are non-digit values in the user supplied string - for {set i [expr $numLen - 1]} {$i >= 0} {} { - incr sum [lindex $num $i] - if {[incr i -1] >= 0} { - foreach adigit [split [expr 2 * [lindex $num $i]] {}] {incr sum $adigit} - incr i -1 - } - } - }] != 0} { + if {[catch { + for {set i [expr $numLen - 1]} {$i >= 0} {} { + incr sum [lindex $num $i] + if {[incr i -1] >= 0} { + foreach adigit [split [expr 2 * [lindex $num $i]] {}] { + incr sum $adigit + } + incr i -1 + } + } }] != 0} { return "-unknown-" } - # emulate a mod 10 (base 10) on the calculated number. - # if there is any remainder, then the number IS NOT VALID - # so reset type to -unknown- + # Emulate a mod 10 (base 10) on the calculated number. If there is + # any remainder, then the number IS NOT VALID so reset type to + # -unknown- - set lsum [split $sum {}] - if {[lindex $lsum [expr [llength $lsum] - 1]]} {set type "-unknown-"} + set lsum [split $sum {}] + if {[lindex $lsum [expr [llength $lsum] - 1]]} { + set type "-unknown-" + } return $type } Index: openacs-4/packages/ecommerce/tcl/ecommerce-credit-procs.xql =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/ecommerce/tcl/ecommerce-credit-procs.xql,v diff -u -r1.1 -r1.2 --- openacs-4/packages/ecommerce/tcl/ecommerce-credit-procs.xql 10 Jul 2001 20:38:43 -0000 1.1 +++ openacs-4/packages/ecommerce/tcl/ecommerce-credit-procs.xql 26 May 2002 04:36:49 -0000 1.2 @@ -1,50 +1,96 @@ + - - - - select creditcard_number, creditcard_expire, - billing_zip_code - from ec_creditcards - where creditcard_id = :creditcard_id - - - + + + select ec_order_cost(:order_id) as total_amount, creditcard_id + from ec_orders + where order_id = :order_id + + + + + + select transaction_amount as total_amount, creditcard_id + from ec_financial_transactions + where transaction_id = :transaction_id + + - - - - - select max(transaction_id) from ec_financial_transactions where order_id = :order_id - - - + + + select c.creditcard_number as card_number, substring(creditcard_expire for 2) as card_exp_month, substring(creditcard_expire from 4 for 2) as card_exp_year, + c.creditcard_type, p.first_names || ' ' || p.last_name as card_name, + a.zip_code as billing_zip, + a.line1 as billing_address, + a.city as billing_city, + coalesce(a.usps_abbrev, a.full_state_name) as billing_state, + a.country_code as billing_country + from ec_creditcards c, persons p, ec_addresses a + where c.user_id=p.person_id + and c.creditcard_id = :creditcard_id + and c.billing_address = a.address_id + + + + + + update ec_financial_transactions + set transaction_id = :pgw_transaction_id + where transaction_id = :transaction_id + + - - - - - select transaction_amount from ec_financial_transactions where transaction_id = :transaction_id - - - + + + select f.transaction_amount, f.transaction_id, c.creditcard_type, p.first_names || ' ' || p.last_name as card_name, + c.creditcard_number as card_number, substring(creditcard_expire for 2) as card_exp_month, substring(creditcard_expire from 4 for 2) as card_exp_year, c.creditcard_type, + a.zip_code as billing_zip, + a.line1 as billing_address, + a.city as billing_city, + coalesce(a.usps_abbrev, a.full_state_name) as billing_state, + a.country_code as billing_country + from ec_financial_transactions f, ec_creditcards c, persons p, ec_addresses a + where transaction_id = :transaction_id + and f.creditcard_id = c.creditcard_id + and c.user_id = p.person_id + and c.billing_address = a.address_id + + - - - - - select t.transaction_amount, - c.creditcard_number, - c.creditcard_expire, - c.billing_zip_code - from ec_financial_transactions t, - ec_creditcards c - where t.transaction_id = :transaction_id - and c.creditcard_id = t.creditcard_id - - - + + + update ec_financial_transactions + set transaction_id = :pgw_transaction_id + where transaction_id = :transaction_id + + - + + + select t.refunded_transaction_id, t.transaction_amount, + c.creditcard_number as card_number, substring(creditcard_expire for 2) as card_exp_month, substring(creditcard_expire from 4 for 2) as card_exp_year, c.creditcard_type, + p.first_names || ' ' || p.last_name as card_name, + a.zip_code as billing_zip, + a.line1 as billing_address, + a.city as billing_city, + coalesce(a.usps_abbrev, a.full_state_name) as billing_state, + a.country_code as billing_country + from ec_financial_transactions t, ec_creditcards c, persons p, ec_addresses a + where t.transaction_id = :transaction_id + and c.creditcard_id = t.creditcard_id + and c.user_id = p.person_id + and c.billing_address = a.address_id + + + + + + update ec_financial_transactions + set failed_p = 't' + where transaction_id = :transaction_id + + + Index: openacs-4/packages/ecommerce/tcl/ecommerce-customer-service-procs-oracle.xql =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/ecommerce/tcl/ecommerce-customer-service-procs-oracle.xql,v diff -u -r1.2 -r1.3 --- openacs-4/packages/ecommerce/tcl/ecommerce-customer-service-procs-oracle.xql 22 Jul 2001 06:13:37 -0000 1.2 +++ openacs-4/packages/ecommerce/tcl/ecommerce-customer-service-procs-oracle.xql 26 May 2002 04:36:49 -0000 1.3 @@ -1,37 +1,33 @@ - oracle8.1.6 + + oracle + 8.1.6 + - - + + select ec_issue_id_sequence.NEXTVAL from dual - - + + + + + + insert into ec_customer_serv_interactions + (interaction_id, customer_service_rep, user_identification_id, interaction_date, interaction_originator, interaction_type, interaction_headers) + values + (:interaction_id, :customer_service_rep, :user_identification_id, sysdate, :interaction_originator, :interaction_type, :interaction_headers) + + + + + + insert into ec_customer_service_issues + (issue_id, user_identification_id, order_id, open_date, close_date, closed_by, gift_certificate_id) + values + (:issue_id, :user_identification_id, :order_id, sysdate, sysdate, :customer_service_rep, :gift_certificate_id) + + - - - - - insert into ec_customer_serv_interactions - (interaction_id, customer_service_rep, user_identification_id, interaction_date, interaction_originator, interaction_type, interaction_headers) - values - (:interaction_id, :customer_service_rep, :user_identification_id, sysdate, :interaction_originator, :interaction_type, :interaction_headers) - - - - - - - - - insert into ec_customer_service_issues - (issue_id, user_identification_id, order_id, open_date, close_date, closed_by, gift_certificate_id) - values - (:issue_id, :user_identification_id, :order_id, sysdate, sysdate, :customer_service_rep, :gift_certificate_id) - - - - - Index: openacs-4/packages/ecommerce/tcl/ecommerce-customer-service-procs-postgresql.xql =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/ecommerce/tcl/ecommerce-customer-service-procs-postgresql.xql,v diff -u -r1.2 -r1.3 --- openacs-4/packages/ecommerce/tcl/ecommerce-customer-service-procs-postgresql.xql 22 Jul 2001 06:13:37 -0000 1.2 +++ openacs-4/packages/ecommerce/tcl/ecommerce-customer-service-procs-postgresql.xql 26 May 2002 04:36:49 -0000 1.3 @@ -1,37 +1,33 @@ - postgresql7.1 + + postgresql + 7.1 + - - - select ec_issue_id_sequence.NEXTVAL - - - - - - - - insert into ec_customer_serv_interactions - (interaction_id, customer_service_rep, user_identification_id, interaction_date, interaction_originator, interaction_type, interaction_headers) - values - (:interaction_id, :customer_service_rep, :user_identification_id, current_timestamp, :interaction_originator, :interaction_type, :interaction_headers) - - - - - - - - - insert into ec_customer_service_issues - (issue_id, user_identification_id, order_id, open_date, close_date, closed_by, gift_certificate_id) - values - (:issue_id, :user_identification_id, :order_id, current_timestamp, current_timestamp, :customer_service_rep, :gift_certificate_id) - - - - - + + + select ec_issue_id_sequence.nextval + + + + + + insert into ec_customer_serv_interactions + (interaction_id, customer_service_rep, user_identification_id, interaction_date, interaction_originator, interaction_type, interaction_headers) + values + (:interaction_id, :customer_service_rep, :user_identification_id, current_timestamp, :interaction_originator, :interaction_type, :interaction_headers) + + + + + + insert into ec_customer_service_issues + (issue_id, user_identification_id, order_id, open_date, close_date, closed_by, gift_certificate_id) + values + (:issue_id, :user_identification_id, :order_id, current_timestamp, current_timestamp, :customer_service_rep, :gift_certificate_id) + + + Index: openacs-4/packages/ecommerce/tcl/ecommerce-customer-service-procs.xql =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/ecommerce/tcl/ecommerce-customer-service-procs.xql,v diff -u -r1.2 -r1.3 --- openacs-4/packages/ecommerce/tcl/ecommerce-customer-service-procs.xql 22 Jul 2001 06:13:37 -0000 1.2 +++ openacs-4/packages/ecommerce/tcl/ecommerce-customer-service-procs.xql 26 May 2002 04:36:49 -0000 1.3 @@ -1,49 +1,38 @@ + - - - - select user_identification_id from ec_user_identification where user_id = :user_id - - - + + + select user_identification_id from ec_user_identification where user_id = :user_id + + - - - - - insert into ec_user_identification - (user_identification_id, user_id) - values - (:user_identification_id, :user_id) - - - + + + insert into ec_user_identification + (user_identification_id, user_id) + values + (:user_identification_id, :user_id) + + - - - - - insert into ec_cs_issue_type_map - (issue_id, issue_type) - values - (:issue_id, :issue_type) - - - + + + insert into ec_cs_issue_type_map + (issue_id, issue_type) + values + (:issue_id, :issue_type) + + - - - - + + insert into ec_customer_service_actions (action_id, issue_id, interaction_id, action_details) values (:action_id, :issue_id, :interaction_id, :action_details) - - - - - + + + Index: openacs-4/packages/ecommerce/tcl/ecommerce-email-procs-oracle.xql =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/ecommerce/tcl/ecommerce-email-procs-oracle.xql,v diff -u -r1.4 -r1.5 --- openacs-4/packages/ecommerce/tcl/ecommerce-email-procs-oracle.xql 31 Jan 2002 06:50:10 -0000 1.4 +++ openacs-4/packages/ecommerce/tcl/ecommerce-email-procs-oracle.xql 26 May 2002 04:36:49 -0000 1.5 @@ -1,7 +1,10 @@ - oracle8.1.6 + + oracle + 8.1.6 + Index: openacs-4/packages/ecommerce/tcl/ecommerce-email-procs-postgresql.xql =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/ecommerce/tcl/ecommerce-email-procs-postgresql.xql,v diff -u -r1.4 -r1.5 --- openacs-4/packages/ecommerce/tcl/ecommerce-email-procs-postgresql.xql 31 Jan 2002 06:50:10 -0000 1.4 +++ openacs-4/packages/ecommerce/tcl/ecommerce-email-procs-postgresql.xql 26 May 2002 04:36:49 -0000 1.5 @@ -1,7 +1,10 @@ - postgresql7.1 + + postgresql + 7.1 + Index: openacs-4/packages/ecommerce/tcl/ecommerce-email-procs.tcl =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/ecommerce/tcl/ecommerce-email-procs.tcl,v diff -u -r1.5 -r1.6 --- openacs-4/packages/ecommerce/tcl/ecommerce-email-procs.tcl 9 Mar 2002 02:00:02 -0000 1.5 +++ openacs-4/packages/ecommerce/tcl/ecommerce-email-procs.tcl 26 May 2002 04:36:49 -0000 1.6 @@ -1,16 +1,35 @@ -# /tcl/ecommerce-email.tcl ad_library { - Email procedures for the ecommerce module - Started April, 1999 by Eve Andersson (eveander@arsdigita.com) - Other ecommerce procedures can be found in ecommerce-*.tcl - @author Eve Andersson (eveander@arsdigita.com) - @creation-date Summer 1999 - @cvs-id ecommerce-email.tcl,v 3.4.2.7 2000/08/17 17:37:15 seb Exp - @author ported by Jerry Asher (jerry-ecommerce@hollyjerry.org) + Email procedures for the ecommerce module + Started April, 1999 by Eve Andersson (eveander@arsdigita.com) + Other ecommerce procedures can be found in ecommerce-*.tcl + + @author Eve Andersson (eveander@arsdigita.com) + @creation-date Summer 1999 + @author ported by Jerry Asher (jerry-ecommerce@hollyjerry.org) + @author revised by Bart Teeuwisse + @revision-date April 2002 } -ad_proc ec_sendmail_from_service { email_to reply_to email_subject email_body {additional_headers ""} {bcc ""} } "Use this when you're sending out customer service emails. It's invoked just like ns_sendmail, except that the email will always be from the customer service email address. The reply-to field can be used for the perl/qmail service-345-9848@whatever.com email trick (but it doesn't have to be).

    Note: one major difference from ns_sendmail: with ns_sendmail, putting a Cc header does not actually send an extra copy of the email; it just puts Cc: whomever@wherever into the header (and then you'd have to specify whomever@wherever in the bcc argument). This procedure does send the email to the Cc'd email addresses." { +ad_proc ec_sendmail_from_service { + email_to + reply_to + email_subject + email_body + {additional_headers ""} + {bcc ""} +} { + Use this when you're sending out customer service emails. It's + invoked just like ns_sendmail, except that the email will always + be from the customer service email address. The reply-to field + can be used for the perl/qmail service-345-9848@whatever.com + email trick (but it doesn't have to be).

    Note: one major + difference from ns_sendmail: with ns_sendmail, putting a Cc + header does not actually send an extra copy of the email; it + just puts Cc: whomever@wherever into the header (and then you'd + have to specify whomever@wherever in the bcc argument). This + procedure does send the email to the Cc'd email addresses. +} { set extra_headers [ns_set new] ns_set put $extra_headers "Reply-to" $reply_to @@ -27,468 +46,524 @@ qmail $email_to $from $email_subject $email_body $extra_headers } -ad_proc ec_email_new_order { order_id } "Use this to send out the \"New Order\" email." { - db_1row email_info_select { - select u.email, - to_char(confirmed_date,'MM/DD/YY') as confirmed_date, - shipping_address, u.user_id - from ec_orders, cc_users u - where ec_orders.user_id = u.user_id - and order_id = :order_id - } +ad_proc ec_email_new_order { + order_id +} { + Use this to send out the \"New Order\" email. +} { + if {[db_0or1row email_info_select " + select u.email, to_char(confirmed_date,'MM/DD/YY') as confirmed_date, shipping_address, u.user_id + from ec_orders, cc_users u + where ec_orders.user_id = u.user_id + and order_id = :order_id"]} { - set item_summary [ec_item_summary_in_confirmed_order $order_id] - - if { ![empty_string_p $shipping_address] } { - set address [ec_pretty_mailing_address_from_ec_addresses $shipping_address] - } else { - set address "not deliverable" - } + set item_summary [ec_item_summary_in_confirmed_order $order_id] + + if { ![empty_string_p $shipping_address] } { + set address [ec_pretty_mailing_address_from_ec_addresses $shipping_address] + } else { + set address "not deliverable" + } - set price_summary [ec_formatted_price_shipping_gift_certificate_and_tax_in_an_order $order_id] - - set customer_service_signature [ec_customer_service_signature] - set system_url "[ec_insecure_location][ec_url]" + set price_summary [ec_formatted_price_shipping_gift_certificate_and_tax_in_an_order $order_id] + + set customer_service_signature [ec_customer_service_signature] + set system_url "[ec_insecure_location][ec_url]" - # have to get rid of ampersands in above variables because they - # mess up regsubs - regsub -all "&" $price_summary {\\&} price_summary - regsub -all "&" $item_summary {\\&} item_summary - regsub -all "&" $address {\\&} address - regsub -all "&" $customer_service_signature {\\&} customer_service_signature - regsub -all "&" $system_url {\\&} system_url + # Have to get rid of ampersands in above variables because + # they # mess up regsubs + + regsub -all -- "&" $price_summary {\\&} price_summary + regsub -all -- "&" $item_summary {\\&} item_summary + regsub -all -- "&" $address {\\&} address + regsub -all -- "&" $customer_service_signature {\\&} customer_service_signature + regsub -all -- "&" $system_url {\\&} system_url - # Note: template #1 is defined to be the "New Order" email - db_1row template_select_1 { - select subject as email_subject, message as email_body, issue_type_list - from ec_email_templates - where email_template_id = 1 - } + # Note: template #1 is defined to be the "New Order" email - # and get rid of ctrl-M's in the body - regsub -all "\r" $email_body "" email_body + db_1row template_select_1 " + select subject as email_subject, message as email_body, issue_type_list + from ec_email_templates + where email_template_id = 1" - regsub -all "confirmed_date_here" $email_body $confirmed_date email_body - regsub -all "item_summary_here" $email_body $item_summary email_body - regsub -all "address_here" $email_body $address email_body - regsub -all "price_summary_here" $email_body $price_summary email_body - regsub -all "customer_service_signature_here" $email_body $customer_service_signature email_body - regsub -all "system_url_here" $email_body $system_url email_body + # And get rid of ctrl-M's in the body - db_transaction { + regsub -all -- "\r" $email_body "" email_body - # create a customer service issue/interaction/action - set user_identification_and_issue_id [ec_customer_service_simple_issue "" "automatic" "email" "To: $email\nFrom: [ad_parameter -package_id [ec_id] CustomerServiceEmailAddress ecommerce]\nSubject: $email_subject" $order_id $issue_type_list $email_body $user_id] + regsub -all -- "confirmed_date_here" $email_body $confirmed_date email_body + regsub -all -- "item_summary_here" $email_body $item_summary email_body + regsub -all -- "address_here" $email_body $address email_body + regsub -all -- "price_summary_here" $email_body $price_summary email_body + regsub -all -- "customer_service_signature_here" $email_body $customer_service_signature email_body + regsub -all -- "system_url_here" $email_body $system_url email_body - set user_identification_id [lindex $user_identification_and_issue_id 0] - set issue_id [lindex $user_identification_and_issue_id 1] - if { [empty_string_p $user_identification_id] } { - set user_identification_id 0 - } + db_transaction { - # add a row to the automatic email log - db_dml email_log_insert_1 { - insert into ec_automatic_email_log - (user_identification_id, email_template_id, order_id, date_sent) - values - (:user_identification_id, 1, :order_id, sysdate) + # Create a customer service issue/interaction/action + + set user_identification_and_issue_id [ec_customer_service_simple_issue "" "automatic" "email" \ + "To: $email\nFrom: [ad_parameter -package_id [ec_id] CustomerServiceEmailAddress ecommerce]\nSubject: $email_subject" \ + $order_id $issue_type_list $email_body $user_id] + + set user_identification_id [lindex $user_identification_and_issue_id 0] + set issue_id [lindex $user_identification_and_issue_id 1] + if { [empty_string_p $user_identification_id] } { + set user_identification_id 0 + } + + # Add a row to the automatic email log + + db_dml email_log_insert_1 " + insert into ec_automatic_email_log + (user_identification_id, email_template_id, order_id, date_sent) + values + (:user_identification_id, 1, :order_id, sysdate)" } - } - set email_from [ec_customer_service_email_address $user_identification_id $issue_id] - - ec_sendmail_from_service "$email" "$email_from" "$email_subject" "$email_body" - ec_email_product_notification $order_id - + set email_from [ec_customer_service_email_address $user_identification_id $issue_id] + + ec_sendmail_from_service "$email" "$email_from" "$email_subject" "$email_body" + ec_email_product_notification $order_id + } } -ad_proc ec_email_product_notification { order_id } "This proc sends notifications for any products in the order that require it." { +ad_proc ec_email_product_notification { + order_id +} { + This proc sends notifications for any products in the order that + require it. +} { set order_link [ec_securelink "[ec_url]admin/orders/one?[export_url_vars order_id]"] -# if { [ad_ssl_available_p] } { -# set order_link "[ec_secure_location][ec_url_concat [ec_url] /admin]/orders/one?[export_url_vars order_id]" -# } else { -# set order_link "[ec_insecure_location][ec_url_concat [ec_url] /admin]/orders/one?[export_url_vars order_id]" -# } - db_foreach notification_select { - select ep.email_on_purchase_list, ep.product_name - from ec_items ei, ec_products ep - where ei.product_id = ep.product_id - and ei.order_id = :order_id - group by ep.email_on_purchase_list, ep.product_name - } { - set email_from [ec_customer_service_email_address] - - ec_sendmail_from_service $email_on_purchase_list $email_from "An order for $product_name" " + db_foreach notification_select { + select ep.email_on_purchase_list, ep.product_name + from ec_items ei, ec_products ep + where ei.product_id = ep.product_id + and ei.order_id = :order_id + group by ep.email_on_purchase_list, ep.product_name + } { + set email_from [ec_customer_service_email_address] + ec_sendmail_from_service $email_on_purchase_list $email_from "An order for $product_name" " A order for $product_name has been placed at [ec_system_name]. The order can be viewed at: $order_link " - } + } } -ad_proc ec_email_delayed_credit_denied { order_id } "Use this to send out the \"Delayed Credit Denied\" email." { +ad_proc ec_email_delayed_credit_denied { + order_id +} { + Use this to send out the \"Delayed Credit Denied\" email. +} { - db_1row user_select { + if {[db_0or1row user_select " select u.email, u.user_id - from ec_orders, cc_users u - where ec_orders.user_id = u.user_id - and order_id = :order_id - } + from ec_orders, cc_users u + where ec_orders.user_id = u.user_id + and order_id = :order_id"]} { - set customer_service_signature [ec_customer_service_signature] - set system_url "[ec_insecure_location][ec_url]" + set customer_service_signature [ec_customer_service_signature] + set system_url "[ec_insecure_location][ec_url]" - # have to get rid of ampersands in above variables because they - # mess up regsubs - regsub -all "&" $customer_service_signature {\\&} customer_service_signature - regsub -all "&" $system_url {\\&} system_url - - # Note: template #3 is defined to be the "Delayed Credit Denied" email - db_1row template_select_3 { - select subject as email_subject, message as email_body, issue_type_list from ec_email_templates where email_template_id = 3 - } + # Have to get rid of ampersands in above variables because + # they mess up regsubs - # and get rid of ctrl-M's in the body - regsub -all "\r" $email_body "" email_body + regsub -all -- "&" $customer_service_signature {\\&} customer_service_signature + regsub -all -- "&" $system_url {\\&} system_url + + # Note: template #3 is defined to be the "Delayed Credit + # Denied" email - regsub -all "customer_service_signature_here" $email_body $customer_service_signature email_body - regsub -all "system_url_here" $email_body $system_url email_body + db_1row template_select_3 " + select subject as email_subject, message as email_body, issue_type_list + from ec_email_templates + where email_template_id = 3" - db_transaction { + # And get rid of ctrl-M's in the body - # create a customer service issue/interaction/action - set user_identification_and_issue_id [ec_customer_service_simple_issue "" "automatic" "email" "To: $email\nFrom: [ad_parameter -package_id [ec_id] CustomerServiceEmailAddress ecommerce]\nSubject: $email_subject" $order_id $issue_type_list $email_body $user_id] + regsub -all -- "\r" $email_body "" email_body + regsub -all -- "customer_service_signature_here" $email_body $customer_service_signature email_body + regsub -all -- "system_url_here" $email_body $system_url email_body - set user_identification_id [lindex $user_identification_and_issue_id 0] - set issue_id [lindex $user_identification_and_issue_id 1] + db_transaction { - # add a row to the automatic email log - db_dml email_log_insert_3 { - insert into ec_automatic_email_log - (user_identification_id, email_template_id, order_id, date_sent) - values - (:user_identification_id, 3, :order_id, sysdate) - } - } + # Create a customer service issue/interaction/action - set email_from [ec_customer_service_email_address $user_identification_id $issue_id] - - ec_sendmail_from_service "$email" "$email_from" "$email_subject" "$email_body" + set user_identification_and_issue_id [ec_customer_service_simple_issue "" "automatic" "email" \ + "To: $email\nFrom: [ad_parameter -package_id [ec_id] CustomerServiceEmailAddress ecommerce]\nSubject: $email_subject" \ + $order_id $issue_type_list $email_body $user_id] + set user_identification_id [lindex $user_identification_and_issue_id 0] + set issue_id [lindex $user_identification_and_issue_id 1] + + # Add a row to the automatic email log + + db_dml email_log_insert_3 " + insert into ec_automatic_email_log + (user_identification_id, email_template_id, order_id, date_sent) + values + (:user_identification_id, 3, :order_id, sysdate)" + + } + set email_from [ec_customer_service_email_address $user_identification_id $issue_id] + ec_sendmail_from_service "$email" "$email_from" "$email_subject" "$email_body" + } } -ad_proc ec_email_order_shipped { shipment_id } "Use this to send out the \"Order Shipped\" email after a shipment is made (full or partial order)." { +ad_proc ec_email_order_shipped { + shipment_id +} { + Use this to send out the \"Order Shipped\" email after a + shipment is made (full or partial order). +} { - db_1row shipment_select { + if {[db_0or1row shipment_select " select u.email, u.user_id, s.shipment_date, s.address_id, o.order_state, o.order_id - from ec_orders o, cc_users u, ec_shipments s - where o.user_id = u.user_id - and o.order_id = s.order_id - and s.shipment_id = :shipment_id - } + from ec_orders o, cc_users u, ec_shipments s + where o.user_id = u.user_id + and o.order_id = s.order_id + and s.shipment_id = :shipment_id"]} { - set shipped_date [util_AnsiDatetoPrettyDate $shipment_date] + set shipped_date [util_AnsiDatetoPrettyDate $shipment_date] - # get item_summary - set item_list [list] - db_foreach item_summary_select { - select p.product_name, p.one_line_description, p.product_id, i.price_charged, i.price_name, count(*) as quantity - from ec_items i, ec_products p - where i.product_id=p.product_id - and i.shipment_id=:shipment_id - group by p.product_name, p.one_line_description, p.product_id, i.price_charged, i.price_name - } { - lappend item_list "Quantity $quantity: $product_name; $price_name: [ec_pretty_price $price_charged]" - } + # Get item_summary - set item_summary [join $item_list "\n"] + set item_list [list] + db_foreach item_summary_select " + select p.product_name, p.one_line_description, p.product_id, i.price_charged, i.price_name, count(*) as quantity + from ec_items i, ec_products p + where i.product_id=p.product_id + and i.shipment_id=:shipment_id + group by p.product_name, p.one_line_description, p.product_id, i.price_charged, i.price_name" { + lappend item_list "Quantity $quantity: $product_name; $price_name: [ec_pretty_price $price_charged]" + } - set address [ec_pretty_mailing_address_from_ec_addresses $address_id] + set item_summary [join $item_list "\n"] + set address [ec_pretty_mailing_address_from_ec_addresses $address_id] - # see whether this completes the order - if { $order_state == "fulfilled" } { - set order_completion_sentence "This completes your order." - } else { - set order_completion_sentence "There is still more to come. We will let you know when\nthe rest of your order ships." - } + # See whether this completes the order - set customer_service_signature [ec_customer_service_signature] - set system_url "[ec_insecure_location][ec_url]" + if { $order_state == "fulfilled" } { + set order_completion_sentence "This completes your order." + } else { + set order_completion_sentence "There is still more to come. We will let you know when\nthe rest of your order ships." + } - # have to get rid of ampersands in above variables because they - # mess up regsubs - regsub -all "&" $item_summary {\\&} item_summary - regsub -all "&" $address {\\&} address - regsub -all "&" $order_completion_sentence {\\&} order_completion_sentence - regsub -all "&" $customer_service_signature {\\&} customer_service_signature - regsub -all "&" $system_url {\\&} system_url - - # Note: template #2 is defined to be the "Order Shipped" email - db_1row template_select_2 { - select subject as email_subject, message as email_body, issue_type_list from ec_email_templates where email_template_id = 2 - } + set customer_service_signature [ec_customer_service_signature] + set system_url "[ec_insecure_location][ec_url]" - # and get rid of ctrl-M's in the body - regsub -all "\r" $email_body "" email_body + # Have to get rid of ampersands in above variables because + # they mess up regsubs - regsub -all "shipped_date_here" $email_body $shipped_date email_body - regsub -all "item_summary_here" $email_body $item_summary email_body - regsub -all "address_here" $email_body $address email_body - regsub -all "sentence_about_whether_this_completes_the_order_here" $email_body $order_completion_sentence email_body - regsub -all "customer_service_signature_here" $email_body $customer_service_signature email_body - regsub -all "system_url_here" $email_body $system_url email_body + regsub -all -- "&" $item_summary {\\&} item_summary + regsub -all -- "&" $address {\\&} address + regsub -all -- "&" $order_completion_sentence {\\&} order_completion_sentence + regsub -all -- "&" $customer_service_signature {\\&} customer_service_signature + regsub -all -- "&" $system_url {\\&} system_url + + # Note: template #2 is defined to be the "Order Shipped" email - db_transaction { + db_1row template_select_2 " + select subject as email_subject, message as email_body, issue_type_list + from ec_email_templates + where email_template_id = 2" - # create a customer service issue/interaction/action - set user_identification_and_issue_id [ec_customer_service_simple_issue "" "automatic" "email" "To: $email\nFrom: [ad_parameter -package_id [ec_id] CustomerServiceEmailAddress ecommerce]\nSubject: $email_subject" $order_id $issue_type_list $email_body $user_id] + # And get rid of ctrl-M's in the body - set user_identification_id [lindex $user_identification_and_issue_id 0] - set issue_id [lindex $user_identification_and_issue_id 1] + regsub -all -- "\r" $email_body "" email_body + regsub -all -- "shipped_date_here" $email_body $shipped_date email_body + regsub -all -- "item_summary_here" $email_body $item_summary email_body + regsub -all -- "address_here" $email_body $address email_body + regsub -all -- "sentence_about_whether_this_completes_the_order_here" $email_body $order_completion_sentence email_body + regsub -all -- "customer_service_signature_here" $email_body $customer_service_signature email_body + regsub -all -- "system_url_here" $email_body $system_url email_body - # add a row to the automatic email log - db_dml email_log_insert_2 { - insert into ec_automatic_email_log - (user_identification_id, email_template_id, order_id, shipment_id, date_sent) - values - (:user_identification_id, 2, :order_id, :shipment_id, sysdate) - } - } + db_transaction { - set email_from [ec_customer_service_email_address $user_identification_id $issue_id] - - ec_sendmail_from_service "$email" "$email_from" "$email_subject" "$email_body" - + # Create a customer service issue/interaction/action + + set user_identification_and_issue_id [ec_customer_service_simple_issue "" "automatic" "email" \ + "To: $email\nFrom: [ad_parameter -package_id [ec_id] CustomerServiceEmailAddress ecommerce]\nSubject: $email_subject" \ + $order_id $issue_type_list $email_body $user_id] + + set user_identification_id [lindex $user_identification_and_issue_id 0] + set issue_id [lindex $user_identification_and_issue_id 1] + + # Add a row to the automatic email log + + db_dml email_log_insert_2 " + insert into ec_automatic_email_log + (user_identification_id, email_template_id, order_id, shipment_id, date_sent) + values + (:user_identification_id, 2, :order_id, :shipment_id, sysdate)" + } + set email_from [ec_customer_service_email_address $user_identification_id $issue_id] + ec_sendmail_from_service "$email" "$email_from" "$email_subject" "$email_body" + } } -ad_proc ec_email_new_gift_certificate_order { gift_certificate_id } { +ad_proc ec_email_new_gift_certificate_order { + gift_certificate_id +} { Use this to send out the \"New Gift Certificate Order\" email after a gift certificate order is authorized. } { - db_1row gift_certificate_select " - select g.purchased_by as user_id, u.email, g.recipient_email, g.amount - from ec_gift_certificates g, cc_users u - where g.purchased_by=u.user_id - and g.gift_certificate_id=:gift_certificate_id - " - - set system_name [ad_system_name] - set customer_service_signature [ec_customer_service_signature] + if {[db_0or1row gift_certificate_select " + select g.purchased_by as user_id, u.email, g.recipient_email, g.amount + from ec_gift_certificates g, cc_users u + where g.purchased_by=u.user_id + and g.gift_certificate_id = :gift_certificate_id"]} { + + set system_name [ad_system_name] + set customer_service_signature [ec_customer_service_signature] - # have to get rid of ampersands in above variables because they - # mess up regsubs - regsub -all "&" $recipient_email {\\&} recipient_email - regsub -all "&" $system_name {\\&} system_name - regsub -all "&" $customer_service_signature {\\&} customer_service_signature - - # Note: template #4 is defined to be the "New Gift Certificate Order" email - db_1row template_select_4 { - select subject as email_subject, message as email_body, issue_type_list from ec_email_templates where email_template_id = 4 - } + # Have to get rid of ampersands in above variables because + # they mess up regsubs - # and get rid of ctrl-M's in the body - regsub -all "\r" $email_body "" email_body + regsub -all -- "&" $recipient_email {\\&} recipient_email + regsub -all -- "&" $system_name {\\&} system_name + regsub -all -- "&" $customer_service_signature {\\&} customer_service_signature + + # Note: template #4 is defined to be the "New Gift Certificate + # Order" email - regsub -all "system_name_here" $email_body $system_name email_body - regsub -all "recipient_email_here" $email_body $recipient_email email_body - regsub -all "certificate_amount_here" $email_body [ec_pretty_price $amount] email_body - regsub -all "customer_service_signature_here" $email_body $customer_service_signature email_body + db_1row template_select_4 " + select subject as email_subject, message as email_body, issue_type_list + from ec_email_templates + where email_template_id = 4" - db_transaction { + # And get rid of ctrl-M's in the body - # create a customer service issue/interaction/action - set user_identification_and_issue_id [ec_customer_service_simple_issue "" "automatic" "email" "To: $email\nFrom: [ad_parameter -package_id [ec_id] CustomerServiceEmailAddress ecommerce]\nSubject: $email_subject" "" $issue_type_list $email_body $user_id "" "f" $gift_certificate_id] + regsub -all -- "\r" $email_body "" email_body - set user_identification_id [lindex $user_identification_and_issue_id 0] - set issue_id [lindex $user_identification_and_issue_id 1] + regsub -all -- "system_name_here" $email_body $system_name email_body + regsub -all -- "recipient_email_here" $email_body $recipient_email email_body + regsub -all -- "certificate_amount_here" $email_body [ec_pretty_price $amount] email_body + regsub -all -- "customer_service_signature_here" $email_body $customer_service_signature email_body - # add a row to the automatic email log - db_dml email_log_insert_4 { - insert into ec_automatic_email_log - (user_identification_id, email_template_id, gift_certificate_id, date_sent) - values - (:user_identification_id, 4, :gift_certificate_id, sysdate) - } - } + db_transaction { - set email_from [ec_customer_service_email_address $user_identification_id $issue_id] - - ec_sendmail_from_service "$email" "$email_from" "$email_subject" "$email_body" + # Create a customer service issue/interaction/action + set user_identification_and_issue_id [ec_customer_service_simple_issue "" "automatic" "email" \ + "To: $email\nFrom: [ad_parameter -package_id [ec_id] CustomerServiceEmailAddress ecommerce]\nSubject: $email_subject" \ + "" $issue_type_list $email_body $user_id "" "f" $gift_certificate_id] + + set user_identification_id [lindex $user_identification_and_issue_id 0] + set issue_id [lindex $user_identification_and_issue_id 1] + + # Add a row to the automatic email log + + db_dml email_log_insert_4 " + insert into ec_automatic_email_log + (user_identification_id, email_template_id, gift_certificate_id, date_sent) + values + (:user_identification_id, 4, :gift_certificate_id, sysdate)" + } + + set email_from [ec_customer_service_email_address $user_identification_id $issue_id] + + ec_sendmail_from_service "$email" "$email_from" "$email_subject" "$email_body" + } } -ad_proc ec_email_gift_certificate_order_failure { gift_certificate_id } "Use this to send out the \"Gift Certificate Order Failure\" email after it is determined that a previously inconclusive auth failed." { - db_1row gift_certificate_select_2 { +ad_proc ec_email_gift_certificate_order_failure { + gift_certificate_id +} { + Use this to send out the \"Gift Certificate Order Failure\" + email after it is determined that a previously inconclusive auth + failed. +} { + if {[db_0or1row gift_certificate_select_2 " select g.purchased_by as user_id, u.email, g.recipient_email, g.amount, g.certificate_to, g.certificate_from, g.certificate_message - from ec_gift_certificates g, cc_users u - where g.purchased_by=u.user_id - and g.gift_certificate_id=:gift_certificate_id - } - - set system_name [ad_system_name] - set system_url "[ec_insecure_location][ec_url]" - set customer_service_signature [ec_customer_service_signature] + from ec_gift_certificates g, cc_users u + where g.purchased_by=u.user_id + and g.gift_certificate_id=:gift_certificate_id"]} { + + set system_name [ad_system_name] + set system_url "[ec_insecure_location][ec_url]" + set customer_service_signature [ec_customer_service_signature] - set amount_and_message_summary "" - if { ![empty_string_p $certificate_to] } { - append amount_and_message_summary "To: $certificate_to\n" - } - append amount_and_message_summary "Amount: [ec_pretty_price $amount]\n" - if { ![empty_string_p $certificate_from] } { - append amount_and_message_summary "From: $certificate_from\n" - } - if { ![empty_string_p $certificate_message] } { - append amount_and_message_summary "Message:\n$certificate_message\n" - } + set amount_and_message_summary "" + if { ![empty_string_p $certificate_to] } { + append amount_and_message_summary "To: $certificate_to\n" + } + append amount_and_message_summary "Amount: [ec_pretty_price $amount]\n" + if { ![empty_string_p $certificate_from] } { + append amount_and_message_summary "From: $certificate_from\n" + } + if { ![empty_string_p $certificate_message] } { + append amount_and_message_summary "Message:\n$certificate_message\n" + } - # have to get rid of ampersands in above variables because they - # mess up regsubs - regsub -all "&" $system_name {\\&} system_name - regsub -all "&" $system_url {\\&} system_url - regsub -all "&" $recipient_email {\\&} recipient_email - regsub -all "&" $amount_and_message_summary {\\&} amount_and_message_summary - regsub -all "&" $customer_service_signature {\\&} customer_service_signature - + # Have to get rid of ampersands in above variables because they + # mess up regsubs - # Note: template #6 is defined to be the "Gift Certificate Order Failure" email - db_1row template_select_6 { - select subject as email_subject, message as email_body, issue_type_list - from ec_email_templates - where email_template_id = 6 - } + regsub -all -- "&" $system_name {\\&} system_name + regsub -all -- "&" $system_url {\\&} system_url + regsub -all -- "&" $recipient_email {\\&} recipient_email + regsub -all -- "&" $amount_and_message_summary {\\&} amount_and_message_summary + regsub -all -- "&" $customer_service_signature {\\&} customer_service_signature + - # and get rid of ctrl-M's in the body - regsub -all "\r" $email_body "" email_body + # Note: template #6 is defined to be the "Gift Certificate Order + # Failure" email - regsub -all "system_name_here" $email_body $system_name email_body - regsub -all "system_url_here" $email_body $system_url email_body - regsub -all "recipient_email_here" $email_body $recipient_email email_body - regsub -all "amount_and_message_summary_here" $email_body $amount_and_message_summary email_body - regsub -all "customer_service_signature_here" $email_body $customer_service_signature email_body + db_1row template_select_6 " + select subject as email_subject, message as email_body, issue_type_list + from ec_email_templates + where email_template_id = 6" - db_transaction { + # And get rid of ctrl-M's in the body - # create a customer service issue/interaction/action - set user_identification_and_issue_id [ec_customer_service_simple_issue "" "automatic" "email" "To: $email\nFrom: [ad_parameter -package_id [ec_id] CustomerServiceEmailAddress ecommerce]\nSubject: $email_subject" "" $issue_type_list $email_body $user_id "" "f" $gift_certificate_id] + regsub -all -- "\r" $email_body "" email_body - set user_identification_id [lindex $user_identification_and_issue_id 0] - set issue_id [lindex $user_identification_and_issue_id 1] + regsub -all -- "system_name_here" $email_body $system_name email_body + regsub -all -- "system_url_here" $email_body $system_url email_body + regsub -all -- "recipient_email_here" $email_body $recipient_email email_body + regsub -all -- "amount_and_message_summary_here" $email_body $amount_and_message_summary email_body + regsub -all -- "customer_service_signature_here" $email_body $customer_service_signature email_body - # add a row to the automatic email log - db_dml email_log_insert_6 { - insert into ec_automatic_email_log - (user_identification_id, email_template_id, gift_certificate_id, date_sent) - values - (:user_identification_id, 6, :gift_certificate_id, sysdate) - } - } + db_transaction { - set email_from [ec_customer_service_email_address $user_identification_id $issue_id] - - ec_sendmail_from_service "$email" "$email_from" "$email_subject" "$email_body" + # Create a customer service issue/interaction/action + set user_identification_and_issue_id [ec_customer_service_simple_issue "" "automatic" "email" \ + "To: $email\nFrom: [ad_parameter -package_id [ec_id] CustomerServiceEmailAddress ecommerce]\nSubject: $email_subject" \ + "" $issue_type_list $email_body $user_id "" "f" $gift_certificate_id] + + set user_identification_id [lindex $user_identification_and_issue_id 0] + set issue_id [lindex $user_identification_and_issue_id 1] + + # Add a row to the automatic email log + + db_dml email_log_insert_6 " + insert into ec_automatic_email_log + (user_identification_id, email_template_id, gift_certificate_id, date_sent) + values + (:user_identification_id, 6, :gift_certificate_id, sysdate)" + } + + set email_from [ec_customer_service_email_address $user_identification_id $issue_id] + ec_sendmail_from_service "$email" "$email_from" "$email_subject" "$email_body" + } } # in this email, the recipient isn't necessarily a user of the system, so the customer service issue # creation code is a little different than in the other autoemails -ad_proc ec_email_gift_certificate_recipient { gift_certificate_id } "Use this to send out the \"Gift Certificate Recipient\" email after it a purchased certificate is authorized." { +ad_proc ec_email_gift_certificate_recipient { + gift_certificate_id +} { + Use this to send out the \"Gift Certificate Recipient\" email + after it a purchased certificate is authorized. +} { - db_1row gift_certificate_select_3 { + if {[db_0or1row gift_certificate_select_3 " select g.recipient_email as email, g.amount, g.certificate_to, g.certificate_from, g.certificate_message, g.claim_check - from ec_gift_certificates g - where g.gift_certificate_id=:gift_certificate_id - } + from ec_gift_certificates g + where g.gift_certificate_id=:gift_certificate_id"]} { - set system_name [ad_system_name] - set system_url "[ec_insecure_location][ec_url]" - set customer_service_signature [ec_customer_service_signature] + set system_name [ad_system_name] + set system_url "[ec_insecure_location][ec_url]" + set customer_service_signature [ec_customer_service_signature] - set amount_and_message_summary "" - if { ![empty_string_p $certificate_to] } { - append amount_and_message_summary "To: $certificate_to\n" - } - append amount_and_message_summary "Amount: [ec_pretty_price $amount]\n" - if { ![empty_string_p $certificate_from] } { - append amount_and_message_summary "From: $certificate_from\n" - } - if { ![empty_string_p $certificate_message] } { - append amount_and_message_summary "Message:\n$certificate_message\n" - } + set amount_and_message_summary "" + if { ![empty_string_p $certificate_to] } { + append amount_and_message_summary "To: $certificate_to\n" + } + append amount_and_message_summary "Amount: [ec_pretty_price $amount]\n" + if { ![empty_string_p $certificate_from] } { + append amount_and_message_summary "From: $certificate_from\n" + } + if { ![empty_string_p $certificate_message] } { + append amount_and_message_summary "Message:\n$certificate_message\n" + } - # have to get rid of ampersands in above variables because they - # mess up regsubs - regsub -all "&" $system_name {\\&} system_name - regsub -all "&" $system_url {\\&} system_url - regsub -all "&" $amount_and_message_summary {\\&} amount_and_message_summary - regsub -all "&" $claim_check {\\&} claim_check - regsub -all "&" $customer_service_signature {\\&} customer_service_signature - + # Have to get rid of ampersands in above variables because + # they mess up regsubs - # Note: template #5 is defined to be the "Gift Certificate Recipient" email - db_1row template_select_5 "select subject as email_subject, message as email_body, issue_type_list from ec_email_templates where email_template_id=5" + regsub -all -- "&" $system_name {\\&} system_name + regsub -all -- "&" $system_url {\\&} system_url + regsub -all -- "&" $amount_and_message_summary {\\&} amount_and_message_summary + regsub -all -- "&" $claim_check {\\&} claim_check + regsub -all -- "&" $customer_service_signature {\\&} customer_service_signature + - # and get rid of ctrl-M's in the body - regsub -all "\r" $email_body "" email_body + # Note: template #5 is defined to be the "Gift Certificate + # Recipient" email - regsub -all "system_name_here" $email_body $system_name email_body - regsub -all "system_url_here" $email_body $system_url email_body - regsub -all "amount_and_message_summary_here" $email_body $amount_and_message_summary email_body - regsub -all "claim_check_here" $email_body $claim_check email_body - regsub -all "customer_service_signature_here" $email_body $customer_service_signature email_body + db_1row template_select_5 " + select subject as email_subject, message as email_body, issue_type_list + from ec_email_templates + where email_template_id=5" - # first let's see if the recipient is a registered user of the system - set user_id [db_string user_id_select " - select user_id - from cc_users - where email=lower(:email) - " -default ""] + # And get rid of ctrl-M's in the body - db_transaction { + regsub -all -- "\r" $email_body "" email_body + regsub -all -- "system_name_here" $email_body $system_name email_body + regsub -all -- "system_url_here" $email_body $system_url email_body + regsub -all -- "amount_and_message_summary_here" $email_body $amount_and_message_summary email_body + regsub -all -- "claim_check_here" $email_body $claim_check email_body + regsub -all -- "customer_service_signature_here" $email_body $customer_service_signature email_body - # create a customer service issue/interaction/action - if { ![empty_string_p $user_id] } { - set user_identification_and_issue_id [ec_customer_service_simple_issue "" "automatic" "email" "To: $email\nFrom: [ad_parameter -package_id [ec_id] CustomerServiceEmailAddress ecommerce]\nSubject: $email_subject" "" $issue_type_list $email_body $user_id "" "f" $gift_certificate_id] - set user_identification_id [lindex $user_identification_and_issue_id 0] - } else { - # check if the recipient is an unregistered user of the system - set user_identification_id [db_string user_identification_id_select "select user_identification_id from ec_user_identification where email=lower(:email)" -default ""] + # First let's see if the recipient is a registered user of the + # system - if { [empty_string_p $user_identification_id] } { - set user_identification_id [db_nextval ec_user_ident_id_sequence] - set trimmed_email [string trim $email] + set user_id [db_string user_id_select " + select user_id + from cc_users + where email=lower(:email) " -default ""] - db_dml user_identification_id_insert { - insert into ec_user_identification - (user_identification_id, email) - values - (:user_identification_id, :trimmed_email) - } + db_transaction { - } + # Create a customer service issue/interaction/action - set user_identification_and_issue_id [ec_customer_service_simple_issue "" "automatic" "email" "To: $email\nFrom: [ad_parameter -package_id [ec_id] CustomerServiceEmailAddress ecommerce]\nSubject: $email_subject" "" $issue_type_list $email_body "" $user_identification_id "f" $gift_certificate_id] - } + if { ![empty_string_p $user_id] } { + set user_identification_and_issue_id [ec_customer_service_simple_issue "" "automatic" "email" \ + "To: $email\nFrom: [ad_parameter -package_id [ec_id] CustomerServiceEmailAddress ecommerce]\nSubject: $email_subject" \ + "" $issue_type_list $email_body $user_id "" "f" $gift_certificate_id] + set user_identification_id [lindex $user_identification_and_issue_id 0] + } else { - set issue_id [lindex $user_identification_and_issue_id 1] + # Check if the recipient is an unregistered user of + # the system - # add a row to the automatic email log - db_dml email_log_insert_5 { - insert into ec_automatic_email_log - (user_identification_id, email_template_id, gift_certificate_id, date_sent) - values - (:user_identification_id, 5, :gift_certificate_id, sysdate) - } - } - - set email_from [ec_customer_service_email_address $user_identification_id $issue_id] - - ec_sendmail_from_service "$email" "$email_from" "$email_subject" "$email_body" + set user_identification_id [db_string user_identification_id_select "select user_identification_id from ec_user_identification where email=lower(:email)" -default ""] + if { [empty_string_p $user_identification_id] } { + set user_identification_id [db_nextval ec_user_ident_id_sequence] + set trimmed_email [string trim $email] + + db_dml user_identification_id_insert " + insert into ec_user_identification + (user_identification_id, email) + values + (:user_identification_id, :trimmed_email)" + } + + set user_identification_and_issue_id [ec_customer_service_simple_issue "" "automatic" "email" \ + "To: $email\nFrom: [ad_parameter -package_id [ec_id] CustomerServiceEmailAddress ecommerce]\nSubject: $email_subject" \ + "" $issue_type_list $email_body "" $user_identification_id "f" $gift_certificate_id] + } + + set issue_id [lindex $user_identification_and_issue_id 1] + + # Add a row to the automatic email log + + db_dml email_log_insert_5 " + insert into ec_automatic_email_log + (user_identification_id, email_template_id, gift_certificate_id, date_sent) + values + (:user_identification_id, 5, :gift_certificate_id, sysdate)" + } + set email_from [ec_customer_service_email_address $user_identification_id $issue_id] + ec_sendmail_from_service "$email" "$email_from" "$email_subject" "$email_body" + } } Index: openacs-4/packages/ecommerce/tcl/ecommerce-email-procs.xql =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/ecommerce/tcl/ecommerce-email-procs.xql,v diff -u -r1.3 -r1.4 --- openacs-4/packages/ecommerce/tcl/ecommerce-email-procs.xql 9 Mar 2002 02:00:02 -0000 1.3 +++ openacs-4/packages/ecommerce/tcl/ecommerce-email-procs.xql 26 May 2002 04:36:49 -0000 1.4 @@ -1,182 +1,139 @@ + - - - - select subject as email_subject, message as email_body, issue_type_list - from ec_email_templates - where email_template_id = 1 - - - + + + select subject as email_subject, message as email_body, issue_type_list + from ec_email_templates + where email_template_id = 1 + + - - - - + + select ep.email_on_purchase_list, ep.product_name from ec_items ei, ec_products ep where ei.product_id = ep.product_id and ei.order_id = :order_id group by ep.email_on_purchase_list, ep.product_name - - - + + - - - - - select u.email, u.user_id - from ec_orders, cc_users u - where ec_orders.user_id = u.user_id - and order_id = :order_id - - - + + + select u.email, u.user_id + from ec_orders, cc_users u + where ec_orders.user_id = u.user_id + and order_id = :order_id + + - - - - - select subject as email_subject, message as email_body, issue_type_list - from ec_email_templates - where email_template_id = 3 - - - + + + select subject as email_subject, message as email_body, issue_type_list + from ec_email_templates + where email_template_id = 3 + + - - - - - select u.email, u.user_id, s.shipment_date, s.address_id, o.order_state, o.order_id - from ec_orders o, cc_users u, ec_shipments s - where o.user_id = u.user_id - and o.order_id = s.order_id - and s.shipment_id = :shipment_id - - - + + + select u.email, u.user_id, s.shipment_date, s.address_id, o.order_state, o.order_id + from ec_orders o, cc_users u, ec_shipments s + where o.user_id = u.user_id + and o.order_id = s.order_id + and s.shipment_id = :shipment_id + + - - - - - select p.product_name, p.one_line_description, p.product_id, i.price_charged, i.price_name, count(*) as quantity - from ec_items i, ec_products p - where i.product_id=p.product_id - and i.shipment_id=:shipment_id - group by p.product_name, p.one_line_description, p.product_id, i.price_charged, i.price_name - - - + + + select p.product_name, p.one_line_description, p.product_id, i.price_charged, i.price_name, count(*) as quantity + from ec_items i, ec_products p + where i.product_id=p.product_id + and i.shipment_id=:shipment_id + group by p.product_name, p.one_line_description, p.product_id, i.price_charged, i.price_name + + - - - - - select subject as email_subject, message as email_body, issue_type_list - from ec_email_templates - where email_template_id = 2 - - - + + + select subject as email_subject, message as email_body, issue_type_list + from ec_email_templates + where email_template_id = 2 + + - - - - - select g.purchased_by as user_id, u.email, g.recipient_email, g.amount + + + select g.purchased_by as user_id, u.email, g.recipient_email, g.amount from ec_gift_certificates g, cc_users u - where g.purchased_by=u.user_id - and g.gift_certificate_id=:gift_certificate_id - - - + where g.purchased_by=u.user_id + and g.gift_certificate_id=:gift_certificate_id + + - - - - - select subject as email_subject, message as email_body, issue_type_list - from ec_email_templates - where email_template_id = 4 - - - + + + select subject as email_subject, message as email_body, issue_type_list + from ec_email_templates + where email_template_id = 4 + + - - - - - select g.purchased_by as user_id, u.email, g.recipient_email, g.amount, g.certificate_to, g.certificate_from, g.certificate_message - from ec_gift_certificates g, cc_users u - where g.purchased_by=u.user_id - and g.gift_certificate_id=:gift_certificate_id - - - + + + select g.purchased_by as user_id, u.email, g.recipient_email, g.amount, g.certificate_to, g.certificate_from, g.certificate_message + from ec_gift_certificates g, cc_users u + where g.purchased_by=u.user_id + and g.gift_certificate_id=:gift_certificate_id + + - - - - - select subject as email_subject, message as email_body, issue_type_list - from ec_email_templates - where email_template_id = 6 - - - + + + select subject as email_subject, message as email_body, issue_type_list + from ec_email_templates + where email_template_id = 6 + + - - - + + + select g.recipient_email as email, g.amount, g.certificate_to, g.certificate_from, g.certificate_message, g.claim_check + from ec_gift_certificates g + where g.gift_certificate_id=:gift_certificate_id + + - select g.recipient_email as email, g.amount, g.certificate_to, g.certificate_from, g.certificate_message, g.claim_check - from ec_gift_certificates g - where g.gift_certificate_id=:gift_certificate_id - - - - - - - + + select subject as email_subject, message as email_body, issue_type_list from ec_email_templates where email_template_id=5 - - + + - - - - - select user_id + + + select user_id from cc_users - where email=lower(:email) - - - + where email=lower(:email) + + - - - + + select user_identification_id from ec_user_identification where email=lower(:email) - - + + - - - - - insert into ec_user_identification - (user_identification_id, email) - values - (:user_identification_id, :trimmed_email) - - - + + + insert into ec_user_identification + (user_identification_id, email) + values + (:user_identification_id, :trimmed_email) + + - Index: openacs-4/packages/ecommerce/tcl/ecommerce-money-computations-procs-oracle.xql =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/ecommerce/tcl/ecommerce-money-computations-procs-oracle.xql,v diff -u -r1.1 -r1.2 --- openacs-4/packages/ecommerce/tcl/ecommerce-money-computations-procs-oracle.xql 10 Jul 2001 20:38:43 -0000 1.1 +++ openacs-4/packages/ecommerce/tcl/ecommerce-money-computations-procs-oracle.xql 26 May 2002 04:36:49 -0000 1.2 @@ -1,20 +1,21 @@ - oracle8.1.6 + + oracle + 8.1.6 + - - + + select ec_gift_certificate_balance(:user_id) from dual - - - - - - + + + + + select ec_order_gift_cert_amount(:order_id) from dual - - - - + + + Index: openacs-4/packages/ecommerce/tcl/ecommerce-money-computations-procs-postgresql.xql =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/ecommerce/tcl/ecommerce-money-computations-procs-postgresql.xql,v diff -u -r1.1 -r1.2 --- openacs-4/packages/ecommerce/tcl/ecommerce-money-computations-procs-postgresql.xql 10 Jul 2001 20:38:43 -0000 1.1 +++ openacs-4/packages/ecommerce/tcl/ecommerce-money-computations-procs-postgresql.xql 26 May 2002 04:36:49 -0000 1.2 @@ -1,20 +1,21 @@ - postgresql7.1 + + postgresql + 7.1 + - - + + select ec_gift_certificate_balance(:user_id) - - - - - - + + + + + select ec_order_gift_cert_amount(:order_id) - - - - + + + Index: openacs-4/packages/ecommerce/tcl/ecommerce-money-computations-procs.tcl =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/ecommerce/tcl/ecommerce-money-computations-procs.tcl,v diff -u -r1.5 -r1.6 --- openacs-4/packages/ecommerce/tcl/ecommerce-money-computations-procs.tcl 19 Mar 2002 00:34:25 -0000 1.5 +++ openacs-4/packages/ecommerce/tcl/ecommerce-money-computations-procs.tcl 26 May 2002 04:36:49 -0000 1.6 @@ -18,7 +18,13 @@ @author ported by Jerry Asher (jerry@theashergroup.com) } -ad_proc ec_lowest_price_and_price_name_for_an_item { product_id user_id {offer_code ""} } { returns the lowest price and price name for an item } { +ad_proc ec_lowest_price_and_price_name_for_an_item { + product_id + user_id + {offer_code ""} +} { + Returns the lowest price and price name for an item +} { set lowest_price 0 set lowest_price_name "" set reg_price [db_string get_price "select price from ec_products where product_id=:product_id"] @@ -73,19 +79,40 @@ # I've included the product_id, order_id, and shipping_method in the arguments because they're # always already known in any environment where I intend to call this procedure, so I might as # well save two database hits. -ad_proc ec_shipping_price_for_one_item {item_id product_id order_id shipping_method} { returns the shipping price for one item } { - # get shipping, shipping_additional, default_shipping_per_item, weight, weight_shipping_cost - # to determine regular shipping price - db_1row get_shipping_info "select shipping, shipping_additional, weight from ec_products where product_id=:product_id" - - db_1row get_default_shipping_info "select default_shipping_per_item, weight_shipping_cost from ec_admin_settings" +ad_proc ec_shipping_price_for_one_item { + item_id + product_id + order_id + shipping_method +} { + returns the shipping price for one item +} { + # Get shipping, shipping_additional, default_shipping_per_item, + # weight, weight_shipping_cost to determine regular shipping price + + db_1row get_shipping_info " + select shipping, shipping_additional, weight + from ec_products + where product_id=:product_id" - # calculate regular shipping price + db_1row get_default_shipping_info " + select default_shipping_per_item, weight_shipping_cost + from ec_admin_settings" + + # Calculate regular shipping price + if { ![empty_string_p $shipping_additional] } { - # find out if this is the first instance of the product in this order, or a later instance - set first_instance [db_string get_first_item "select min(item_id) from ec_items where product_id=:product_id and order_id:order_id"] + + # Find out if this is the first instance of the product in + # this order, or a later instance + + set first_instance [db_string get_first_item " + select min(item_id) + from ec_items + where product_id = :product_id + and order_id = :order_id"] if { $item_id != $first_instance } { set reg_shipping $shipping_additional } elseif { ![empty_string_p $shipping] } { @@ -102,9 +129,13 @@ } set total_shipping_cost $reg_shipping - # see if we have to add something for express shipping + + # See if we have to add something for express shipping + if { $shipping_method == "express" } { - db_1row get_exp_info "select add_exp_amount_per_item, add_exp_amount_by_weight from ec_admin_settings" + db_1row get_exp_info " + select add_exp_amount_per_item, add_exp_amount_by_weight + from ec_admin_settings" if { ![empty_string_p $add_exp_amount_per_item] } { set total_shipping_cost [expr $total_shipping_cost + $add_exp_amount_per_item] @@ -116,37 +147,63 @@ return $total_shipping_cost } -# Returns price, price_name, shipping, price_tax, and shipping_tax (all in a list) for one item. -# I will make user_class_id_list default_shipping_per_item, weight_shipping_cost, -# add_exp_amount_per_item, add_exp_amount_by_weight, tax_rate, and shipping_p arguments -# because they are constant, so I don't want to have to pull them from the database each -# time (this procedure is called from within a loop) -# For preconfirmed orders. -ad_proc 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 "no shipping"} {default_shipping_per_item 0} {weight_shipping_cost 0} {add_exp_amount_per_item 0} {add_exp_amount_by_weight 0} {tax_rate 0} {shipping_p "f"}} { Returns price, price_name, shipping, price_tax, and shipping_tax (all in a list) for one item. } { +ad_proc 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 "no shipping"} + {default_shipping_per_item 0} + {weight_shipping_cost 0} + {add_exp_amount_per_item 0} + {add_exp_amount_by_weight 0} + {tax_rate 0} + {shipping_p "f"} +} { + Returns price, price_name, shipping, price_tax, and shipping_tax + (all in a list) for one item. + Made user_class_id_list default_shipping_per_item, + weight_shipping_cost, add_exp_amount_per_item, + add_exp_amount_by_weight, tax_rate, and shipping_p arguments + because they are constant, so they don't have to be pulled them + from the database each time (this procedure is called from + within a loop) + + For preconfirmed orders. +} { + ## ## Part 1: Get Price & Price Name ## set lowest_price 0 set lowest_price_name "none" - set reg_price [db_string get_item_price "select price from ec_products where product_id=:product_id"] + set reg_price [db_string get_item_price " + select price + from ec_products + where product_id = :product_id"] if { ![empty_string_p $reg_price] } { set lowest_price $reg_price set lowest_price_name "Our Price" } + if { [llength $user_class_id_list] > 0 } { - db_foreach get_price_and_name "select p.price, c.user_class_name - from ec_product_user_class_prices p, ec_user_classes c - where p.product_id=:product_id - and p.user_class_id=c.user_class_id - and p.user_class_id in ([join $user_class_id_list ", "])" { + db_foreach get_price_and_name " + select p.price, c.user_class_name + from ec_product_user_class_prices p, ec_user_classes c + where p.product_id=:product_id + and p.user_class_id=c.user_class_id + and p.user_class_id in ([join $user_class_id_list ", "])" { - if { ![empty_string_p $price] && $price < $lowest_price } { set lowest_price $price - # only include the user_class_name in the name of the price if - # the user is allowed to see what user classes they're in + + # Only include the user_class_name in the name of the + # price if the user is allowed to see what user + # classes they're in + if { [ad_parameter -package_id [ec_id] UserClassUserViewP ecommerce] == 1 } { set lowest_price_name "$user_class_name Price" } else { @@ -161,12 +218,11 @@ } else { set or_part_of_query "" } - db_foreach get_sale_prices "select sale_price, sale_name - from ec_sale_prices_current - where product_id=:product_id - and (offer_code is null $or_part_of_query) - " { - + db_foreach get_sale_prices " + select sale_price, sale_name + from ec_sale_prices_current + where product_id=:product_id + and (offer_code is null $or_part_of_query)" { if { ![empty_string_p $sale_price] && $sale_price < $lowest_price } { set lowest_price $sale_price @@ -175,20 +231,33 @@ } # To return: + set price_to_return $lowest_price set price_name_to_return $lowest_price_name ## ## Part 2: Determine Shipping Cost ## - db_1row get_shipping_costs "select shipping, shipping_additional, weight from ec_products where product_id=:product_id" - + db_1row get_shipping_costs " + select case when no_shipping_avail_p = 'f' then shipping else null end as shipping, + case when no_shipping_avail_p = 'f' then shipping_additional else null end as shipping_additional, + case when no_shipping_avail_p = 'f' then weight else null end as weight + from ec_products + where product_id = :product_id" - # calculate regular shipping price + # Calculate regular shipping price + if { ![empty_string_p $shipping_additional] } { - # find out if this is the first instance of the product in this order, or a later instance - set first_instance [db_string get_first_instance "select min(item_id) from ec_items where product_id=:product_id and order_id=:order_id"] + + # Find out if this is the first instance of the product in + # this order, or a later instance + + set first_instance [db_string get_first_instance " + select min(item_id) + from ec_items + where product_id = :product_id + and order_id = :order_id"] if { $item_id != $first_instance } { set reg_shipping $shipping_additional } elseif { ![empty_string_p $shipping] } { @@ -205,7 +274,9 @@ } set total_shipping_cost $reg_shipping - # see if we have to add something for express shipping + + # See if we have to add something for express shipping + if { $shipping_method == "express" } { if { ![empty_string_p $add_exp_amount_per_item] } { set total_shipping_cost [expr $total_shipping_cost + $add_exp_amount_per_item] @@ -216,6 +287,7 @@ } # To return: + set shipping_to_return $total_shipping_cost ## @@ -227,47 +299,58 @@ set shipping_tax_to_return 0 } else { set price_tax_to_return [expr $price_to_return * $tax_rate] - if { $shipping_p == "f" } { set shipping_tax_to_return 0 } else { set shipping_tax_to_return [expr $shipping_to_return * $tax_rate] } } - return [list $price_to_return $price_name_to_return $shipping_to_return $price_tax_to_return $shipping_tax_to_return] - } -# returns a list containing the total price, total shipping, gift_certificate amount -# and total tax for an order -# this assumes all prices and shipping and tax charges are filled in for the order -# and items -# gift_certificate amount is: taken from database for confirmed orders, or calculated -# for not yet confirmed orders -# Note: the price it shows is really price charged minus price refunded, similarly -# for shipping and tax. -ad_proc ec_price_shipping_gift_certificate_and_tax_in_an_order { order_id } { returns a list containing the total price, total shipping, gift_certificate amount and total tax for an order } { +ad_proc ec_price_shipping_gift_certificate_and_tax_in_an_order { + order_id +} { - db_1row get_confirmed_info { + Returns a list containing the total price, total shipping, + gift_certificate amount and total tax for an order. This + assumes all prices and shipping and tax charges are filled in + for the order and items. + + gift_certificate amount is taken from database for confirmed + orders, or calculated for not yet confirmed orders. + + Note: the price it shows is really price charged minus price + refunded, similarly for shipping and tax. + +} { + + db_1row get_confirmed_info " select confirmed_date, user_id, - ec_total_price(:order_id) as total_price, - ec_total_shipping(:order_id) as total_shipping, - ec_total_tax(:order_id) as total_tax + ec_total_price(:order_id) as total_price, + ec_total_shipping(:order_id) as total_shipping, + ec_total_tax(:order_id) as total_tax from ec_orders - where order_id = :order_id - } + where order_id = :order_id" - # if order has been confirmed, use the gift certificate amount actually used - # otherwise determine what it will be using ec_gift_certificate_balance($user_id) + # If order has been confirmed, use the gift certificate amount + # actually used otherwise determine what it will be using + # ec_gift_certificate_balance($user_id) if { [empty_string_p $confirmed_date] } { - set gift_certificate_balance [db_string get_ec_gc_bal "select ec_gift_certificate_balance(:user_id) from dual"] + set gift_certificate_balance [db_string get_ec_gc_bal " + select ec_gift_certificate_balance(:user_id) + from dual"] set gift_certificate_amount [ec_min [expr $total_price + $total_shipping + $total_tax] $gift_certificate_balance] } else { - # the gift certificate amount is always up-to-date (includes reinstatements) - set gift_certificate_amount [db_string get_gc_amount "select ec_order_gift_cert_amount(:order_id) from dual"] + + # The gift certificate amount is always up-to-date (includes + # reinstatements) + + set gift_certificate_amount [db_string get_gc_amount " + select ec_order_gift_cert_amount(:order_id) + from dual"] } return [list $total_price $total_shipping $gift_certificate_amount $total_tax] -} \ No newline at end of file +} Index: openacs-4/packages/ecommerce/tcl/ecommerce-money-computations-procs.xql =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/ecommerce/tcl/ecommerce-money-computations-procs.xql,v diff -u -r1.1 -r1.2 --- openacs-4/packages/ecommerce/tcl/ecommerce-money-computations-procs.xql 10 Jul 2001 20:38:43 -0000 1.1 +++ openacs-4/packages/ecommerce/tcl/ecommerce-money-computations-procs.xql 26 May 2002 04:36:49 -0000 1.2 @@ -1,120 +1,119 @@ + - - + + select price from ec_products where product_id=:product_id - - - - - - - - select p.price, c.user_class_name - from ec_product_user_class_prices p, ec_user_classes c - where p.product_id=:product_id - and p.user_class_id=c.user_class_id - and p.user_class_id in (select m.user_class_id from ec_user_class_user_map m where m.user_id=:user_id $additional_user_class_restriction) - - - - - - - + + + + + + select p.price, c.user_class_name + from ec_product_user_class_prices p, ec_user_classes c + where p.product_id=:product_id + and p.user_class_id=c.user_class_id + and p.user_class_id in (select m.user_class_id + from ec_user_class_user_map m + where m.user_id=:user_id $additional_user_class_restriction) + + + + + select sale_price, sale_name - from ec_sale_prices_current - where product_id=:product_id - and (offer_code is null $or_part_of_query) - - - - - - - - select shipping, shipping_additional, weight from ec_products where product_id=:product_id - - - - - - - select default_shipping_per_item, weight_shipping_cost from ec_admin_settings - - - - - - - select min(item_id) from ec_items where product_id=:product_id and order_id:order_id - - - - - - - select add_exp_amount_per_item, add_exp_amount_by_weight from ec_admin_settings - - - - - - - select price from ec_products where product_id=:product_id - - - - - - + from ec_sale_prices_current + where product_id=:product_id + and (offer_code is null $or_part_of_query) + + + + + + select shipping, shipping_additional, weight + from ec_products + where product_id=:product_id + + + + + + select default_shipping_per_item, weight_shipping_cost + from ec_admin_settings + + + + + + select min(item_id) + from ec_items + where product_id = :product_id + and order_id:order_id + + + + + + select add_exp_amount_per_item, add_exp_amount_by_weight + from ec_admin_settings + + + + + + select price from ec_products + where product_id=:product_id + + + + + select p.price, c.user_class_name - from ec_product_user_class_prices p, ec_user_classes c - where p.product_id=:product_id - and p.user_class_id=c.user_class_id - and p.user_class_id in ([join $user_class_id_list ", "]) - - - - - - + from ec_product_user_class_prices p, ec_user_classes c + where p.product_id=:product_id + and p.user_class_id=c.user_class_id + and p.user_class_id in ([join $user_class_id_list ", "]) + + + + + select sale_price, sale_name - from ec_sale_prices_current - where product_id=:product_id - and (offer_code is null $or_part_of_query) - - - - - - - - select shipping, shipping_additional, weight from ec_products where product_id=:product_id - - - - - - - select min(item_id) from ec_items where product_id=:product_id and order_id=:order_id - - - - - - - - select confirmed_date, user_id, - ec_total_price(:order_id) as total_price, - ec_total_shipping(:order_id) as total_shipping, - ec_total_tax(:order_id) as total_tax - from ec_orders - where order_id = :order_id - - - - - + from ec_sale_prices_current + where product_id=:product_id + and (offer_code is null $or_part_of_query) + + + + + + select case when no_shipping_avail_p = 'f' then shipping else null end as shipping, + case when no_shipping_avail_p = 'f' then shipping_additional else null end as shipping_additional, + case when no_shipping_avail_p = 'f' then weight else null end as weight + from ec_products + where product_id = :product_id + + + + + + select min(item_id) + from ec_items + where product_id = :product_id + and order_id=:order_id + + + + + + select confirmed_date, user_id, + ec_total_price(:order_id) as total_price, + ec_total_shipping(:order_id) as total_shipping, + ec_total_tax(:order_id) as total_tax + from ec_orders + where order_id = :order_id + + + Index: openacs-4/packages/ecommerce/tcl/ecommerce-procs-oracle.xql =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/ecommerce/tcl/ecommerce-procs-oracle.xql,v diff -u -r1.4 -r1.5 --- openacs-4/packages/ecommerce/tcl/ecommerce-procs-oracle.xql 24 Nov 2001 03:52:22 -0000 1.4 +++ openacs-4/packages/ecommerce/tcl/ecommerce-procs-oracle.xql 26 May 2002 04:36:49 -0000 1.5 @@ -1,102 +1,84 @@ - oracle8.1.6 + + oracle + 8.1.6 + - - - - select site_node.url(s.node_id) - from site_nodes s, apm_packages a - where s.object_id = a.package_id - and a.package_key = 'ecommerce' - - - + + + select site_node.url(s.node_id) + from site_nodes s, apm_packages a + where s.object_id = a.package_id + and a.package_key = 'ecommerce' + + - - - - - select site_node.url(s.node_id) - from site_nodes s, apm_packages a - where s.object_id = a.package_id - and a.package_key = '$package_key' - - - + + + select site_node.url(s.node_id) + from site_nodes s, apm_packages a + where s.object_id = a.package_id + and a.package_key = '$package_key' + + - - - - - select c.one_line_summary, - c.rating, - c.user_comment, - to_char(c.last_modified,'Day Month DD, YYYY') as last_modified_pretty, - u.email, - u.user_id - from ec_product_comments c, - cc_users u - where c.user_id = u.user_id - and c.product_id = :product_id - $end_of_comment_query - - - + + + select c.one_line_summary, + c.rating, + c.user_comment, + to_char(c.last_modified,'Day Month DD, YYYY') as last_modified_pretty, + u.email, + u.user_id + from ec_product_comments c, + cc_users u + where c.user_id = u.user_id + and c.product_id = :product_id + $end_of_comment_query + + - - - - - select decode(sign(sysdate-available_date),1,1,null,1,0) as available_p, - color_list, size_list, style_list, no_shipping_avail_p - from ec_products - where product_id = :product_id - - - + + + select decode(sign(sysdate-available_date),1,1,null,1,0) as available_p, + color_list, size_list, style_list, no_shipping_avail_p + from ec_products + where product_id = :product_id + + - - - - - select to_char(available_date,'Month DD, YYYY') available_date - from ec_products - where product_id = :product_id - - - + + + select to_char(available_date,'Month DD, YYYY') available_date + from ec_products + where product_id = :product_id + + - - - - - select eco.confirmed_date, eco.creditcard_id, eco.shipping_method, - u.email, - eca.line1, eca.line2, eca.city, eca.usps_abbrev, eca.zip_code, eca.country_code, - eca.full_state_name, eca.attn, eca.phone, eca.phone_time - from ec_orders eco, - cc_users u, - ec_addresses eca - where eco.order_id = :order_id - and eco.user_id = u.user_id(+) - and eco.shipping_address = eca.address_id(+) - - - + + + select eco.confirmed_date, eco.creditcard_id, eco.shipping_method, + u.email, + eca.line1, eca.line2, eca.city, eca.usps_abbrev, eca.zip_code, eca.country_code, + eca.full_state_name, eca.attn, eca.phone, eca.phone_time + from ec_orders eco, + cc_users u, + ec_addresses eca + where eco.order_id = :order_id + and eco.user_id = u.user_id(+) + and eco.shipping_address = eca.address_id(+) + + - - - - - insert into ec_user_sessions - (user_session_id, ip_address, start_time, http_user_agent) - values - (:user_session_id, :ip_address , sysdate, :http_user_agent) - - - + + + insert into ec_user_sessions + (user_session_id, ip_address, start_time, http_user_agent) + values + (:user_session_id, :ip_address , sysdate, :http_user_agent) + + - Index: openacs-4/packages/ecommerce/tcl/ecommerce-procs-postgresql.xql =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/ecommerce/tcl/ecommerce-procs-postgresql.xql,v diff -u -r1.7 -r1.8 --- openacs-4/packages/ecommerce/tcl/ecommerce-procs-postgresql.xql 24 Nov 2001 03:52:22 -0000 1.7 +++ openacs-4/packages/ecommerce/tcl/ecommerce-procs-postgresql.xql 26 May 2002 04:36:49 -0000 1.8 @@ -1,84 +1,69 @@ - postgresql7.1 + + postgresql + 7.1 + - - - - select site_node__url(s.node_id) - from site_nodes s, apm_packages a - where s.object_id = a.package_id - and a.package_key = 'ecommerce' - - - + + + select site_node__url(s.node_id) + from site_nodes s, apm_packages a + where s.object_id = a.package_id + and a.package_key = 'ecommerce' + + - - - - - select site_node__url(s.node_id) - from site_nodes s, apm_packages a - where s.object_id = a.package_id - and a.package_key = '$package_key' - - - + + + select site_node__url(s.node_id) + from site_nodes s, apm_packages a + where s.object_id = a.package_id + and a.package_key = '$package_key' + + - - - - - select c.one_line_summary, - c.rating, - c.user_comment, - to_char(c.last_modified,'Day Month DD, YYYY') as last_modified_pretty, - u.email, - u.user_id - from ec_product_comments c, - cc_users u - where c.user_id = u.user_id - and c.product_id = :product_id - $end_of_comment_query - - - + + + select c.one_line_summary, + c.rating, + c.user_comment, + to_char(c.last_modified,'Day Month DD, YYYY') as last_modified_pretty, + u.email, + u.user_id + from ec_product_comments c, + cc_users u + where c.user_id = u.user_id + and c.product_id = :product_id + $end_of_comment_query + + - - - + + + select case when current_timestamp > available_date then 1 when current_timestamp-available_date is NULL then 1 else 0 end as available_p, + color_list, size_list, style_list, no_shipping_avail_p + from ec_products + where product_id = :product_id + + - select case when current_timestamp > available_date then 1 when current_timestamp-available_date is NULL then 1 else 0 end as available_p, - color_list, size_list, style_list, no_shipping_avail_p - from ec_products - where product_id = :product_id - - - + + + select to_char(available_date,'Month DD, YYYY') available_date + from ec_products + where product_id = :product_id + + - - - - - select to_char(available_date,'Month DD, YYYY') available_date - from ec_products - where product_id = :product_id - - - + + + insert into ec_user_sessions + (user_session_id, ip_address, start_time, http_user_agent) + values + (:user_session_id, :ip_address, current_timestamp, :http_user_agent) + + - - - - - insert into ec_user_sessions - (user_session_id, ip_address, start_time, http_user_agent) - values - (:user_session_id, :ip_address, current_timestamp, :http_user_agent) - - - - - Index: openacs-4/packages/ecommerce/tcl/ecommerce-procs.tcl =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/ecommerce/tcl/ecommerce-procs.tcl,v diff -u -r1.11 -r1.12 --- openacs-4/packages/ecommerce/tcl/ecommerce-procs.tcl 21 Feb 2002 21:07:15 -0000 1.11 +++ openacs-4/packages/ecommerce/tcl/ecommerce-procs.tcl 26 May 2002 04:36:49 -0000 1.12 @@ -1,4 +1,3 @@ -# /tcl/ecommerce-defs.tcl ad_library { Definitions for the ecommerce module Note: Other ecommerce procedures can be found in ecommerce-*.tcl @@ -112,20 +111,22 @@ ### the url to get to ec -ad_proc -public ec_url {} { +ad_proc -public ec_url { +} { @return The url (without protocol or port) of the ecommerce mountpoint if it exists, 0 otherwise. } { return [util_memoize {ec_url_mem} [ec_cache_refresh]] } -ad_proc -private ec_url_mem {} {} { +ad_proc -private ec_url_mem { +} { +} { if {[db_table_exists apm_packages]} { - return [db_string ec_mountpoint { - select site_node.url(s.node_id) - from site_nodes s, apm_packages a - where s.object_id = a.package_id - and a.package_key = 'ecommerce' - } -default 0] + return [db_string ec_mountpoint " + select site_node.url(s.node_id) + from site_nodes s, apm_packages a + where s.object_id = a.package_id + and a.package_key = 'ecommerce'" -default 0] } else { return 0 } @@ -649,18 +650,17 @@ {preorder_button_text "Pre-order This Now!"} {form_action "shopping-cart-add"} {order_id ""} -} { returns cart link } { +} { + Returns cart link +} { - db_1row get_product_info_1 { - select decode(sign(sysdate-available_date),1,1,null,1,0) as available_p, - color_list, size_list, style_list, no_shipping_avail_p - from ec_products - where product_id = :product_id - } + db_1row get_product_info_1 " + select decode(sign(sysdate-available_date),1,1,null,1,0) as available_p, color_list, size_list, style_list, no_shipping_avail_p + from ec_products + where product_id = :product_id" if { ![empty_string_p $color_list] } { - set color_widget "Color: " foreach color [split $color_list ","] { append color_widget "

    $category_descriptions -
    [join $linked_category_list " | "]
    -
    - " +
    + $category_descriptions + + + + +
    + [join $linked_category_list " | "] +
    +
    " - return "$top_links $linked_category_list" + return "$linked_category_list" } -# for_customer, as opposed to one for the admins -# if show_item_detail_p is "t", then the user will see the tracking number, etc. -ad_proc ec_order_summary_for_customer { order_id user_id {show_item_detail_p "f"} } { shows item details } { +ad_proc ec_order_summary_for_customer { + order_id + user_id + {show_item_detail_p "f"} +} { + Shows item details to customers, as opposed to one for the + admins. If show_item_detail_p is "t", then the user will see the + tracking number, etc. +} { # display : # email address # shipping address (w/phone #) @@ -825,48 +805,42 @@ # total cost # little security check - set correct_user_id [db_string correct_user_id { - select user_id as correct_user_id from ec_orders where order_id = :order_id - }] - + + set correct_user_id [db_string correct_user_id " + select user_id as correct_user_id + from ec_orders + where order_id = :order_id"] if { [string compare $user_id $correct_user_id] != 0 } { return "Invalid Order ID" } - db_1row order_info_select { - select eco.confirmed_date, eco.creditcard_id, eco.shipping_method, - u.email, - eca.line1, eca.line2, eca.city, eca.usps_abbrev, eca.zip_code, eca.country_code, - eca.full_state_name, eca.attn, eca.phone, eca.phone_time - from ec_orders eco, - cc_users u, - ec_addresses eca - where eco.order_id = :order_id - and eco.user_id = u.user_id(+) - and eco.shipping_address = eca.address_id(+) - } + db_1row order_info_select " + select o.confirmed_date, o.creditcard_id, o.shipping_method, + u.email, o.shipping_address as shipping_address_id, c.billing_address as billing_address_id + from ec_orders o + left join cc_users u on (o.user_id = u.user_id) + left join ec_creditcards c on (o.creditcard_id = c.creditcard_id) + where o.order_id = :order_id" - set address [ec_pretty_mailing_address_from_args $line1 $line2 $city $usps_abbrev $zip_code $country_code $full_state_name $attn $phone $phone_time] + set shipping_address [ec_pretty_mailing_address_from_ec_addresses $shipping_address_id] if { ![empty_string_p $creditcard_id] } { set creditcard_summary [ec_creditcard_summary $creditcard_id] } else { set creditcard_summary "" } + + set billing_address [ec_pretty_mailing_address_from_ec_addresses $billing_address_id] set items_ul "" - db_foreach order_details_select { + 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 - } { + 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" { set option_list [list] if { ![empty_string_p $color_choice] } { @@ -883,20 +857,18 @@ set options "$options; " } - append items_ul "
  • Quantity $quantity: $product_name; $options$price_name: [ec_pretty_price $price_charged [ad_parameter -package_id [ec_id] Currency ecommerce]]\n" + append items_ul "
  • Quantity $quantity: $product_name; $options$price_name: [ec_pretty_price $price_charged [ad_parameter -package_id [ec_id] Currency ecommerce]]" if { $show_item_detail_p == "t" } { append items_ul "
    - [ec_shipment_summary_sub $product_id $color_choice $size_choice $style_choice $price_charged $price_name $order_id] - " + [ec_shipment_summary_sub $product_id $color_choice $size_choice $style_choice $price_charged $price_name $order_id]" } + append items_ul "
  • " } set shipping_method_to_print "[ec_decode $shipping_method "standard" "Standard Shipping" "express" "Express Shipping" "pickup" "Pickup" "no shipping" "No Shipping" "Unknown Shipping Method"]" - set price_summary [ec_formatted_price_shipping_gift_certificate_and_tax_in_an_order $order_id] - set to_return "
    -"
    +    set to_return "
    "
         if { ![empty_string_p $confirmed_date] } {
     	append to_return "Order date:\n[util_AnsiDatetoPrettyDate $confirmed_date]\n\n"
         }
    @@ -905,7 +877,10 @@
     $email
     
     [ec_decode $shipping_method "pickup" "Address:" "no shipping" "Address:" "Ship to:"]
    -$address
    +$shipping_address
    +
    +Bill to:
    +$billing_address
     [ec_decode $creditcard_summary "" "" "
     Credit card:
     $creditcard_summary
    @@ -921,10 +896,8 @@
     Ship via: $shipping_method_to_print
     
     $price_summary
    -
    -" - -return $to_return +
    " + return $to_return } # Eve deleted the procedure ec_gift_certificate_summary_for_customer @@ -1072,15 +1045,99 @@ } } -ad_proc ec_price_line { product_id user_id {offer_code "" } {order_confirmed_p "f"} } { returns the price line } { +ad_proc ec_price_line { + product_id + user_id + {offer_code "" } + {order_confirmed_p "f"} +} { + Returns the price line +} { + set currency [ad_parameter -package_id [ec_id] Currency] set lowest_price_and_price_name [ec_lowest_price_and_price_name_for_an_item $product_id $user_id $offer_code] - + set lowest_price [lindex $lowest_price_and_price_name 0] set lowest_price_description [lindex $lowest_price_and_price_name 1] if {![string equal "" $lowest_price_description]} { - append lowest_price_description : + set price_line " + + + " + } else { + set price_line " +
    $lowest_price_description:
    + + " } - set currency [ad_parameter -package_id [ec_id] Currency] - return "$lowest_price_description [ec_pretty_price [lindex $lowest_price_and_price_name 0] $currency]" + append price_line " + + " + + if { [ad_parameter -package_id [ec_id] UserClassApproveP ecommerce] } { + db_1row get_regular_approvalrequired_price " + select min(case when ucp.price is null then p.price + when p.price < ucp.price then p.price + else ucp.price end) as regular_price, ucp.user_class_name + from ec_products p left join (select uc.product_id, uc.price, c.user_class_name + from ec_product_user_class_prices uc, ec_user_classes c, + ec_user_class_user_map m + where uc.user_class_id = c.user_class_id + and uc.product_id = :product_id + and uc.user_class_id = m.user_class_id + and m.user_id = :user_id + and m.user_class_approved_p = 't' + order by uc.price + limit 1) as ucp using (product_id) + where p.product_id = :product_id + group by p.product_id, ucp.user_class_name" + } else { + db_1row get_regular_no_approval_required_price " + select min(case when ucp.price is null then p.price + when p.price < ucp.price then p.price + else ucp.price end) as regular_price, ucp.user_class_name + from ec_products p left join (select uc.product_id, uc.price, c.user_class_name + from ec_product_user_class_prices uc, ec_user_classes c, + ec_user_class_user_map m + where uc.user_class_id = c.user_class_id + and uc.product_id = :product_id + and uc.user_class_id = m.user_class_id + and m.user_id = :user_id + and (m.user_class_approved_p is null + or m.user_class_approved_p = 't') + order by uc.price + limit 1) as ucp using (product_id) + where p.product_id = :product_id + group by p.product_id, ucp.user_class_name" + } + + # Compare the sales price with the regular price and show the + # savings. + + if {[string compare $lowest_price $regular_price] == -1} { + append price_line " + + + + + + + + +
    Our Price: + [ec_pretty_price $lowest_price $currency] +
    Compare to:[ec_pretty_price $regular_price $currency]
    Savings:[format %.2f [expr (($regular_price - $lowest_price) / $regular_price) * 100]]%
    " + } else { + append price_line " +
      
      
    " + } + return $price_line } ad_proc ec_product_review_summary {author_name publication review_date} "Returns a one-line user-readable summary of a product review" { @@ -1102,7 +1159,7 @@ if { [exists_and_not_null confirmed_date] } { append to_return " on [ec_IllustraDatetoPrettyDate $confirmed_date] " } - if { $order_state == "confirmed" || $order_state == "authorized_plus_avs" || $order_state == "authorized_minus_avs" || $order_state == "partially_fulfilled" } { + if { $order_state == "confirmed" || $order_state == "authorized" || $order_state == "partially_fulfilled" } { # this is awaiting authorization # or needs to be fulfilled, so highlight the order state append to_return "($order_state)\n" @@ -1218,72 +1275,54 @@ return $price_summary } -# says how the items with a given product_id, color, size, style, price_charged, -# and price_name in a given order shipped; the reason we put in all these parameters -# is that item summaries group items in this manner -ad_proc ec_shipment_summary_sub { product_id color_choice size_choice style_choice price_charged price_name order_id } { -says how the items with a given product_id, color, size, style, price_charged, -and price_name in a given order shipped; the reason we put in all these parameters is that item summaries group items in this manner +ad_proc ec_shipment_summary_sub { + product_id + color_choice + size_choice + style_choice + price_charged + price_name + order_id +} { + Says how the items with a given product_id, color, size, style, + price_charged, and price_name in a given order shipped; the + reason we put in all these parameters is that item summaries + group items in this manner } { set shipment_list [list] db_foreach items_shipped_select " select s.shipment_date, s.carrier, s.tracking_number, s.shipment_id, s.shippable_p, count(*) as n_items - from ec_items i, - ec_shipments s - where i.order_id = :order_id - and i.shipment_id = s.shipment_id - and i.product_id = :product_id - and i.color_choice [ec_decode $color_choice "" "is null" "= :color_choice"] - and i.size_choice [ec_decode $size_choice "" "is null" "= :size_choice"] - and i.style_choice [ec_decode $style_choice "" "is null" "= :style_choice"] - and i.price_charged [ec_decode $price_charged "" "is null" "= :price_charged"] - and i.price_name [ec_decode $price_name "" "is null" "= :price_name"] - group by s.shipment_date, s.carrier, s.tracking_number, s.shipment_id, s.shippable_p - " { + from ec_items i, ec_shipments s + where i.order_id = :order_id + and i.shipment_id = s.shipment_id + and i.product_id = :product_id + and i.color_choice [ec_decode $color_choice "" "is null" "= :color_choice"] + and i.size_choice [ec_decode $size_choice "" "is null" "= :size_choice"] + and i.style_choice [ec_decode $style_choice "" "is null" "= :style_choice"] + and i.price_charged [ec_decode $price_charged "" "is null" "= :price_charged"] + and i.price_name [ec_decode $price_name "" "is null" "= :price_name"] + group by s.shipment_date, s.carrier, s.tracking_number, s.shipment_id, s.shippable_p" { - if { ![empty_string_p $shipment_date] } { - set to_append_to_shipment_list "      $n_items [ec_decode $shippable_p "t" "shipped" "fullfilled"] on [util_AnsiDatetoPrettyDate $shipment_date]" + if { ![empty_string_p $shipment_date] } { + set to_append_to_shipment_list "      $n_items [ec_decode $shippable_p "t" "shipped" "fullfilled"] on [util_AnsiDatetoPrettyDate $shipment_date]" if { ![empty_string_p $carrier] } { append to_append_to_shipment_list " via $carrier" } - if { ![empty_string_p $tracking_number] } { + if { ![empty_string_p $tracking_number] } { if { ([string tolower $carrier] == "fedex" || [string range [string tolower $carrier] 0 2] == "ups") } { append to_append_to_shipment_list " (track)" - } else { - append to_append_to_shipment_list " (tracking # $tracking_number)" - } + } else { + append to_append_to_shipment_list " (tracking # $tracking_number)" + } } lappend shipment_list $to_append_to_shipment_list } } return "[join $shipment_list "
    "]" } -#### -#### obsoleted and subsited by www/product-file/index.vuh -#### -### ad_proc ec_return_product_file { } "Returns a file for the product in the calling url." { -### -### # Get file_path from url -### set is_url [ad_conn url] -### set e_url [ad_conn extra_url] -### set f [ad_conn file] -### set p [ad_conn path_info] -### ns_log debug is_url $is_url e_url $e_url f $f p $p -### set re {product-file/([^/]+/[^/]+/[^/]+)$} -### set re [ec_url]$re -### regexp $re $is_url match file_path -### # take any ..'s out of file_path -### regsub -all {\.\.} $file_path "" file_path -### set full_path "[ec_data_directory][ec_product_directory]$file_path" -### -### ns_returnfile 200 [ns_guesstype $full_path] $full_path -### } -### -### ad_register_proc GET /product-file/* ec_return_product_file - # Returns HTML and JavaScript for a selection widget and a button # which will insert canned responses into a text area. # Takes a database handle, the name associated with a form, @@ -1359,10 +1398,6 @@ if {![empty_string_p [ns_conn form]]} {export_entire_form_as_url_vars} else {concat ""} } -ad_proc ec_use_cybercash_p {} {Should we use cybercash? Use ad_parameter UseCyberCashP and default value 1 to find out.} { - return [ad_parameter -package_id [ec_id] UseCyberCashP ecommerce 1] -} - ### concatenate two pieces of a url. Gets number of /s right. ad_proc -private ec_url_concat {a b} { joins a & b, ensuring that the right number of slashes are present @@ -1422,21 +1457,24 @@ ad_proc -private ec_create_new_session_if_necessary { {more_url_vars_exported ""} {cookie_requirement "cookies_are_required"} -} { Create a new session if needed } { +} { + Create a new session if needed +} { uplevel "set _ec_more_url_vars_exported \"$more_url_vars_exported\"" uplevel "set _ec_cookie_requirement \"$cookie_requirement\"" + # DanW's suggestion - upvar __sql sql - set sql [db_map insert_user_session_sql] + uplevel { if { $user_session_id == 0 } { if {![info exists usca_p]} { - # first time we've seen this visitor - # no previous attempt made + # First time we've seen this visitor no previous + # attempt made. - set user_session_id [db_nextval "ec_user_session_sequence"] + set user_session_id [db_nextval ec_user_session_sequence] + ## use ACS 4 faster sessions ## set user_session_id [ad_conn session_id] @@ -1446,8 +1484,11 @@ # we should be able to get rid of this in ACS 4, but # we need to examine longevity of ad_sessions - # DanW's suggestion ------------v - db_dml insert_user_session $__sql + db_dml insert_user_session " + insert into ec_user_sessions + (user_session_id, ip_address, start_time, http_user_agent) + values + (:user_session_id, :ip_address, current_timestamp, :http_user_agent)" set cookie_name user_session_id set cookie_value $user_session_id @@ -1458,15 +1499,17 @@ append final_page "&" $_ec_more_url_vars_exported } - # it would probably be good to add max_age as a parameter - # in the future + # It would probably be good to add max_age as a + # parameter in the future + ad_set_cookie -replace "t" -path "/" user_session_id $cookie_value ad_returnredirect $final_page template::adp_abort } else { - # usca_p has been set, but user id is still 0! So, cookies haven't been set! - # visitor has been here before - # previous attempt made + + # usca_p has been set, but user id is still 0! So, + # cookies haven't been set! visitor has been here + # before previous attempt made if {[string compare $_ec_cookie_requirement "cookies_are_required"] ==0} { @@ -1479,22 +1522,20 @@ } elseif {[string compare $_ec_cookie_requirement "cookies_are_not_required"] == 0} { # For this page continue + ns_log debug "ec_create_session cookies are off but that's okay, they aren't required" } elseif {[string compare $_ec_cookie_requirement "shopping_cart_required"] == 0} { - ad_return_error "No Cart Found" "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_return_error "No Cart Found" " +

    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]

    " } else { ad_return_error "bug" "we should never get here" Index: openacs-4/packages/ecommerce/tcl/ecommerce-procs.xql =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/ecommerce/tcl/ecommerce-procs.xql,v diff -u -r1.5 -r1.6 --- openacs-4/packages/ecommerce/tcl/ecommerce-procs.xql 22 Oct 2001 08:02:10 -0000 1.5 +++ openacs-4/packages/ecommerce/tcl/ecommerce-procs.xql 26 May 2002 04:36:49 -0000 1.6 @@ -1,414 +1,357 @@ + - - - - select package_id from apm_packages - where package_key = 'ecommerce' - - - + + + select package_id from apm_packages + where package_key = 'ecommerce' + + + + + + select subcategory_id + from ec_subcategories + where category_id = :category_id + and subcategory_id in ([join $subcategory_list ", "]) + order by subcategory_name + + - - - - - select subcategory_id from ec_subcategories where category_id = :category_id and subcategory_id in ([join $subcategory_list ", "]) order by subcategory_name - - - + + + select category_name + from ec_categories + where category_id = :category_id + + - - - - - select category_name from ec_categories where category_id = :category_id - - - + + + select category_name + from ec_categories + where category_id = :category_id + + - - - - - select category_name from ec_categories where category_id = :category_id - - - + + + select subcategory_name + from ec_subcategories + where subcategory_id = :subcategory_id + + - - - - - select subcategory_name from ec_subcategories where subcategory_id = :subcategory_id - - - + + + select subsubcategory_name + from ec_subsubcategories + where subcategory_id = :subcategory_id + and subsubcategory_id in ([join $subsubcategory_list ","]) + order by subsubcategory_name + + - - - - - select subsubcategory_name from ec_subsubcategories where subcategory_id = :subcategory_id and subsubcategory_id in ([join $subsubcategory_list ","]) order by subsubcategory_name - - - + + + select product_name + from ec_products + where product_id = :product_id + + - - - - - select product_name from ec_products where product_id = :product_id - - - + + + select subcategory_id + from ec_subsubcategories + where subsubcategory_id = :subsubcategory_id + + - - - - - select subcategory_id from ec_subsubcategories where subsubcategory_id = :subsubcategory_id - - - + + + select category_id + from ec_subcategories + where subcategory_id = :subcategory_id + + - - - - - select category_id from ec_subcategories where subcategory_id = :subcategory_id - - - + + + select category_name + from ec_categories + where category_id = :category_id + + - - - - select category_name from ec_categories where category_id = :category_id - - + + + select subcategory_name + from ec_subcategories + where subcategory_id = :subcategory_id + + - - - - select subcategory_name from ec_subcategories where subcategory_id = :subcategory_id - - + + + select subsubcategory_name + from ec_subsubcategories + where subsubcategory_id = :subsubcategory_id + + - - - - select subsubcategory_name from ec_subsubcategories where subsubcategory_id = :subsubcategory_id - - + + + select category_id + from ec_subcategories + where subcategory_id = :subcategory_id + + - - - - - select category_id from ec_subcategories where subcategory_id = :subcategory_id - - - + + + select category_name + from ec_categories + where category_id = :category_id + + - - - - select category_name from ec_categories where category_id = :category_id - - + + + select subcategory_name + from ec_subcategories + where subcategory_id = :subcategory_id + + - - - - select subcategory_name from ec_subcategories where subcategory_id = :subcategory_id - - + + + select category_name + from ec_categories + where category_id = :category_id + + - - - - select category_name from ec_categories where category_id = :category_id - - + + + select category_id + from ec_category_product_map + where product_id = :product_id + + - - - - - select category_id from ec_category_product_map where product_id = :product_id - - - + + + select s.subcategory_id + from ec_subcategory_product_map m, ec_subcategories s + where m.subcategory_id = s.subcategory_id + and s.category_id = :category_id + and m.product_id = :product_id + + - - - - - select s.subcategory_id - from ec_subcategory_product_map m, - ec_subcategories s - where m.subcategory_id = s.subcategory_id - and s.category_id = :category_id - and m.product_id = :product_id - - - + + + select ss.subsubcategory_id + from ec_subsubcategory_product_map m, ec_subsubcategories ss + where m.subsubcategory_id = ss.subsubcategory_id + and ss.subcategory_id = :subcategory_id + and m.product_id = :product_id + + - - - - - select ss.subsubcategory_id - from ec_subsubcategory_product_map m, - ec_subsubcategories ss - where m.subsubcategory_id = ss.subsubcategory_id - and ss.subcategory_id = :subcategory_id - and m.product_id = :product_id - - - + + + select p.product_id, p.product_name + from ec_products_displayable p, ec_product_links l + where l.product_a = :product_id + and l.product_b = p.product_id + + - - - - - select p.product_id, p.product_name from ec_products_displayable p, ec_product_links l where l.product_a = :product_id and l.product_b = p.product_id - - - + + + select publication, author_name, review_date, review + from ec_product_reviews + where product_id = :product_id + and display_p = 't' + + - - - - - select publication, author_name, review_date, review from ec_product_reviews where product_id = :product_id and display_p = 't' - - - + + + select avg(rating) + from ec_product_comments + where product_id = :product_id + and approved_p = 't' + + - - - - - select avg(rating) from ec_product_comments where product_id = :product_id and approved_p = 't' - - - + + + select count(*) + from ec_product_comments + where product_id = :product_id + and (approved_p='t' [ec_decode [util_memoize {ad_parameter -package_id [ec_id] ProductCommentsNeedApprovalP ecommerce} [ec_cache_refresh]] "0" "or approved_p is null" ""]) + + - - - - - select count(*) from ec_product_comments where product_id = :product_id and (approved_p='t' [ec_decode [util_memoize {ad_parameter -package_id [ec_id] ProductCommentsNeedApprovalP ecommerce} [ec_cache_refresh]] "0" "or approved_p is null" ""]) - - - + + + select category_id, category_name + from ec_categories + order by sort_key + + - - - - - select category_id, category_name from ec_categories order by sort_key - - - + + + select user_id as correct_user_id + from ec_orders + where order_id = :order_id + + - - - - - select user_id as correct_user_id from ec_orders where order_id = :order_id - - - + + + select o.confirmed_date, o.creditcard_id, o.shipping_method, + u.email, o.shipping_address as shipping_address_id, c.billing_address as billing_address_id + from ec_orders o + left join cc_users u on (o.user_id = u.user_id) + left join ec_creditcards c on (o.creditcard_id = c.creditcard_id) + where o.order_id = :order_id + + - - - + + + 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 + + - select eco.confirmed_date, eco.creditcard_id, eco.shipping_method, - u.email, - eca.line1, eca.line2, eca.city, eca.usps_abbrev, eca.zip_code, eca.country_code, - eca.full_state_name, eca.attn, eca.phone, eca.phone_time - from ec_orders eco - LEFT JOIN cc_users u on (eco.user_id = u.user_id) - LEFT JOIN ec_addresses eca on (eco.shipping_address = eca.address_id) - where eco.order_id = :order_id - - - + + + select i.price_charged, i.price_name, 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_charged, i.price_name, i.color_choice, i.size_choice, i.style_choice + + - - - - - 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 - - - + + + select i.price_charged, i.price_name, 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_charged, i.price_name, i.color_choice, i.size_choice, i.style_choice + + - - - - - select i.price_charged, i.price_name, 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_charged, i.price_name, i.color_choice, i.size_choice, i.style_choice - - - + + + select count(*) + from $item_view + where order_id = :order_id + + - - - - - select i.price_charged, i.price_name, 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_charged, i.price_name, i.color_choice, i.size_choice, i.style_choice - - - + + + select o.order_id, o.confirmed_date, o.order_state + from ec_orders o + where o.user_id = :user_id + order by o.order_id + + - - - - select count(*) from $item_view where order_id = :order_id - - + + + select * + from ec_product_purchase_comb + where product_id = :product_id + + - - - - - select o.order_id, o.confirmed_date, o.order_state - from ec_orders o - where o.user_id = :user_id - order by o.order_id - - - + + + select product_name + from ec_products + where product_id = :product_id + + - - - - - select * from ec_product_purchase_comb where product_id = :product_id - - - + + + select product_name + from ec_products + where product_id = :product_id + + - - - - - select product_name from ec_products where product_id = :product_id - - - + + + select s.shipment_date, s.carrier, s.tracking_number, s.shipment_id, s.shippable_p, count(*) as n_items + from ec_items i, ec_shipments s + where i.order_id = :order_id + and i.shipment_id = s.shipment_id + and i.product_id = :product_id + and i.color_choice [ec_decode $color_choice "" "is null" "= :color_choice"] + and i.size_choice [ec_decode $size_choice "" "is null" "= :size_choice"] + and i.style_choice [ec_decode $style_choice "" "is null" "= :style_choice"] + and i.price_charged [ec_decode $price_charged "" "is null" "= :price_charged"] + and i.price_name [ec_decode $price_name "" "is null" "= :price_name"] + group by s.shipment_date, s.carrier, s.tracking_number, s.shipment_id, s.shippable_p + + - - - - - select product_name from ec_products where product_id = :product_id - - - + + + select response_id, one_line, response_text + from ec_canned_responses + order by one_line + + - - - - - select s.shipment_date, s.carrier, s.tracking_number, s.shipment_id, s.shippable_p, count(*) as n_items - from ec_items i, - ec_shipments s - where i.order_id = :order_id - and i.shipment_id = s.shipment_id - and i.product_id = :product_id - and i.color_choice [ec_decode $color_choice "" "is null" "= :color_choice"] - and i.size_choice [ec_decode $size_choice "" "is null" "= :size_choice"] - and i.style_choice [ec_decode $style_choice "" "is null" "= :style_choice"] - and i.price_charged [ec_decode $price_charged "" "is null" "= :price_charged"] - and i.price_name [ec_decode $price_name "" "is null" "= :price_name"] - group by s.shipment_date, s.carrier, s.tracking_number, s.shipment_id, s.shippable_p - - - + + + select c.user_class_name, m.user_class_approved_p, c.user_class_id + from ec_user_classes c, ec_user_class_user_map m + where m.user_id = :user_id + and m.user_class_id = c.user_class_id + order by c.user_class_id + + - - - - - select response_id, one_line, response_text - from ec_canned_responses - order by one_line - - - + + + update ec_user_sessions + set user_id = :user_id + where user_session_id = :user_session_id + + - - - - - select c.user_class_name, m.user_class_approved_p, c.user_class_id - from ec_user_classes c, ec_user_class_user_map m - where m.user_id = :user_id - and m.user_class_id = c.user_class_id - order by c.user_class_id - - - + + + select state_name + from us_states + where abbrev = :usps_abbrev + + - - - - - update ec_user_sessions - set user_id = :user_id - where user_session_id = :user_session_id - - - - - - - - - select state_name from us_states where abbrev =:usps_abbrev - - - - - - - - - select default_name from countries where iso=:country_code - - - - - + + + select default_name + from countries + where iso = :country_code + + + Index: openacs-4/packages/ecommerce/tcl/ecommerce-scheduled-procs-oracle.xql =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/ecommerce/tcl/ecommerce-scheduled-procs-oracle.xql,v diff -u -r1.2 -r1.3 --- openacs-4/packages/ecommerce/tcl/ecommerce-scheduled-procs-oracle.xql 18 Jul 2001 23:46:14 -0000 1.2 +++ openacs-4/packages/ecommerce/tcl/ecommerce-scheduled-procs-oracle.xql 26 May 2002 04:36:49 -0000 1.3 @@ -1,246 +1,227 @@ - oracle8.1.6 + + oracle + 8.1.6 + - - - - select order_id, ec_order_cost(order_id) as total_order_price - from ec_orders + + + select o.order_id, ec_order_cost(o.order_id) as total_order_price, + f.transaction_id, f.inserted_date, f.transaction_amount, + c.creditcard_type as card_type, p.first_names || ' ' || p.last_name as card_name, + c.creditcard_number as card_number, substring(creditcard_expire for 2) as card_exp_month, substring(creditcard_expire from 4 for 2) as card_exp_year, c.creditcard_type, + a.zip_code as billing_zip, + a.line1 as billing_address, + a.city as billing_city, + coalesce(a.usps_abbrev, a.full_state_name) as billing_state, + a.country_code as billing_country + from ec_orders o, ec_financial_transactions f, ec_creditcards c, persons p , ec_addresses a where order_state = 'confirmed' and (sysdate - confirmed_date) > 1/96 + and f.failed_p = 'f' + and f.order_id = o.order_id + and f.creditcard_id = c.creditcard_id + and c.user_id = p.person_id + and c.billing_address = a.address_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) + + - - - - - insert into ec_problems_log - (problem_id, problem_date, problem_details, order_id) - values - (ec_problem_id_sequence.nextval, sysdate, :problem_details, :order_id) - - - - - - - - - select g.gift_certificate_id, t.transaction_id - from ec_gift_certificates g, ec_financial_transactions t - where g.gift_certificate_id=t.gift_certificate_id - and g.gift_certificate_state = 'confirmed' + + + select g.gift_certificate_id, f.transaction_id, f.transaction_amount, f.inserted_date, + c.creditcard_type, c.creditcard_number as card_number, c.creditcard_expire as card_expiration, + p.first_names || ' ' || p.last_name as card_name, + a.zip_code as billing_zip, + a.line1 as billing_address, + a.city as billing_city, + coalesce(a.usps_abbrev, a.full_state_name) as billing_state, + a.country_code as billing_country + from ec_gift_certificates g, ec_financial_transactions f, ec_creditcards c, persons p, ec_addresses a + where g.gift_certificate_state = 'confirmed' and (sysdate - g.issue_date) > 1/96 + and f.failed_p = 'f' + and g.gift_certificate_id = f.gift_certificate_id + and f.creditcard_id = c.creditcard_id + and c.user_id = p.person_id + and c.billing_address = a.address_id + + - - + + + update ec_financial_transactions + set transaction_id = :pgw_transaction_id, authorized_date=sysdate, + to_be_captured_p='t' + where transaction_id = :transaction_id + + + + + + update ec_gift_certificates + set authorized_date = sysdate, + gift_certificate_state = 'authorized' + where gift_certificate_id = :gift_certificate_id + + - - - - - update ec_financial_transactions - set authorized_date=sysdate, - to_be_captured_p='t' - 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_gift_certificates - set authorized_date = sysdate, - gift_certificate_state = :cc_result - where gift_certificate_id = :gift_certificate_id - - - + + + update ec_orders + set order_state='expired', expired_date=sysdate + where order_state='in_basket' + and sysdate-in_basket_date > :cart_duration + + + + + + update ec_items + set item_state='expired', expired_date=sysdate + where item_state='in_basket' + and order_id in (select order_id from ec_orders where order_state='expired') + + + + + + update ec_creditcards + set creditcard_number=null + where creditcard_id in (select unique c.creditcard_id + from ec_creditcards c, ec_orders o + where c.creditcard_id = o.creditcard_id + and c.creditcard_number is not null + and 0=(select count(*) + from ec_orders o2 + where o2.creditcard_id=c.creditcard_id + and o2.order_state not in ('fulfilled','returned','void','expired')) + and 0=(select count(*) + from ec_financial_transactions f + where f.transaction_type = 'refund' + and f.creditcard_id = c.creditcard_id + and refunded_date is null)) + + + + + + select f.transaction_id, f.order_id, f.transaction_amount, f.to_be_captured_date, + p.first_names || ' ' || p.last_name as card_name, + c.creditcard_expire as card_expiration, c.creditcard_number as card_number, c.creditcard_type, + a.zip_code as billing_zip, + a.line1 as billing_address, + a.city as billing_city, + coalesce(a.usps_abbrev, a.full_state_name) as billing_state, + a.country_code as billing_country + from ec_financial_transactions f, ec_creditcards c, persons p, ec_addresses a + where to_be_captured_p='t' + and sysdate-to_be_captured_date > 1/48 + and authorized_date is null + and f.failed_p='f' + and f.creditcard_id=c.creditcard_id + and c.user_id=p.person_id + and c.billing_address = a.address_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_orders set order_state='expired', expired_date=sysdate where order_state='in_basket' and sysdate-in_basket_date > [util_memoize {ad_parameter -package_id [ec_id] CartDuration ecommerce} [ec_cache_refresh]] - - - - - - - update ec_items set item_state='expired', expired_date=sysdate where item_state='in_basket' and order_id in (select order_id from ec_orders where order_state='expired') - - - - - - - - select transaction_id, order_id from ec_financial_transactions - where to_be_captured_p='t' - and sysdate-to_be_captured_date > 1/48 - and authorized_date is null - and failed_p='f' - - - - - - - - - insert into ec_problems_log - (problem_id, problem_date, problem_details, order_id) - values - (ec_problem_id_sequence.nextval, sysdate, 'invalid input to ec_creditcard_authorization in ec_unauthorized_transactions', :order_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 authorized_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=: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 settled_date=sysdate where transaction_id=:transaction_id - - - - - - - select case when sign(1 - ((sysdate-marked_date)/2)) = -1 then 1 else 0 end from ec_financial_transactions 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) - - - - - - - - - select transaction_id, order_id from ec_financial_transactions - where transaction_type='refund' - and sysdate - inserted_date > 1/48 - and refunded_date is null - and failed_p='f' - - - - - - - - update ec_financial_transactions set refunded_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 refunded_date=sysdate where transaction_id=:transaction_id - - - - - - - update ec_financial_transactions set refund_settled_date=sysdate where transaction_id=:transaction_id - - - - - - - select case when sign(1 - ((sysdate-refunded_date)/2)) = -1 then 1 else 0 end from ec_financial_transactions where transaction_id=:transaction_id - - - - - - + + + update ec_financial_transactions + set transaction_id = :pgw_transaction_id, authorized_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) - - - + (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=:transaction_id + + + + + + select f.transaction_id, f.order_id, f.transaction_amount, f.to_be_captured_date, + p.first_names || ' ' || p.last_name as card_name, + c.creditcard_number as card_number, c.creditcard_type, c.creditcard_expire as card_expiration, + a.zip_code as billing_zip, + a.line1 as billing_address, + a.city as billing_city, + coalesce(a.usps_abbrev, a.full_state_name) as billing_state, + a.country_code as billing_country + from ec_financial_transactions f, ec_creditcards c, persons p, ec_addresses a + where transaction_type='refund' + and sysdate-to_be_captured_date > 1/48 + and f.refunded_date is null + and f.failed_p='f' + and f.creditcard_id=c.creditcard_id + and c.user_id=p.person_id + and c.billing_address = a.address_id + + + + + + update ec_financial_transactions + set refunded_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 transaction_id = :pgw_transaction_id, refunded_date=sysdate + where transaction_id=:transaction_id + + + Index: openacs-4/packages/ecommerce/tcl/ecommerce-scheduled-procs-postgresql.xql =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/ecommerce/tcl/ecommerce-scheduled-procs-postgresql.xql,v diff -u -r1.5 -r1.6 --- openacs-4/packages/ecommerce/tcl/ecommerce-scheduled-procs-postgresql.xql 24 Nov 2001 03:50:55 -0000 1.5 +++ openacs-4/packages/ecommerce/tcl/ecommerce-scheduled-procs-postgresql.xql 26 May 2002 04:36:49 -0000 1.6 @@ -1,132 +1,148 @@ - postgresql7.1 + + postgresql + 7.1 + - + - select order_id, ec_order_cost(order_id) as total_order_price - from ec_orders + select o.order_id, ec_order_cost(o.order_id) as total_order_price, + f.transaction_id, f.inserted_date, f.transaction_amount, + c.creditcard_type as card_type, p.first_names || ' ' || p.last_name as card_name, + c.creditcard_number as card_number, substring(creditcard_expire for 2) as card_exp_month, substring(creditcard_expire from 4 for 2) as card_exp_year, c.creditcard_type, + a.zip_code as billing_zip, + a.line1 as billing_address, + a.city as billing_city, + coalesce(a.usps_abbrev, a.full_state_name) as billing_state, + a.country_code as billing_country + from ec_orders o, ec_financial_transactions f, ec_creditcards c, persons p , ec_addresses a where order_state = 'confirmed' and (current_timestamp - confirmed_date) > timespan_days(1/96::float) + and f.failed_p = 'f' + and f.order_id = o.order_id + and f.creditcard_id = c.creditcard_id + and c.user_id = p.person_id + and c.billing_address = a.address_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) - - + + - select g.gift_certificate_id, t.transaction_id - from ec_gift_certificates g, ec_financial_transactions t - where g.gift_certificate_id=t.gift_certificate_id - and g.gift_certificate_state = 'confirmed' + select g.gift_certificate_id, f.transaction_id, f.transaction_amount, f.inserted_date, + c.creditcard_type, c.creditcard_number as card_number, substring(creditcard_expire for 2) as card_exp_month, substring(creditcard_expire from 4 for 2) as card_exp_year, + p.first_names || ' ' || p.last_name as card_name, + a.zip_code as billing_zip, + a.line1 as billing_address, + a.city as billing_city, + coalesce(a.usps_abbrev, a.full_state_name) as billing_state, + a.country_code as billing_country + from ec_gift_certificates g, ec_financial_transactions f, ec_creditcards c, persons p, ec_addresses a + where g.gift_certificate_state = 'confirmed' and (current_timestamp - g.issue_date) > timespan_days(1/96::float) + and f.failed_p = 'f' + and g.gift_certificate_id = f.gift_certificate_id + and f.creditcard_id = c.creditcard_id + and c.user_id = p.person_id + and c.billing_address = a.address_id - + update ec_financial_transactions - set authorized_date=current_timestamp, - to_be_captured_p='t' + set transaction_id = :pgw_transaction_id, authorized_date=current_timestamp, to_be_captured_p='t' where transaction_id = :transaction_id - + update ec_gift_certificates - set authorized_date = current_timestamp, - gift_certificate_state = :cc_result + set authorized_date = current_timestamp, gift_certificate_state = 'authorized' where gift_certificate_id = :gift_certificate_id - + - update ec_orders set order_state='expired', expired_date=current_timestamp where order_state='in_basket' and current_timestamp-in_basket_date > timespan_days([util_memoize {ad_parameter -package_id [ec_id] CartDuration ecommerce} [ec_cache_refresh]]::float) - - - - - - update ec_items set item_state='expired', expired_date=current_timestamp where item_state='in_basket' and order_id in (select order_id from ec_orders where order_state='expired') - - - - - - select transaction_id, order_id from ec_financial_transactions - where to_be_captured_p='t' - and current_timestamp-to_be_captured_date > timespan_days(1/48::float) - and authorized_date is null - and failed_p='f' - - - - - insert into ec_problems_log (problem_id, problem_date, problem_details, order_id) values - (ec_problem_id_sequence.nextval, current_timestamp, 'invalid input to ec_creditcard_authorization in ec_unauthorized_transactions', :order_id) + (ec_problem_id_sequence.nextval, current_timestamp, :problem_details, :order_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_orders + set order_state='expired', expired_date=current_timestamp + where order_state='in_basket' + and current_timestamp-in_basket_date > timespan_days(:cart_duration::float) - + - update ec_financial_transactions set authorized_date=current_timestamp where transaction_id=:transaction_id + update ec_items + set item_state='expired', expired_date=current_timestamp + where item_state='in_basket' and order_id in (select order_id + from ec_orders + where order_state='expired') - - + - 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_creditcards + set creditcard_number=null + where creditcard_id in (select distinct c.creditcard_id + from ec_creditcards c, ec_orders o + where c.creditcard_id = o.creditcard_id + and c.creditcard_number is not null + and 0=(select count(*) + from ec_orders o2 + where o2.creditcard_id=c.creditcard_id + and o2.order_state not in ('fulfilled','returned','void','expired')) + and 0=(select count(*) + from ec_financial_transactions f + where f.transaction_type = 'refund' + and f.creditcard_id = c.creditcard_id + and refunded_date is null)) - - + - update ec_financial_transactions set marked_date=current_timestamp where transaction_id=:transaction_id + select f.transaction_id, f.order_id, f.transaction_amount, f.to_be_captured_date, + p.first_names || ' ' || p.last_name as card_name, + substring(creditcard_expire for 2) as card_exp_month, substring(creditcard_expire from 4 for 2) as card_exp_year, c.creditcard_number as card_number, c.creditcard_type, + a.zip_code as billing_zip, + a.line1 as billing_address, + a.city as billing_city, + coalesce(a.usps_abbrev, a.full_state_name) as billing_state, + a.country_code as billing_country + from ec_financial_transactions f, ec_creditcards c, persons p, ec_addresses a + where to_be_captured_p='t' + and current_timestamp-to_be_captured_date > timespan_days(1/48::float) + and authorized_date is null + and f.failed_p='f' + and f.creditcard_id=c.creditcard_id + and c.user_id=p.person_id + and c.billing_address = a.address_id - - - - update ec_financial_transactions set refunded_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) - - - insert into ec_problems_log @@ -135,87 +151,67 @@ (ec_problem_id_sequence.nextval, current_timestamp, :problem_details, :order_id) - - - - update ec_financial_transactions set settled_date=current_timestamp where transaction_id=:transaction_id - - - - + - select case when marked_date + '2 days'::interval < now() then 1 else 0 end from ec_financial_transactions where transaction_id=:transaction_id + update ec_financial_transactions + set transaction_id = :pgw_transaction_id, authorized_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) - - - + - select transaction_id, order_id from ec_financial_transactions - where transaction_type='refund' - and current_timestamp - inserted_date > timespan_days(1/48::float) - and refunded_date is null - and failed_p='f' - - - - - - update ec_financial_transactions set refunded_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 refunded_date=current_timestamp where transaction_id=:transaction_id + update ec_financial_transactions + set marked_date=current_timestamp, transaction_id = :pgw_transaction_id + where transaction_id=:transaction_id - - + + - update ec_financial_transactions set refund_settled_date=current_timestamp where transaction_id=:transaction_id + select f.transaction_id, f.order_id, f.transaction_amount, f.to_be_captured_date, + p.first_names || ' ' || p.last_name as card_name, + c.creditcard_number as card_number, c.creditcard_type, substring(creditcard_expire for 2) as card_exp_month, substring(creditcard_expire from 4 for 2) as card_exp_year, + a.zip_code as billing_zip, + a.line1 as billing_address, + a.city as billing_city, + coalesce(a.usps_abbrev, a.full_state_name) as billing_state, + a.country_code as billing_country + from ec_financial_transactions f, ec_creditcards c, persons p, ec_addresses a + where transaction_type = 'refund' + and f.refunded_date is null + and f.failed_p='f' + and f.creditcard_id = c.creditcard_id + and c.user_id = p.person_id + and c.billing_address = a.address_id + and current_timestamp-to_be_captured_date > timespan_days(1/48::float) - + - select case when refunded_date + '2 days'::interval < now() then 1 else 0 end from ec_financial_transactions 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) - - + + - 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 transaction_id = :pgw_transaction_id, refunded_date=current_timestamp + where transaction_id=:transaction_id Index: openacs-4/packages/ecommerce/tcl/ecommerce-scheduled-procs.tcl =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/ecommerce/tcl/ecommerce-scheduled-procs.tcl,v diff -u -r1.7 -r1.8 --- openacs-4/packages/ecommerce/tcl/ecommerce-scheduled-procs.tcl 31 Jan 2002 22:43:54 -0000 1.7 +++ openacs-4/packages/ecommerce/tcl/ecommerce-scheduled-procs.tcl 26 May 2002 04:36:49 -0000 1.8 @@ -5,792 +5,1175 @@ Other ecommerce procedures can be found in ecommerce-*.tcl Procedures: + ec_calculate_product_purchase_combinations - ec_sweep_for_cybercash_zombies - ec_sweep_for_cybercash_zombie_gift_certificates + ec_sweep_for_payment_zombies + ec_sweep_for_payment_zombie_gift_certificates ec_send_unsent_new_order_email ec_send_unsent_new_gift_certificate_order_email ec_send_unsent_gift_certificate_recipient_email ec_delayed_credit_denied ec_expire_old_carts ec_remove_creditcard_data - financial transaction procedures: - ec_unauthorized_transactions - to_be_captured_date is over 1/2 hr old and authorized_date is null - ec_unmarked_transactions - to_be_captured_p is 't' and authorized_date is not null and marked_date is null - ec_unsettled_transactions - marked_date is non-null and settled_date is null - ec_unrefunded_transactions - transaction_type is 'refund' and inserted_date is over 1/2 hr old and refunded_date is null - ec_unrefund_settled_transactions - refunded_date is non-null and refund_settled_date is null + Financial transaction procedures: - I'll run this nightly so that calculations of popular product - combinations don't have to be done each time a product's page is - accessed. I will actually look at all orders, not just orders which - have been confirmed, so that there will be more data (so this isn't - *technically* a calculation of people who bought this product also - bought these products, because the buying didn't have to take place, - only the placing into the cart). + ec_unauthorized_transactions - to_be_captured_date is over 1/2 hr old + and authorized_date is null + ec_unmarked_transactions - to_be_captured_p is 't' + and authorized_date is not null + and marked_date is null + + ec_unrefunded_transactions - transaction_type is 'refund' + and inserted_date is over 1/2 hr old + and refunded_date is null + @author Eve Andersson (eveander@arsdigita.com) @creation-date April 1999 - @cvs-id ecommerce-scheduled-procs.tcl,v 3.6.2.4 2000/08/17 17:37:16 seb Exp @author ported by Jerry Asher (jerry@theashergroup.com) + @author revised by Bart Teeuwisse + @revision-date March 2002 + } -ad_proc ec_calculate_product_purchase_combinations {} { finds product purchase combinations } { - # for each product, I want to find other products that are items of - # orders with the same user id +ad_proc ec_calculate_product_purchase_combinations { +} { + Find product purchase combinations and store those in + ec_product_purchase_comb. + + This procedure runs nightly so that calculations of popular product + combinations don't have to be done each time a product's page is + accessed. The procedure looks at all orders, not just orders which + have been confirmed, so that there will be more data. *Technically* + the calculation isn't a calculation of people who bought this + product also bought these products, because the buying didn't have + to take place. Placing products into the cart is sufficient to be + included in the calculation. + +} { + + # For each product find other products that are items of orders + # with the same user_id. + db_foreach products_select "select product_id from ec_products" { set correlated_product_counter 0 set insert_cols [list] set insert_vals [list] set update_items [list] - db_foreach correlated_products_select { - select i2.product_id as correlated_product_id, - count(*) as n_product_occurrences - from ec_items i2 - where i2.order_id in (select o2.order_id - from ec_orders o2 - where o2.user_id in (select user_id - from ec_orders o - where o.order_id in (select i.order_id - from ec_items i - where product_id = :product_id))) - and i2.product_id <> :product_id + db_foreach correlated_products_select " + select i2.product_id as correlated_product_id, count(*) as n_product_occurrences + from ec_items i2 + where i2.order_id in (select o2.order_id + from ec_orders o2 + where o2.user_id in (select user_id + from ec_orders o + where o.order_id in (select i.order_id + from ec_items i + where product_id = :product_id))) + and i2.product_id <> :product_id group by i2.product_id - order by n_product_occurrences desc - } { + order by n_product_occurrences desc" { if { $correlated_product_counter >= 5 } { break } - # I don't know whether it will be an update or insert + + # Unknown at this point whether it will be an update or + # insert. + lappend insert_cols "product_$correlated_product_counter" lappend insert_vals $correlated_product_id lappend update_items "product_$correlated_product_counter = $correlated_product_id" incr correlated_product_counter } - if { [db_string product_purchase_comb_select "select count(*) from ec_product_purchase_comb where product_id=:product_id"] == 0 } { + if { [db_string product_purchase_comb_select " + select count(*) + from ec_product_purchase_comb + where product_id=:product_id"] == 0 } { if { [llength $insert_cols] > 0 } { + + # Insert the new product purchase combination. + db_dml product_purchase_comb_insert " insert into ec_product_purchase_comb (product_id, [join $insert_cols ", "]) values - (:product_id, [join $insert_vals ", "]) - " + (:product_id, [join $insert_vals ", "])" + } } else { if { [llength $update_items] > 0 } { + + # Update an existing product purchase combination. + db_dml product_purchase_comb_update " update ec_product_purchase_comb set [join $update_items ", "] - where product_id=:product_id - " + where product_id=:product_id" + } } } } -ad_proc ec_sweep_for_cybercash_zombies {} "Looks for confirmed orders that aren't either failed or authorized, i.e., where we didn't hear back from CyberCash" { - # cron job to dig up confirmed but not failed or authorized orders - # over 15 minutes old ("zombies") - # These only happen when we go off to CyberCash to authorize an order - # but either we got no response or the response indicated nothing about - # whether the card was actually valid. It also happens if the consumer - # pushes reload after the order is inserted into the database but - # before it goes through to CyberCash. - # - # OVERALL STRATEGY - # (1) query CyberCash to see if they have a record of the order - # (2) if CyberCash has the record and it was successful, - # update order_state to authorized_plus/minus_avs - # (3) if CyberCash doesn't have the order or it was inconclusive, - # retry order - # (a) if successful, update order_state to authorized_*_avs - # (b) if inconclusive, leave in this state - # (c) if a definite failure, change order_state failed_authorization - # (it will later be moved back to in_basket by ec_delayed_credit_denied) +ad_proc ec_sweep_for_payment_zombies { +} { + Cron job to dig up confirmed orders over 15 minutes old ("zombies") + that did not fail and haven't been authorized . + + These only happen when there is no response from the payment + gateway when authorizing an order or the response indicated + nothing about whether the card was actually valid. + + It also happens if the consumer pushes reload after the order + is inserted into the database but before it goes through to + the payment gateway. + + OVERALL STRATEGY + + (1) If the authorization was successful, update order_state to + authorized - ns_log Notice "ec_sweep_for_cybercash_zombies starting" + (2) If the response was inconclusive, leave the order in this state. - # Note that the outer loop uses $db2, so use $db within it - db_foreach confirmed_orders_select { - select order_id, ec_order_cost(order_id) as total_order_price - from ec_orders - where order_state = 'confirmed' - and (sysdate - confirmed_date) > 1/96 - } { - ns_log Notice "ec_sweep_for_cybercash_zombies working on order $order_id" - - if { $total_order_price == 0 } { - set auth_status_is_now "success" - } else { - set transaction_id [db_string transaction_id_select { - select max(transaction_id) - from ec_financial_transactions - where order_id = :order_id - }] + (3) If the retry failed definitely, change order_state to + failed_authorization (it will later be moved back to in_basket + by ec_delayed_credit_denied) + +} { + + # Lookup the selected currency. + + set currency [ad_parameter Currency ecommerce] + + # Lookup the selected payment gateway + + set payment_gateway [ad_parameter PaymentGateway -default [ad_parameter -package_id [ec_id] PaymentGateway]] + if {[empty_string_p $payment_gateway] } { + ns_log warning "ec_sweep_for_payment_zombies: No payment gateway has been selected." + return + } else { + if {![acs_sc_binding_exists_p "PaymentGateway" $payment_gateway]} { + ns_log warning "ec_sweep_for_payment_zombies: Payment gateway $payment_gateway is not bound to the Payment Service Contract." + return + } + } + + # Select the transaction of all orders that have been confirmed + # over 15 minutes ago. These orders should have reached either an + # authorized state or failure state if the credit card + # authorization failed. Orders that are still in the confirmed + # state need to be reprocessed. At this stage there is a one on + # one relationship between transactions and orders. + + db_foreach transactions_select " + select o.order_id, ec_order_cost(o.order_id) as total_order_price, + f.transaction_id, f.inserted_date, f.transaction_amount, c.creditcard_type as card_type, + p.first_names || ' ' || p.last_name as card_name, + c.creditcard_number as card_number, substring(creditcard_expire for 2) as card_exp_month, substring(creditcard_expire from 4 for 2) as card_exp_year, c.creditcard_type, + a.zip_code as billing_zip, + a.line1 as billing_address, + a.city as billing_city, + coalesce(a.usps_abbrev, a.full_state_name) as billing_state, + a.country_code as billing_country + from ec_orders o, ec_financial_transactions f, ec_creditcards c, persons p + where order_state = 'confirmed' + and (sysdate - confirmed_date) > 1/96 + and f.failed_p = 'f' + and f.order_id = o.order_id + and f.creditcard_id = c.creditcard_id + and c.user_id = p.person_id + and c.billing_address = a.address_id" { + + # Log the orders that are being processed. + + ns_log notice "ec_sweep_for_payment_zombies working on transaction $transaction_id" - # Query CyberCash: - set cc_args [ns_set new] - ns_set put $cc_args "order-id" "$transaction_id" - ns_set put $cc_args "txn-type" "auth" + # If the order amount is 0 (zero) then there is thus no need + # to contact the payment gateway. Record an instant success. + + if { $total_order_price == 0 } { + + # Update the status of the order to authorized - set ttcc_output [ec_talk_to_cybercash "query" $cc_args] + ec_update_state_to_authorized $order_id + + } else { + + # Convert the one digit creditcard abbreviation to the + # standardized name of the card. + + set card_type [ec_pretty_creditcard_type $creditcard_type] + + # Connect to the payment gateway to authorize the transaction. + + array set response [acs_sc_call "PaymentGateway" "Authorize" \ + [list $transaction_id \ + $transaction_amount \ + $card_type \ + $card_number \ + $card_exp_month \ + $card_exp_year \ + $card_name \ + $billing_address \ + $billing_city \ + $billing_state \ + $billing_zip \ + $billing_country] \ + $payment_gateway] - set txn_status [ns_set get $ttcc_output "txn_status"] - - if { [regexp {success} $txn_status] } { - set auth_status_is_now "success" - } elseif { [empty_string_p $txn_status] || [regexp {failure} $txn_status] } { - # Retry the authorization - set new_cc_status [ec_creditcard_authorization $order_id] - if { $new_cc_status == "authorized_plus_avs" || $new_cc_status == "authorized_minus_avs" } { - set auth_status_is_now "success" - } elseif { $new_cc_status == "failed_authorization" } { - set auth_status_is_now "failure" - } else { - set auth_status_is_now "lack_of_success" - if { $new_cc_status == "invalid_input" } { - ns_log Notice "invalid input to ec_creditcard_authorization in ec_sweep_for_cybercash_zombies " - } - } - } elseif { [regexp {pending} $txn_status] } { - # We need to retry the auth using the API call "retry" - - set cc_args_2 [ns_set new] - ns_set put $cc_args_2 "order-id" "$transaction_id" - ns_set put $cc_args_2 "txn-type" "auth" - - set ttcc_output_2 [ec_talk_to_cybercash "retry" $cc_args_2] - - if { [regexp {success} [ns_set get $ttcc_output_2 "txn_status"]] } { - set auth_status_is_now "success" - } else { - set auth_status_is_now "lack_of_success" - # This proc won't do anything with it in this case. It'll - # be caught next time around (ec_creditcard_authorization - # knows how to interpret the various failure messages). - } - } else { - # weird result, which we don't know what to do with. We should - # just leave the order_state alone and let it be subjected to this - # proc again in another half-hour, by which time things may have - # cleared up. - - set auth_status_is_now "unknown" + # Extract response_code, reason and the gateway transaction id + # from the response. The response_code values are defined in + # payment-gateway/tcl/payment-gateway-init.tcl. The reason is a + # human readable description of the response and the + # transaction id is the ID as returned by the payment gateway. - set problem_details "Strange CyberCash result when querying about auth: [ns_set get $ttcc_output_2 "txn_status"]" - - db_dml problems_log_insert { - insert into ec_problems_log - (problem_id, problem_date, problem_details, order_id) - values - (ec_problem_id_sequence.nextval, sysdate, :problem_details, :order_id) - } - } - # end of non-free order section - } - - # If the auth_status_is_now is "success" or "failure", then we want to - # update the order state. Otherwise, the order - # stays in the confirmed state. - - if { $auth_status_is_now == "success" } { - if { ![ec_use_cybercash_p] } { - # ignore cybercash and assume credit card is completely authorized - set new_order_state "authorized_plus_avs" - } elseif { $total_order_price > 0 } { - # get avs code from CyberCash log for most recent row containing this - # order_id - db_1row avs_code_select { - select avs_code - from ec_cybercash_log - where transaction_id = :transaction_id - and avs_code != '' - and txn_attempted_time = (select MAX(txn_attempted_time) - from ec_cybercash_log log2 - where log2.transaction_id = :transaction_id) - } - if { [ec_avs_acceptable_p $avs_code] == 1 } { - set new_order_state "authorized_plus_avs" - } else { - set new_order_state "authorized_minus_avs" - } - } else { - set new_order_state "authorized_plus_avs" - } - # update the order_state - ec_update_state_to_authorized $order_id [ec_decode $new_order_state "authorized_plus_avs" "t" "f"] - } elseif { $auth_status_is_now == "failure" } { - # this will get changed to in_basket by the ec_delayed_credit_denied proc - set new_order_state "failed_authorization" - db_dml order_state_update "update ec_orders set order_state=:new_order_state where order_id=:order_id" - } - } + set response_code $response(response_code) + set reason $response(reason) + set pgw_transaction_id $response(transaction_id) - ns_log Notice "ec_sweep_for_cybercash_zombies finishing" + # Interpret the response_code. + + switch -exact $response_code { + + "failure" - + "not_supported" - + "not_implemented" - + default { + + # The payment gateway rejected to authorize the + # transaction, can not authorize any transaction + # or the gateway returned an unknown + # response_code. Fail the authorization to be on + # the safe side. + + # Set the order status to + # failed_authorization. Later the proc + # ec_delayed_credit_denied will change the status + # to in_basket. + + db_dml order_failure_update " + update ec_orders + set order_state = 'failed_authorization' + where order_id = :order_id" + + db_dml transaction_failure_update " + update ec_financial_transactions + set failed_p = 't' + where transaction_id = :transaction_id" + } + + "failure-retry" { + + # The response_code is failure-retry, this means + # there was a temporary failure that can be + # retried. Fail the transaction however, if the + # order was confirmed a while ago (as defined in + # package parameter PaymentRetryPeriod) the + # temporary failure turns out to be less + # 'temporary'. + + if { [expr [dt_interval_check $inserted_date [clock format [clock seconds] -format "%D %H:%M:%S"]] / (60 * 60) ] > \ + [ad_parameter PaymentRetryPeriod -default [ad_parameter -package_id [ec_id] PaymentRetryPeriod]] } { + + db_transaction { + + # Flag the transaction as failed so that it + # will not be retried. Don't set the order to + # 'failed_authorization' as this is a + # technical problem with the payment gateway + # that the customer has nothing to do with. + + db_dml transaction_failure_update " + update ec_financial_transactions + set failed_p = 't' + where transaction_id = :transaction_id" + + # Log this failure in the problem log. + + set problem_details "Transaction $transaction_id failed to authorize due to repeated 'failure-retry' reponses from the payment gateway" + db_dml problems_log_insert " + insert into ec_problems_log + (problem_id, problem_date, problem_details, order_id) + values + (ec_problem_id_sequence.nextval, sysdate, :problem_details, :order_id)" + } + + } else { + + # Leave the order as is so that the order will + # be retried the next time this procedure is + # run. + + } + } + + "success" { + + # The payment gateway authorized the transaction. + # Update the status of the order to + # authorized. And update the transaction_id to the + # id returned by the payment gateway. + + ec_update_state_to_authorized $order_id + db_dml update_transaction_id " + update ec_financial_transactions + set transaction_id = :pgw_transaction_id + where transaction_id = :transaction_id" + + } + } + } + } } -ad_proc ec_sweep_for_cybercash_zombie_gift_certificates {} "Looks for confirmed gift certificates that aren't either failed or authorized, i.e., where we didn't hear back from CyberCash" { - # cron job to dig up confirmed but not failed or authorized gift certificates - # over 15 minutes old ("zombies") - # These only happen when we go off to CyberCash to authorize a transaction - # but either we got no response or the response indicated nothing about - # whether the card was actually valid. It can also happen if the consumer - # pushes reload after the gift certificate is inserted into the database but - # before it goes through to CyberCash. - # - # This is similar to ec_sweep_for_cybercash_zombies except that inconclusiveness - # is not tolerated in the case of gift certificates. If it's inconclusive we - # fail it and send a note telling them to reorder. - # - # OVERALL STRATEGY - # (1) query CyberCash to see if they have a record of the transaction - # (2) if CyberCash has the record and it was successful, - # update gift_certificate_state to authorized_plus/minus_avs - # (3) if CyberCash doesn't have the transaction or it was inconclusive, - # retry order - # (a) if successful, update gift_certificate_state to authorized_*_avs - # (c) if inconclusive or failure, change gift_certificate_state failed_authorization +ad_proc ec_sweep_for_payment_zombie_gift_certificates { +} { - ns_log Notice "ec_sweep_for_cybercash_zombie_gift_certificates starting" + Looks for confirmed gift certificates that aren't either failed + or authorized, i.e., where we didn't hear back from the payment + cron job to dig up confirmed but not failed or authorized gift + certificates over 15 minutes old ("zombies"). + + These only happen when authorizing a transaction returned + failure-retry, : an inconclusive failure. In other words the + response indicated nothing about whether the card was actually + valid. + + It can also happen if the consumer pushes reload after the gift + certificate is inserted into the database but before it goes + through to the payment gateway. + + This proc is similar to ec_sweep_for_payment_zombies except that + inconclusiveness is not tolerated in the case of gift + certificates. If the response from the payment gateway is + inconclusive fail the transaction and send a note to the user to + reorder. + +} { - db_foreach gift_certificate_select { - select g.gift_certificate_id, t.transaction_id - from ec_gift_certificates g, ec_financial_transactions t - where g.gift_certificate_id=t.gift_certificate_id - and g.gift_certificate_state = 'confirmed' - and (sysdate - g.issue_date) > 1/96 - } { - ns_log Notice "ec_sweep_for_cybercash_zombies working on order $order_id" - - # there's a 1-1 correspondence between user-purchased gift certificates and - # financial transactions - set transaction_id [db_string transaction_id_select "select transaction_id from ec_financial_transactions where gift_certificate_id=:gift_certificate_id"] - - # Query CyberCash: - set cc_args [ns_set new] - ns_set put $cc_args "order-id" "$transaction_id" - ns_set put $cc_args "txn-type" "auth" - - set ttcc_output [ec_talk_to_cybercash "query" $cc_args] - - set txn_status [ns_set get $ttcc_output "txn_status"] - set avs_code [ns_set get $ttcc_output "avs_code"] + # Lookup the selected currency. - if { [empty_string_p $txn_status] } { - # no response; inconclusive=failure for gift certificates - set cybercash_status "failure" - } elseif { $txn_status == "success" || $txn_status == "success-duplicate" } { - set cybercash_status "success" - } elseif { $txn_status == "failure-q-or-cancel" || $txn_status == "pending" } { - # we'll retry once - ns_log Notice "Retrying failure-q-or-cancel gift certificate # $gift_certificate_id (transaction # $transaction_id)" - set cc_args [ns_set new] - ns_set put $cc_args "txn-type" "auth" - ns_set put $cc_args "order-id" "$transaction_id" + set currency [ad_parameter Currency ecommerce] + + # Lookup the selected payment gateway + + set payment_gateway [ad_parameter PaymentGateway -default [ad_parameter -package_id [ec_id] PaymentGateway]] + if {[empty_string_p $payment_gateway] } { + ns_log warning "ec_sweep_for_payment_zombie_gift_certificates: No payment gateway has been selected." + return + } else { + if {![acs_sc_binding_exists_p "PaymentGateway" $payment_gateway]} { + ns_log warning "ec_sweep_for_payment_zombie_gift_certificates: Payment gateway $payment_gateway is not bound to the Payment Service Contract." + return + } + } + + # Select all gift certificates that have been confirmed over 15 + # minutes ago. These certificates should have reached either an + # authorized state or failure state if the credit card + # authorization failed. Certificates that are still in the + # confirmed state need to be reprocessed. There's a one on one + # correspondence between user-purchased gift certificates and + # transactions. + + db_foreach transactions_select " + select g.gift_certificate_id, f.transaction_id, f.transaction_amount, f.inserted_date, + c.creditcard_type, c.creditcard_number as card_number, substring(creditcard_expire for 2) as card_exp_month, substring(creditcard_expire from 4 for 2) as card_exp_year, + p.first_names || ' ' || p.last_name as card_name, + a.zip_code as billing_zip, + a.line1 as billing_address, + a.city as billing_city, + coalesce(a.usps_abbrev, a.full_state_name) as billing_state, + a.country_code as billing_country + from ec_gift_certificates g, ec_financial_transactions f, ec_creditcards c, persons p + where g.gift_certificate_state = 'confirmed' + and (sysdate - g.issue_date) > 1/96 + and g.gift_certificate_id = f.gift_certificate_id + and f.creditcard_id = c.creditcard_id + and c.user_id = p.person_id + and c.billing_address = a.address_id" { - set ttcc_output [ec_talk_to_cybercash "retry" $cc_args] - set txn_status [ns_set get $ttcc_output "txn_status"] - set errmsg [ns_set get $ttcc_output "errmsg"] - set avs_code [ns_set get $ttcc_output "avs_code"] + ns_log notice "ec_sweep_for_payment_zombies_gift_certificates working on transaction $transaction_id" + + # Convert the one digit creditcard abbreviation to the + # standardized name of the card. - if {[regexp {success} $txn_status]} { - set cybercash_status "success" - } else { - set cybercash_status "failure" - } - } else { - set cybercash_status "failure" - } + set card_type [ec_pretty_creditcard_type $creditcard_type] - # Now deal with the cybercash_status: - # 1. If success, update transaction and gift certificate to authorized, - # and send gift certificate order email - # 2. If failure, update gift certificate and transaction to failed, - # and send gift certificate order failure email - - if { $cybercash_status == "success" } { - if { [ ec_avs_acceptable_p $avs_code ] == 1 } { - set cc_result "authorized_plus_avs" - } else { - set cc_result "authorized_minus_avs" - } - # update transaction and gift certificate to authorized - # setting to_be_captured_p to 't' will cause ec_unmarked_transactions to come along and mark it for capture - db_dml financial_transactions_update { - update ec_financial_transactions - set authorized_date=sysdate, - to_be_captured_p='t' - where transaction_id = :transaction_id - } + # Connect to the payment gateway to authorize the transaction. - db_dml gift_certificate_state_update { - update ec_gift_certificates - set authorized_date = sysdate, - gift_certificate_state = :cc_result - where gift_certificate_id = :gift_certificate_id - } + array set response [acs_sc_call "PaymentGateway" "Authorize" \ + [list $transaction_id \ + $transaction_amount \ + $card_type \ + $card_number \ + $card_exp_month \ + $card_exp_year \ + $card_name \ + $billing_address \ + $billing_city \ + $billing_state \ + $billing_zip \ + $billing_country] \ + $payment_gateway] - # send gift certificate order email - ec_email_new_gift_certificate_order $gift_certificate_id + # Extract response_code, reason and the gateway transaction id + # from the response. The response_code values are defined in + # payment-gateway/tcl/payment-gateway-init.tcl. The reason is a + # human readable description of the response and the transaction + # id is the ID as returned by the payment gateway. - } else { - # we probably don't need to do this update of to_be_captured_p - # because no cron jobs distinguish between null and 'f' right - # now, but it doesn't hurt and it might alleviate someone's - # concern when they're looking at ec_financial_transactions and - # wondering whether they should be concerned that failed_p is - # 't' + set response_code $response(response_code) + set reason $response(reason) + set pgw_transaction_id $response(transaction_id) - db_dml financial_transactions_update_1 "update ec_financial_transactions set failed_p='t', to_be_captured_p='f' where transaction_id=:transaction_id" - db_dml gift_certificate_state_update_1 "update ec_gift_certificates set gift_certificate_state='failed_authorization' where gift_certificate_id=:gift_certificate_id" + # Interpret the response_code. - # send gift certificate order failure email - ec_email_gift_certificate_order_failure $gift_certificate_id - } - } + switch -exact $response_code { + + "failure" - + "failure-retry" - + "not_supported" - + "not_implemented" - + default { - ns_log Notice "ec_sweep_for_cybercash_zombie_gift_certificates finishing" + # The payment gateway rejected to authorize the + # transaction, can not authorize any transaction or the + # gateway returned an unknown response_code. Fail the + # authorization to be on the safe side. Update gift + # certificate and transaction to failed, and send a gift + # certificate order failure email to the user. + + # There is no immediate need to update of + # to_be_captured_p because no cron jobs distinguish + # between null and 'f' right now, but it doesn't hurt + # and it might alleviate someone's concern when they're + # looking at ec_financial_transactions and wondering + # whether they should be concerned that failed_p is 't' + + db_dml transaction_failure_update " + update ec_financial_transactions + set failed_p = 't', to_be_captured_p = 'f' + where transaction_id=:transaction_id" + + db_dml certificate_failure_update " + update ec_gift_certificates + set gift_certificate_state='failed_authorization' + where gift_certificate_id=:gift_certificate_id" + + # Send a gift certificate order failure email to the user. + + ec_email_gift_certificate_order_failure $gift_certificate_id + } + + "success" { + + # The payment gateway authorized the transaction. Update + # the transaction and gift certificate to authorized, + # and send a gift certificate order email to the user. + + # Update transaction and gift certificate to authorized + # setting to_be_captured_p to 't' will cause + # ec_unmarked_transactions to come along and mark it for + # capture + + db_dml transaction_success_update " + update ec_financial_transactions + set transaction_id = :pgw_transaction_id, authorized_date=sysdate, + to_be_captured_p='t' + where transaction_id = :transaction_id" + + db_dml certificate_success_update " + update ec_gift_certificates + set authorized_date = sysdate, + gift_certificate_state = 'authorized' + where gift_certificate_id = :gift_certificate_id" + + # Send out the gift certificate order email + + ec_email_new_gift_certificate_order $gift_certificate_id + } + } + } } -# this procedure is needed because new order email is only sent after -# the order is authorized and some authorizations occur when the user is -# not on the web site or execution of the thread on the site may -# terminate after the order is authorized but before the email is sent +ad_proc ec_send_unsent_new_order_email { +} { -ad_proc ec_send_unsent_new_order_email {} "Finds authorized orders for which confirmation email has not been sent, sends the email, and records that it has been sent." { - db_foreach unsent_orders_select { + Finds authorized orders for which confirmation email has not + been sent, sends the email, and records that it has been sent. + + This procedure is needed because new order email is only sent + after the order is authorized and some authorizations occur when + the user is not on the web site or execution of the thread on + the site may terminate after the order is authorized but before + the email is sent + +} { + db_foreach orders_select " select order_id from ec_orders o - where (order_state='authorized_plus_avs' or order_state='authorized_minus_avs') - and (0=(select count(*) from ec_automatic_email_log log where log.order_id=o.order_id and email_template_id=1)) - } { + where order_state='authorized' + and (0=(select count(*) + from ec_automatic_email_log log + where log.order_id=o.order_id and email_template_id=1))" { ec_email_new_order $order_id } } -# ec_send_unsent_new_gift_certificate_order_email -ad_proc ec_send_unsent_new_gift_certificate_order_email {} "Finds authorized_plus/minus_avs gift certificates for which confirmation email has not been sent, sends the email, and records that it has been sent." { +ad_proc ec_send_unsent_new_gift_certificate_order_email { +} { - db_foreach unsent_gift_certificate_email { + Finds authorized gift certificates for which confirmation email + has not been sent, sends the email, and records that it has been + sent. + +} { + + db_foreach certificates_select " select gift_certificate_id from ec_gift_certificates g - where (gift_certificate_state='authorized_plus_avs' or gift_certificate_state='authorized_minus_avs') - and (0=(select count(*) from ec_automatic_email_log log where log.gift_certificate_id=g.gift_certificate_id and email_template_id=4)) - } { + where gift_certificate_state='authorized' + and (0=(select count(*) + from ec_automatic_email_log log + where log.gift_certificate_id=g.gift_certificate_id + and email_template_id=4))" { ec_email_new_gift_certificate_order $gift_certificate_id } } -# ec_send_unsent_gift_certificate_recipient_email -ad_proc ec_send_unsent_gift_certificate_recipient_email {} "Finds authorized_plus/minus_avs gift certificates for which email has not been sent to the recipient, sends the email, and records that it has been sent." { - ns_log Notice "ec_send_unsent_gift_certificate_recipient_email starting" +ad_proc ec_send_unsent_gift_certificate_recipient_email {} { + + Finds authorized gift certificates for which email + has not been sent to the recipient, sends the email, and records + that it has been sent. - db_foreach unsent_gift_certificate_select { +} { + db_foreach certificates_select " select gift_certificate_id from ec_gift_certificates g - where (gift_certificate_state='authorized_plus_avs' or gift_certificate_state='authorized_minus_avs') - and (0=(select count(*) from ec_automatic_email_log log where log.gift_certificate_id=g.gift_certificate_id and email_template_id=5)) - } { + where gift_certificate_state='authorized' + and (0=(select count(*) + from ec_automatic_email_log log + where log.gift_certificate_id=g.gift_certificate_id + and email_template_id=5))" { ec_email_gift_certificate_recipient $gift_certificate_id } - - ns_log Notice "ec_send_unsent_gift_certificate_recipient_email ending" } -ad_proc ec_delayed_credit_denied {} { Sends "Credit Denied" email to consumers whose authorization was initially inconclusive and then failed, and then saves the order for them (so that consumer can go back to site and retry the authorization). +ad_proc ec_delayed_credit_denied { +} { + + Sends "Credit Denied" email to consumers whose authorization was + initially inconclusive and then failed, and then saves the order + for them (so that consumer can go back to site and retry the + authorization). + } { - ns_log Notice "ec_delayed_credit_denied starting" - set order_id_list [db_list denied_orders_select "select order_id from ec_orders where order_state='failed_authorization'"] + set order_id_list [db_list denied_orders_select " + select order_id + from ec_orders + where order_state='failed_authorization'"] foreach order_id $order_id_list { - ns_log Notice "working on order #$order_id" - # save this shopping cart for the user - db_dml order_state_update "update ec_orders set order_state='in_basket', saved_p='t' where order_id=:order_id" + ns_log notice "ec_delayed_credit_denied working on order #$order_id" + # Save this shopping cart for the user + + db_dml order_state_update " + update ec_orders + set order_state='in_basket', saved_p='t' + where order_id=:order_id" + ec_email_delayed_credit_denied $order_id } - - ns_log Notice "ec_delayed_credit_denied ending" } -ad_proc ec_expire_old_carts {} { expires old carts } { +ad_proc ec_expire_old_carts { +} { + + Expires old carts. + +} { + set cart_duration [ad_parameter -package_id [ec_id] CartDuration ecommerce] db_transaction { - db_dml expired_carts_update "update ec_orders set order_state='expired', expired_date=sysdate where order_state='in_basket' and sysdate-in_basket_date > [ad_parameter -package_id [ec_id] CartDuration ecommerce]" - db_dml item_state_update "update ec_items set item_state='expired', expired_date=sysdate where item_state='in_basket' and order_id in (select order_id from ec_orders where order_state='expired')" + db_dml expired_carts_update " + update ec_orders + set order_state='expired', expired_date=sysdate + where order_state='in_basket' + and sysdate-in_basket_date > :cart_duration" + db_dml item_state_update " + update ec_items + set item_state='expired', expired_date=sysdate + where item_state='in_basket' + and order_id in (select order_id + from ec_orders + where order_state='expired')" } } -ad_proc ec_remove_creditcard_data {} { remove credit card data } { - # if SaveCreditCardDataP=0 we should remove the creditcard_number for the cards whose numbers are - # no longer needed (i.e. all their orders are fulfilled, returned, void, or expired) +ad_proc ec_remove_creditcard_data { +} { + + Remove credit card number from ec_creditcards if package + parameter SaveCreditCardDataP = 0. Ec_remove_creditcard_data + removes only the credit card numbers for the cards whose numbers + are no longer needed (i.e. all their orders are fulfilled, + returned, void, or expired). The last four digits -also stored in + ec_creditcards- remain. + +} { if { [ad_parameter -package_id [ec_id] SaveCreditCardDataP ecommerce] == 0 } { - db_dml creditcard_update { + db_dml creditcard_update " update ec_creditcards set creditcard_number=null where creditcard_id in (select unique c.creditcard_id - from ec_creditcards c, ec_orders o - where c.creditcard_id = o.creditcard_id - and c.creditcard_number is not null - and 0=(select count(*) - from ec_orders o2 - where o2.creditcard_id=c.creditcard_id - and o2.order_state not in ('fulfilled','returned','void','expired'))) - } + from ec_creditcards c, ec_orders o + where c.creditcard_id = o.creditcard_id + and c.creditcard_number is not null + and 0=(select count(*) + from ec_orders o2 + where o2.creditcard_id=c.creditcard_id + and o2.order_state not in ('fulfilled','returned','void','expired')) + and 0=(select count(*) + from ec_financial_transactions + where transaction_type = 'refund' + and refunded_date is null))" } } -# to_be_captured_date is over 1/2 hr old and authorized_date is null -# this is similar to ec_sweep_for_cybercash_zombies except that in this -# case these are shipments that are unauthorized -ad_proc ec_unauthorized_transactions {} { searches for unauthorized transactions } { - db_foreach unauthorized_transactions_select { - select transaction_id, order_id from ec_financial_transactions +ad_proc ec_unauthorized_transactions { +} { + + Ec_unauthorized_transactions searches for unauthorized transactions + whose to_be_captured_date is over 1/2 hr old and authorized_date is + null this is similar to ec_sweep_for_payment_zombies except that in + this case these are shipments that are unauthorized. + +} { + + # Lookup the selected currency. + + set currency [ad_parameter Currency ecommerce] + + # Lookup the selected payment gateway + + set payment_gateway [ad_parameter PaymentGateway -default [ad_parameter -package_id [ec_id] PaymentGateway]] + if {[empty_string_p $payment_gateway]} { + ns_log warning "ec_unauthorized_transactions: No payment gateway has been selected." + return + } else { + if {![acs_sc_binding_exists_p "PaymentGateway" $payment_gateway]} { + ns_log warning "ec_unauthorized_transactions: Payment gateway $payment_gateway is not bound to the Payment Service Contract." + return + } + } + + db_foreach transactions_select " + select f.transaction_id, f.order_id, f.transaction_amount, f.to_be_captured_date, + p.first_names || ' ' || p.last_name as card_name, + substring(creditcard_expire for 2) as card_exp_month, substring(creditcard_expire from 4 for 2) as card_exp_year, c.creditcard_number as card_number, c.creditcard_type, + a.zip_code as billing_zip, + a.line1 as billing_address, + a.city as billing_city, + coalesce(a.usps_abbrev, a.full_state_name) as billing_state, + a.country_code as billing_country + from ec_financial_transactions f, ec_creditcards c, persons p, ec_addresses a where to_be_captured_p='t' and sysdate-to_be_captured_date > 1/48 and authorized_date is null and failed_p='f' - } { - ns_log Notice "ec_unauthorized_transactions working on transaction_id $transaction_id" + and f.creditcard_id=c.creditcard_id + and c.user_id=p.person_id + and c.billing_address = a.address_id" { - # Query CyberCash: - set cc_args [ns_set new] - ns_set put $cc_args "order-id" "$transaction_id" - ns_set put $cc_args "txn-type" "auth" + ns_log notice "ec_unauthorized_transactions working on transaction $transaction_id" - set ttcc_output [ec_talk_to_cybercash "query" $cc_args] + # Convert the one digit creditcard abbreviation to the + # standardized name of the card. - if { [regexp {success} [ns_set get $ttcc_output "txn_status"]] } { - set auth_status_is_now "success" - } elseif { [ns_set get $ttcc_output "txn_status"] == "" || [regexp {failure} [ns_set get $ttcc_output "txn_status"]] } { - # Retry the authorization - set new_cc_status [ec_creditcard_authorization $order_id $transaction_id] + set card_type [ec_pretty_creditcard_type $creditcard_type] + + # Connect to the payment gateway to authorize the transaction. + + array set response [acs_sc_call "PaymentGateway" "Authorize" \ + [list $transaction_id \ + $transaction_amount \ + $card_type \ + $card_number \ + $card_exp_month \ + $card_exp_year \ + $card_name \ + $billing_address \ + $billing_city \ + $billing_state \ + $billing_zip \ + $billing_country] \ + $payment_gateway] + + # Extract response_code, reason and the gateway transaction id + # from the response. The response_code values are defined in + # payment-gateway/tcl/payment-gateway-init.tcl. The reason is a + # human readable description of the response and the transaction + # id is the ID as returned by the payment gateway. + + set response_code $response(response_code) + set reason $response(reason) + set pgw_transaction_id $response(transaction_id) + + # Interpret the response_code. + + switch -exact $response_code { - if { $new_cc_status == "authorized_plus_avs" || $new_cc_status == "authorized_minus_avs" } { - set auth_status_is_now "success" - } elseif { $new_cc_status == "failed_authorization" } { - set auth_status_is_now "failure" - } else { - set auth_status_is_now "lack_of_success" - if { $new_cc_status == "invalid_input" } { - db_dml problems_log_insert { + "failure" - + "not_supported" - + "not_implemented" - + default { + + # The payment gateway rejected to authorize the + # transaction, can not authorize any transaction. + + # Flag the transaction as failed and log the problem + # in the ecommerce problem log for the administrator. + + db_transaction { + db_dml transaction_failed_update " + update ec_financial_transactions + set failed_p = 't' + where transaction_id = :transaction_id" + set problem_details "The authorization failed for transaction_id $transaction_id for the following reason: $reason" + db_dml problems_log_insert " insert into ec_problems_log (problem_id, problem_date, problem_details, order_id) values - (ec_problem_id_sequence.nextval, sysdate, 'invalid input to ec_creditcard_authorization in ec_unauthorized_transactions', :order_id) - } + (ec_problem_id_sequence.nextval, sysdate, :problem_details, :order_id)" } } - } elseif { [regexp {pending} [ns_set get $ttcc_output "txn_status"]] } { - # We need to retry the auth using the API call "retry" - set cc_args_2 [ns_set new] - ns_set put $cc_args_2 "order-id" "$transaction_id" - ns_set put $cc_args_2 "txn-type" "auth" - set ttcc_output_2 [ec_talk_to_cybercash "retry" $cc_args_2] - - if { [regexp {success} [ns_set get $ttcc_output_2 "txn_status"]] } { - set auth_status_is_now "success" - } else { - set auth_status_is_now "lack_of_success" - # This proc won't do anything with it in this case. It'll - # be caught next time around (ec_creditcard_authorization - # knows how to interpret the various failure messages). - } - } else { - # weird result, which we don't know what to do with. We should just leave - # the order_state alone and let it be subjected to this proc again in - # another half-hour, by which time things may have cleared up. - set auth_status_is_now "unknown" + "failure-retry" { - set problem_details "Strange CyberCash result when querying about auth: [ns_set get $ttcc_output_2 "txn_status"]" + # The response_code is failure-retry, this means there + # was a temporary failure that can be retried. Fail + # the transaction however, if the order was authorized + # a while ago (as defined in package parameter + # PaymentRetryPeriod) the temporary failure turns out + # to be less 'temporary'. - db_dml problems_insert { - insert into ec_problems_log - (problem_id, problem_date, problem_details, order_id) - values - (ec_problem_id_sequence.nextval, sysdate, :problem_details, :order_id) - } - } - # done determining auth_status - - # If the auth_status_is_now is "success" or "failure", then we want to - # update the transaction. Otherwise, it stays as it is. - - if { $auth_status_is_now == "success" } { - db_dml transaction_success_update "update ec_financial_transactions set authorized_date=sysdate where transaction_id=:transaction_id" - } elseif { $auth_status_is_now == "failure" } { - db_transaction { - db_dml transaction_failed_update "update ec_financial_transactions set failed_p='t' where transaction_id=:transaction_id" - set problem_details "The authorization failed for transaction_id $transaction_id." - db_dml problems_log_insert { - insert into ec_problems_log - (problem_id, problem_date, problem_details, order_id) - values - (ec_problem_id_sequence.nextval, sysdate, :problem_details, :order_id) + if { [expr [dt_interval_check $to_be_captured_date [clock format [clock seconds] -format "%D %H:%M:%S"]] / (60 * 60) ] > \ + [ad_parameter PaymentRetryPeriod -default [ad_parameter -package_id [ec_id] PaymentRetryPeriod]] } { + + db_transaction { + + # Flag the transaction as failed so that it + # will not be retried. + + db_dml transaction_failure_update " + update ec_financial_transactions + set failed_p = 't' + where transaction_id=:transaction_id" + + # Log this failure in the problem log. + + set problem_details "Transaction $transaction_id failed to mark due to repeated 'failure-retry' reponses from the payment gateway" + db_dml problems_log_insert " + insert into ec_problems_log + (problem_id, problem_date, problem_details, order_id) + values + (ec_problem_id_sequence.nextval, sysdate, :problem_details, :order_id)" + } + } else { + + # Leave the order as is so that the order will be + # retried the next time this procedure is run. + } } + + "success" { + + # The payment gateway authorized the + # transaction. Update the # transaction. + + db_dml transaction_success_update " + update ec_financial_transactions + set transaction_id = :pgw_transaction_id, authorized_date=sysdate + where transaction_id=:transaction_id" + } } } - - ns_log Notice "ec_unauthorized_transactions finishing" } -# to_be_captured_p is 't' and authorized_date is not null and marked_date is null -ad_proc ec_unmarked_transactions {} { unmarked transactions } { - ns_log Notice "ec_unmarked_transactions starting" +ad_proc ec_unmarked_transactions { +} { + + unmarked transactions + to_be_captured_p is 't' and authorized_date is not null and marked_date is null - db_foreach unmarked_transactions_select { - select transaction_id, order_id from ec_financial_transactions +} { + + # Lookup the selected currency. + + set currency [ad_parameter Currency ecommerce] + + # Lookup the selected payment gateway + + set payment_gateway [ad_parameter PaymentGateway -default [ad_parameter -package_id [ec_id] PaymentGateway]] + if {[empty_string_p $payment_gateway]} { + ns_log warning "ec_unmarked_transactions: No payment gateway has been selected." + return + } else { + if {![acs_sc_binding_exists_p "PaymentGateway" $payment_gateway]} { + ns_log warning "ec_unmarked_transactions: Payment gateway $payment_gateway is not bound to the Payment Service Contract." + return + } + } + + db_foreach transactions_select " + select f.transaction_id, f.order_id, f.transaction_amount, f.to_be_captured_date, + p.first_names || ' ' || p.last_name as card_name, + c.creditcard_number as card_number, c.creditcard_type, substring(creditcard_expire for 2) as card_exp_month, substring(creditcard_expire from 4 for 2) as card_exp_year, + a.zip_code as billing_zip, + a.line1 as billing_address, + a.city as billing_city, + coalesce(a.usps_abbrev, a.full_state_name) as billing_state, + a.country_code as billing_country + from ec_financial_transactions f, ec_creditcards c, persons p, ec_addresses a where to_be_captured_p='t' - and authorized_date is not null and marked_date is null - and failed_p='f' - } { - ns_log Notice "ec_unmarked_transactions working on transaction_id $transaction_id" + and f.failed_p='f' + and f.creditcard_id=c.creditcard_id + and c.user_id=p.person_id + and c.billing_address = a.address_id" { - set postauth_success [ec_creditcard_marking $transaction_id] - - if { $postauth_success != "success" } { + ns_log notice "ec_unmarked_transactions working on transaction $transaction_id" + + # Convert the one digit creditcard abbreviation to the + # standardized name of the card. + + set card_type [ec_pretty_creditcard_type $creditcard_type] + + # Connect to the payment gateway to authorize the transaction. + + array set response [acs_sc_call "PaymentGateway" "ChargeCard" \ + [list $transaction_id \ + $transaction_amount \ + $card_type \ + $card_number \ + $card_exp_month \ + $card_exp_year \ + $card_name \ + $billing_address \ + $billing_city \ + $billing_state \ + $billing_zip \ + $billing_country] \ + $payment_gateway] + + # Extract response_code, reason and the gateway transaction id + # from the response. The response_code values are defined in + # payment-gateway/tcl/payment-gateway-init.tcl. The reason is a + # human readable description of the response and the transaction + # id is the ID as returned by the payment gateway. + + set response_code $response(response_code) + set reason $response(reason) + set pgw_transaction_id $response(transaction_id) + + # Interpret the response_code. + + switch -exact $response_code { - # the error may be because the order was already marked, so check for that - set cc_args [ns_set new] - ns_set put $cc_args "order-id" "$transaction_id" - ns_set put $cc_args "txn-type" "postauth" - - set ttcc_output [ec_talk_to_cybercash "query" $cc_args] - - if { [regexp {success} [ns_set get $ttcc_output "txn_status"]] } { - db_dml financial_transaction_success_update "update ec_financial_transactions set marked_date=sysdate where transaction_id=:transaction_id" - } else { + "failure" - + "not_supported" - + "not_implemented" - + default { + + # The payment gateway rejected to post authorize the + # transaction, can not post authorize any + # transaction. Or the gateway returned an unknown + # response_code. + + # Flag the transaction as failed and log the problem + # in the ecommerce problem log for the administrator. + db_transaction { - db_dml financial_transaction_failed_update "update ec_financial_transactions set failed_p='t' where transaction_id=:transaction_id" - set problem_details "The marking failed for transaction_id $transaction_id." - db_dml problems_log_insert { + db_dml transaction_failed_update " + update ec_financial_transactions + set failed_p='t' + where transaction_id=:transaction_id" + set problem_details "The post authorization failed for transaction_id $transaction_id for the following reason: $reason" + db_dml problems_log_insert " insert into ec_problems_log (problem_id, problem_date, problem_details, order_id) values - (ec_problem_id_sequence.nextval, sysdate, :problem_details, :order_id) - } + (ec_problem_id_sequence.nextval, sysdate, :problem_details, :order_id)" } } - } else { - # postauth successful - db_dml financial_transactions_update "update ec_financial_transactions set marked_date=sysdate where transaction_id=:transaction_id" - } - } - ns_log Notice "ec_unmarked_transactions ending" -} + + "failure-retry" { -# marked_date is non-null and settled_date is null -# this should be run late at night because CyberCash settled marked transactions in the early night (before midnight) -# if it isn't settled 2 days after it's marked, failed_p is set to 't' and a row is added to the problems_log -ad_proc ec_unsettled_transactions {} { unsettled transactions } { - ns_log Notice "ec_unsettled_transactions starting" - - db_foreach unsettled_transactions_select { - select transaction_id, order_id from ec_financial_transactions - where marked_date is not null - and settled_date is null - and failed_p='f' - } { - ns_log Notice "ec_unsettled_transactions working on transaction_id $transaction_id" + # The response_code is failure-retry, this means there + # was a temporary failure that can be retried. Fail + # the transaction however, if the order was authorized + # a while ago (as defined in package parameter + # PaymentRetryPeriod) the temporary failure turns out + # to be less 'temporary'. - # query CyberCash - set cc_args [ns_set new] - ns_set put $cc_args "order-id" "$transaction_id" - ns_set put $cc_args "txn-type" "settled" - - set ttcc_output [ec_talk_to_cybercash "query" $cc_args] - if { [regexp {success} [ns_set get $ttcc_output "txn_status"]] } { - db_dml settled_date_update "update ec_financial_transactions set settled_date=sysdate where transaction_id=:transaction_id" - } else { - # see if it's been at least 2 days since the order was marked (otherwise, don't bother - # making a note of the failure yet; in my experience, there were a number of times - # when it took more than a day for us to find out that an order settled, with the delay - # perhaps due to CyberCash's nightly settlement not occurring or due to a communications - # failure between us and CyberCash) - - # to see if a > b, check the sign of (1 - (a/b)); if it's positive, then ab. I use this in the following decode to see - # whether (sysdate - marked_date) > 2. - - if { [db_string two_days_since_order_was_marked_p "select decode(sign(1 - ((sysdate-marked_date)/2)), -1, 1, 0) from ec_financial_transactions where transaction_id=:transaction_id"] } { - db_transaction { - db_dml transaction_failed_update "update ec_financial_transactions set failed_p='t' where transaction_id=:transaction_id" - set problem_details "The settlement failed for transaction_id $transaction_id even though it has been more than 2 days since the transaction was marked." - db_dml problems_log_insert { - insert into ec_problems_log - (problem_id, problem_date, problem_details, order_id) - values - (ec_problem_id_sequence.nextval, sysdate, :problem_details, :order_id) + if { [expr [dt_interval_check $to_be_captured_date [clock format [clock seconds] -format "%D %H:%M:%S"]] / (60 * 60) ] > \ + [ad_parameter PaymentRetryPeriod -default [ad_parameter -package_id [ec_id] PaymentRetryPeriod]] } { + + db_transaction { + + # Flag the transaction as failed so that it + # will not be retried. + + db_dml transaction_failure_update " + update ec_financial_transactions + set failed_p = 't' + where transaction_id=:transaction_id" + + # Log this failure in the problem log. + + set problem_details "Transaction $transaction_id failed to mark due to repeated 'failure-retry' reponses from the payment gateway" + db_dml problems_log_insert " + insert into ec_problems_log + (problem_id, problem_date, problem_details, order_id) + values + (ec_problem_id_sequence.nextval, sysdate, :problem_details, :order_id)" } + } else { + + # Leave the order as is so that the order will be + # retried the next time this procedure is run. + } } + + "success" { + + # The payment gateway approved the transaction. Update + # the transaction. The gateway returns a new + # transaction_id when ChargeCard resulted in a new + # transaction rather than the next step in processing + # an existing transaction. + + if { [empty_string_p $pgw_transaction_id] } { + set pgw_transaction_id $transaction_id + } + db_dml transaction_success_update " + update ec_financial_transactions + set transaction_id = :pgw_transaction_id, marked_date=sysdate + where transaction_id=:transaction_id" + } } } - ns_log Notice "ec_unsettled_transactions ending" } -# transaction_type is 'refund' and inserted_date is over 1/2 hr old and refunded_date is null -ad_proc ec_unrefunded_transactions {} { unrefunded transactions } { - ns_log Notice "ec_unrefunded_transactions starting" +ad_proc ec_unrefunded_transactions { +} { - db_foreach unrefunded_transactions_select { - select transaction_id, order_id from ec_financial_transactions - where transaction_type='refund' - and sysdate - inserted_date > 1/48 - and refunded_date is null - and failed_p='f' - } { - ns_log Notice "ec_unrefunded_transactions working on transaction_id $transaction_id" - - set return_success [ec_creditcard_return $transaction_id] - - if { $return_success != "success" } { + Unrefunded transactions. Transaction_type is 'refund' and + inserted_date is over 1/2 hr old and refunded_date is null + +} { + + # Lookup the selected currency. + + set currency [ad_parameter Currency ecommerce] + + # Lookup the selected payment gateway + + set payment_gateway [ad_parameter PaymentGateway -default [ad_parameter -package_id [ec_id] PaymentGateway]] + if {[empty_string_p $payment_gateway]} { + ns_log warning "ec_unrefunded_transactions: No payment gateway has been selected." + return + } else { + if {![acs_sc_binding_exists_p "PaymentGateway" $payment_gateway]} { + ns_log warning "ec_unrefunded_transactions: Payment gateway $payment_gateway is not bound to the Payment Service Contract." + return + } + } + + db_foreach transactions_select " + select f.transaction_id, f.order_id, f.transaction_amount, f.to_be_captured_date, c.creditcard_type as card_type, + p.first_names || ' ' || p.last_name as card_name, c.creditcard_number as card_number, + c.creditcard_expire as card_expiration, c.creditcard_type + a.zip_code as billing_zip, + a.line1 as billing_address, + a.city as billing_city, + nsvl(a.usps_abbrev, a.full_state_name) as billing_state, + a.country_code as billing_country + from ec_financial_transactions f, ec_creditcards c, persons p, ec_addresses a + where transaction_type = 'refund' + and f.refunded_date is null + and f.failed_p='f' + and f.creditcard_id = c.creditcard_id + and c.user_id = p.person_id + and c.billing_address = a.address_id + and sysdate-to_be_captured_date > 1/48" { + + ns_log notice "ec_unrefunded_transactions working on transaction $transaction_id" - # the error may be because the order was already marked, so check for that - set cc_args [ns_set new] - ns_set put $cc_args "order-id" "$transaction_id" - ns_set put $cc_args "txn-type" "markret" + # Convert the one digit creditcard abbreviation to the + # standardized name of the card. + + set card_type [ec_pretty_creditcard_type $creditcard_type] + + # Connect to the payment gateway to authorize the transaction. + + array set response [acs_sc_call "PaymentGateway" "Return" \ + [list $marked_transaction_id \ + $transaction_amount \ + $card_type \ + $card_number \ + $card_exp_month \ + $card_exp_year \ + $card_name \ + $billing_address \ + $billing_city \ + $billing_state \ + $billing_zip \ + $billing_country] \ + $payment_gateway] + + # Extract response_code, reason and the gateway transaction id + # from the response. The response_code values are defined in + # payment-gateway/tcl/payment-gateway-init.tcl. The reason is a + # human readable description of the response and the transaction + # id is the ID as returned by the payment gateway. + + set response_code $response(response_code) + set reason $response(reason) + set pgw_transaction_id $response(transaction_id) + + # Interpret the response_code. + + switch -exact $response_code { - set ttcc_output [ec_talk_to_cybercash "query" $cc_args] - - if { [regexp {success} [ns_set get $ttcc_output "txn_status"]] } { - db_dml financial_transactions_update "update ec_financial_transactions set refunded_date=sysdate where transaction_id=:transaction_id" - } else { + "failure" - + "not_supported" - + "not_implemented" - + default { + + # The payment gateway rejected to refund the + # transaction, can not refund any transactions. Or + # returned an unknown response_code. + + # Flag the transaction as failed and log the problem + # in the ecommerce problem log for the administrator. + db_transaction { - db_dml financial_transaction_failed_update "update ec_financial_transactions set failed_p='t' where transaction_id=:transaction_id" - set problem_details "The refund (the marking of it) failed for transaction_id $transaction_id." - db_dml problems_log_insert { + db_dml transaction_failed_update " + update ec_financial_transactions + set failed_p='t' + where transaction_id=:transaction_id" + set problem_details "The refund failed for transaction_id $transaction_id for the following reason: $reason" + db_dml problems_log_insert " insert into ec_problems_log (problem_id, problem_date, problem_details, order_id) values - (ec_problem_id_sequence.nextval, sysdate, :problem_details, :order_id) - } + (ec_problem_id_sequence.nextval, sysdate, :problem_details, :order_id)" } + } - } else { - # refund successful - db_dml financial_transaction_refund_update "update ec_financial_transactions set refunded_date=sysdate where transaction_id=:transaction_id" - } - } - ns_log Notice "ec_unrefunded_transactions ending" -} -# refunded_date is non-null and refund_settled_date is null -# yes, I know the name of this proc is gramatically iffy, but I want to be consistent -ad_proc ec_unrefund_settled_transactions {} { unrefunded settled transactions } { - ns_log Notice "ec_unrefund_settled_transactions starting" + "failure-retry" { - db_foreach unrefund_settled_transactions_select "select transaction_id, order_id from ec_financial_transactions - where refunded_date is not null - and refund_settled_date is null - and failed_p='f'" { - ns_log Notice "ec_unrefund_settled_transactions working on transaction_id $transaction_id" + # The response_code is failure-retry, this means there + # was a temporary failure that can be retried. Fail + # the transaction however, if the order was authorized + # a while ago (as defined in package parameter + # PaymentRetryPeriod) the temporary failure turns out + # to be less 'temporary'. - # query CyberCash - set cc_args [ns_set new] - ns_set put $cc_args "order-id" "$transaction_id" - ns_set put $cc_args "txn-type" "setlret" + if { [expr [dt_interval_check $to_be_captured_date [clock format [clock seconds] -format "%D %H:%M:%S"]] / (60 * 60) ] > \ + [ad_parameter PaymentRetryPeriod -default [ad_parameter -package_id [ec_id] PaymentRetryPeriod]] } { - set ttcc_output [ec_talk_to_cybercash "query" $cc_args] - if { [regexp {success} [ns_set get $ttcc_output "txn_status"]] } { - db_dml financial_transaction_refund_settled_update "update ec_financial_transactions set refund_settled_date=sysdate where transaction_id=:transaction_id" - } else { - # see if it's been at least 2 days since the order was marked (otherwise, don't bother - # making a note of the failure yet; in my experience, there were a number of times - # when it took more than a day for us to find out that a refund settled, with the delay - # perhaps due to CyberCash's nightly settlement not occurring or due to a communications - # failure between us and CyberCash) + db_transaction { - # to see if a > b, check the sign of (1 - (a/b)); if it's positive, then ab. I use this in the following decode to see - # whether (sysdate - refunded_date) > 2. + # Flag the transaction as failed so that it + # will not be retried. - if { [db_string two_days_since_order_was_refunded_p "select decode(sign(1 - ((sysdate-refunded_date)/2)), -1, 1, 0) from ec_financial_transactions where transaction_id=:transaction_id"] } { - db_transaction { - db_dml transaction_failed_update "update ec_financial_transactions set failed_p='t' where transaction_id=:transaction_id" - set problem_details "The refund settlement failed for transaction_id $transaction_id even though it has been more than 2 days since the transaction was marked refunded." - db_dml problems_log_insert "insert into ec_problems_log - (problem_id, problem_date, problem_details, order_id) - values - (ec_problem_id_sequence.nextval, sysdate, :problem_details, :order_id) - " + db_dml transaction_failure_update " + update ec_financial_transactions + set failed_p = 't' + where transaction_id=:transaction_id" + + # Log this failure in the problem log. + + set problem_details "Transaction $transaction_id failed to mark due to repeated 'failure-retry' reponses from the payment gateway" + db_dml problems_log_insert " + insert into ec_problems_log + (problem_id, problem_date, problem_details, order_id) + values + (ec_problem_id_sequence.nextval, sysdate, :problem_details, :order_id)" + } + } else { + + # Leave the order as is so that the order will be + # retried the next time this procedure is run. + + } + } + + "success" { + + # The payment gateway refunded the transaction. Update + # the transaction. + + db_dml transaction_success_update " + update ec_financial_transactions + set refunded_date=sysdate, transaction_id = :pgw_transaction_id + where transaction_id=:transaction_id" + } } - } } - } - ns_log Notice "ec_unrefund_settled_transactions ending" } -## Schedule these procedures +# Schedule these procedures if there is a binding with a payment +# service contract. -set ec_procs_scheduled_p 0 -set ep [ad_parameter -package_id [ec_id] EnabledP ecommerce 0] +if { [acs_sc_binding_exists_p "PaymentGateway" [ad_parameter PaymentGateway -default [ad_parameter -package_id [ec_id] PaymentGateway]]] } { -if { !$ec_procs_scheduled_p && $ep} { - set ec_procs_scheduled_p 1 - # Scheduled proc scheduling: - - # Nightly - # pi time + 1 = 4:14am EST = late in U.S., early in Europe + # Nightly pi time + 1 = 4:14am - ns_log Notice "scheduling ec_calculate_product_purchase_combinations" ns_schedule_daily -thread 4 14 ec_calculate_product_purchase_combinations - # A few times a day - # every three hours or so (slightly different intervals so they'll eventually space themselves out) + # A few times a day every three hours or so (slightly different + # intervals so they'll eventually space themselves out) set infrequent_base [expr 3 * 60 * 60] - ns_log Notice "scheduling ec_expire_old_carts" ad_schedule_proc -thread t [expr $infrequent_base + 0] ec_expire_old_carts - ns_log Notice "scheduling ec_unauthorized_transactions" ad_schedule_proc -thread t [expr $infrequent_base + 50] ec_unauthorized_transactions - ns_log Notice "scheduling ec_unmarked_transactions" ad_schedule_proc -thread t [expr $infrequent_base + 10] ec_unmarked_transactions - ns_log Notice "scheduling ec_unsettled_transactions" - ad_schedule_proc -thread t [expr $infrequent_base + 150] ec_unsettled_transactions - - ns_log Notice "scheduling ec_unrefunded_transactions" ad_schedule_proc -thread t [expr $infrequent_base + 200] ec_unrefunded_transactions - ns_log Notice "scheduling ec_unrefund_settled_transactions" - ad_schedule_proc -thread t [expr $infrequent_base + 250] ec_unrefund_settled_transactions + # Often, every 10 - 15 minutes - # Often - # every half hour or so - set frequent_base [expr 60 * 10] - ns_log Notice "scheduling ec_sweep_for_cybercash_zombies" - ad_schedule_proc -thread t [expr $frequent_base + 0] ec_sweep_for_cybercash_zombies + ad_schedule_proc -thread t [expr $frequent_base + 0] ec_sweep_for_payment_zombies - ns_log Notice "scheduling ec_sweep_for_cybercash_zombie_gift_certificates" - ad_schedule_proc -thread t [expr $frequent_base + 25] ec_sweep_for_cybercash_zombie_gift_certificates + ad_schedule_proc -thread t [expr $frequent_base + 25] ec_sweep_for_payment_zombie_gift_certificates - ns_log Notice "scheduling ec_send_unsent_new_order_email" ad_schedule_proc -thread t [expr $frequent_base + 50] ec_send_unsent_new_order_email - ns_log Notice "scheduling ec_delayed_credit_denied" ad_schedule_proc -thread t [expr $frequent_base + 100] ec_delayed_credit_denied - ns_log Notice "scheduling ec_remove_creditcard_data" ad_schedule_proc -thread t [expr $frequent_base + 150] ec_remove_creditcard_data - ns_log Notice "scheduling ec_send_unsent_new_gift_certificate_order_email" ad_schedule_proc -thread t [expr $frequent_base + 200] ec_send_unsent_new_gift_certificate_order_email - ns_log Notice "scheduling ec_send_unsent_gift_certificate_recipient_email" ad_schedule_proc -thread t [expr $frequent_base + 250] ec_send_unsent_gift_certificate_recipient_email } Index: openacs-4/packages/ecommerce/tcl/ecommerce-scheduled-procs.xql =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/ecommerce/tcl/ecommerce-scheduled-procs.xql,v diff -u -r1.4 -r1.5 --- openacs-4/packages/ecommerce/tcl/ecommerce-scheduled-procs.xql 19 Mar 2002 00:34:25 -0000 1.4 +++ openacs-4/packages/ecommerce/tcl/ecommerce-scheduled-procs.xql 26 May 2002 04:36:50 -0000 1.5 @@ -1,262 +1,173 @@ + - - + + select product_id from ec_products - - + + + + + + select i2.product_id as correlated_product_id, + count(*) as n_product_occurrences + from ec_items i2 + where i2.order_id in (select o2.order_id + from ec_orders o2 + where o2.user_id in (select user_id + from ec_orders o + where o.order_id in (select i.order_id + from ec_items i + where product_id = :product_id))) + and i2.product_id <> :product_id + group by i2.product_id + order by n_product_occurrences desc + + + + + + select count(*) + from ec_product_purchase_comb + where product_id = :product_id + + + + + + insert into ec_product_purchase_comb + (product_id, [join $insert_cols ", "]) + values + (:product_id, [join $insert_vals ", "]) + + + + + + update ec_product_purchase_comb + set [join $update_items ", "] + where product_id = :product_id + + + + + + update ec_orders + set order_state = 'failed_authorization' + 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', to_be_captured_p = 'f' + where transaction_id = :transaction_id + + + + + + update ec_gift_certificates + set gift_certificate_state = 'failed_authorization' + where gift_certificate_id = :gift_certificate_id + + + + + + select order_id + from ec_orders o + where order_state = 'authorized' + and (0 = (select count(*) + from ec_automatic_email_log log + where log.order_id = o.order_id and email_template_id = 1)) + + + + + + select gift_certificate_id + from ec_gift_certificates g + where gift_certificate_state = 'authorized' + and (0 = (select count(*) + from ec_automatic_email_log log + where log.gift_certificate_id = g.gift_certificate_id + and email_template_id = 4)) + + + + + + select gift_certificate_id + from ec_gift_certificates g + where gift_certificate_state = 'authorized' + and (0 = (select count(*) + from ec_automatic_email_log log + where log.gift_certificate_id = g.gift_certificate_id + and email_template_id = 5)) + + + + + + select order_id + from ec_orders + where order_state = 'failed_authorization' + + + + + + update ec_orders + set order_state = 'in_basket', saved_p = 't' + where order_id = :order_id + + - - - - - select i2.product_id as correlated_product_id, - count(*) as n_product_occurrences - from ec_items i2 - where i2.order_id in (select o2.order_id - from ec_orders o2 - where o2.user_id in (select user_id - from ec_orders o - where o.order_id in (select i.order_id - from ec_items i - where product_id = :product_id))) - and i2.product_id <> :product_id - group by i2.product_id - order by n_product_occurrences desc - - - - - - - - select count(*) from ec_product_purchase_comb where product_id=:product_id - - - - - - - - insert into ec_product_purchase_comb - (product_id, [join $insert_cols ", "]) - values - (:product_id, [join $insert_vals ", "]) - - - - - - - - - update ec_product_purchase_comb - set [join $update_items ", "] - where product_id=:product_id - - - - - - - - - select max(transaction_id) - from ec_financial_transactions - where order_id = :order_id - - - - - - - - - select avs_code - from ec_cybercash_log - where transaction_id = :transaction_id - and avs_code != '' - and txn_attempted_type != 'query' - and txn_attempted_time = (select MAX(txn_attempted_time) - from ec_cybercash_log log2 - where log2.transaction_id = :transaction_id) - - - - - - - - update ec_orders set order_state=:new_order_state where order_id=:order_id - - - - - - - select transaction_id from ec_financial_transactions where gift_certificate_id=:gift_certificate_id - - - - - - - update ec_financial_transactions set failed_p='t', to_be_captured_p='f' where transaction_id=:transaction_id - - - - - - - update ec_gift_certificates set gift_certificate_state='failed_authorization' where gift_certificate_id=:gift_certificate_id - - - - - - - - select order_id - from ec_orders o - where (order_state='authorized_plus_avs' or order_state='authorized_minus_avs') - and (0=(select count(*) from ec_automatic_email_log log where log.order_id=o.order_id and email_template_id=1)) - - - - - - - - - select gift_certificate_id - from ec_gift_certificates g - where (gift_certificate_state='authorized_plus_avs' or gift_certificate_state='authorized_minus_avs') - and (0=(select count(*) from ec_automatic_email_log log where log.gift_certificate_id=g.gift_certificate_id and email_template_id=4)) - - - - - - - - - select gift_certificate_id - from ec_gift_certificates g - where (gift_certificate_state='authorized_plus_avs' or gift_certificate_state='authorized_minus_avs') - and (0=(select count(*) from ec_automatic_email_log log where log.gift_certificate_id=g.gift_certificate_id and email_template_id=5)) - - - - - - - - select order_id from ec_orders where order_state='failed_authorization' - - - - - - - update ec_orders set order_state='in_basket', saved_p='t' where order_id=:order_id - - - - - - - - update ec_creditcards - set creditcard_number=null - where creditcard_id in (select unique c.creditcard_id - from ec_creditcards c, ec_orders o - where c.creditcard_id = o.creditcard_id - and c.creditcard_number is not null - and 0=(select count(*) - from ec_orders o2 - where o2.creditcard_id=c.creditcard_id - and o2.order_state not in ('fulfilled','returned','void','expired'))) - - - - - - - - update ec_financial_transactions set failed_p='t' where transaction_id=:transaction_id - - - - - - - - select transaction_id, order_id from ec_financial_transactions - where to_be_captured_p='t' - and authorized_date is not null - and marked_date is null - and failed_p='f' - - - - - - - - update ec_financial_transactions set failed_p='t' where transaction_id=:transaction_id - - - - - - - financial_transactions set marked_date=sysdate where transaction_id=:transaction_id - - - - - - - - select transaction_id, order_id from ec_financial_transactions - where marked_date is not null - and settled_date is null - and failed_p='f' - - - - - - - - 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 - - - - - - - select transaction_id, order_id from ec_financial_transactions - where refunded_date is not null - and refund_settled_date is null - and failed_p='f' - - - - - - - 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 + + + + + + select f.transaction_id, f.order_id, f.transaction_amount, f.to_be_captured_date, + p.first_names || ' ' || p.last_name as card_name, + c.creditcard_number as card_number, substring(creditcard_expire for 2) as card_exp_month, substring(creditcard_expire from 4 for 2) as card_exp_year, c.creditcard_type, + a.zip_code as billing_zip, + a.line1 as billing_address, + a.city as billing_city, + coalesce(a.usps_abbrev, a.full_state_name) as billing_state, + a.country_code as billing_country + from ec_financial_transactions f, ec_creditcards c, persons p, ec_addresses a + where to_be_captured_p = 't' + and marked_date is null + and f.failed_p = 'f' + and f.creditcard_id = c.creditcard_id + and c.user_id = p.person_id + and c.billing_address = a.address_id + + + + + + update ec_financial_transactions + set failed_p = 't' + where transaction_id = :transaction_id + + + Index: openacs-4/packages/ecommerce/tcl/ecommerce-state-changes-procs-oracle.xql =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/ecommerce/tcl/ecommerce-state-changes-procs-oracle.xql,v diff -u -r1.4 -r1.5 --- openacs-4/packages/ecommerce/tcl/ecommerce-state-changes-procs-oracle.xql 29 Jan 2002 00:11:46 -0000 1.4 +++ openacs-4/packages/ecommerce/tcl/ecommerce-state-changes-procs-oracle.xql 26 May 2002 04:36:50 -0000 1.5 @@ -1,118 +1,93 @@ - oracle8.1.6 + + oracle + 8.1.6 + - - - declare begin ec_reinst_gift_cert_on_order (:order_id); end; - - + + + declare + begin + ec_reinst_gift_cert_on_order (:order_id); + end; + + + + + + select ec_order_cost(:order_id) + from dual + + - - - - select ec_order_cost(:order_id) from dual - - + + + update ec_orders + set order_state='authorized', authorized_date=sysdate + where order_id=:order_id + + + + + + update ec_financial_transactions + set authorized_date=sysdate + where transaction_id=:transaction_id + + - - - - update ec_orders set order_state=:new_state, authorized_date=sysdate where order_id=:order_id - - - - - - update ec_financial_transactions set authorized_date=sysdate where transaction_id=:transaction_id - - - - - - - update ec_orders set order_state='confirmed', confirmed_date=sysdate where order_id=:order_id - - - - - - - select ec_order_cost(:order_id) from dual - - - - - - + + + update ec_orders + set order_state='confirmed', confirmed_date=sysdate + where order_id=:order_id + + + + + + select ec_order_cost(:order_id) + from dual + + + + + insert into ec_financial_transactions - (transaction_id, order_id, transaction_amount, transaction_type, inserted_date) - values - (:transaction_id, :order_id, :total_amount, 'charge', sysdate) - - - - - - - - select gift_certificate_id - from ec_gift_certificates_approved - where user_id=:user_id - and sysdate - expires < 0 - and amount_remaining_p = 't' - order by expires + (transaction_id, order_id, transaction_amount, transaction_type, inserted_date) + values + (:transaction_id, :order_id, :total_amount, 'charge', sysdate) + + - - - - - - - select ec_gift_certificate_balance(:user_id) from dual - - - - - - - select ec_order_amount_owed(:order_id) from dual - - - - - - - select gift_certificate_amount_left(:gift_certificate_id) from dual - - - - - - + + + select ec_order_amount_owed(:order_id) + from dual + + + + + + select gift_certificate_id, gift_certificate_amount_left(gift_certificate_id) as amount_available + from ec_gift_certificates_approved + where user_id = :user_id + and sysdate - expires < 0 + and amount_remaining_p = 't' + and gift_certificate_amount_left(gift_certificate_id) > 0 + order by expires + + + + + insert into ec_gift_certificate_usage (gift_certificate_id, order_id, amount_used, used_date) - VALUES - (:gift_certificate_id, :order_id, least(to_number(:gift_certificate_amount_left), - to_number(:amount_owed)), sysdate) - - - - - - - - select ec_gift_certificate_balance(:user_id) from dual - - - - - - - select ec_order_amount_owed(:order_id) from dual - - - - + values + (:gift_certificate_id, :order_id, least(to_number(:amount_available), to_number(:amount_owed)), sysdate) + + + Index: openacs-4/packages/ecommerce/tcl/ecommerce-state-changes-procs-postgresql.xql =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/ecommerce/tcl/ecommerce-state-changes-procs-postgresql.xql,v diff -u -r1.6 -r1.7 --- openacs-4/packages/ecommerce/tcl/ecommerce-state-changes-procs-postgresql.xql 29 Jan 2002 00:11:46 -0000 1.6 +++ openacs-4/packages/ecommerce/tcl/ecommerce-state-changes-procs-postgresql.xql 26 May 2002 04:36:50 -0000 1.7 @@ -1,121 +1,94 @@ - postgresql7.1 + + postgresql + 7.1 + - - + + + select ec_reinst_gift_cert_on_order (:order_id) + + -select ec_reinst_gift_cert_on_order (:order_id) + + + update ec_orders + set order_state = 'authorized', authorized_date = current_timestamp + where order_id = :order_id + + - - + + + insert into ec_shipments + (shipment_id, order_id, shipment_date, expected_arrival_date, carrier, shippable_p, last_modified, last_modifying_user, modified_ip_address) + select :shipment_id, :order_id, current_timestamp, current_timestamp, 'none', 'f', current_timestamp, user_id, :peeraddr from ec_orders where order_id = :order_id + + - - - - select ec_order_cost(:order_id) - - + + + update ec_orders + set order_state='confirmed', confirmed_date=current_timestamp + where order_id=:order_id + + - - - - update ec_orders set order_state=:new_state, authorized_date=current_timestamp where order_id=:order_id - - - - - - - update ec_financial_transactions set authorized_date=current_timestamp where transaction_id=:transaction_id - - - - - - - update ec_orders set order_state='confirmed', confirmed_date=current_timestamp where order_id=:order_id - - - - - - + + select ec_order_cost(:order_id) - - + + - - - + + insert into ec_financial_transactions - (transaction_id, order_id, transaction_amount, transaction_type, inserted_date) - values - (:transaction_id, :order_id, :total_amount, 'charge', current_timestamp) - - + (transaction_id, order_id, transaction_amount, transaction_type, inserted_date) + values + (:transaction_id, :order_id, :total_amount, 'charge', current_timestamp) + + - - - - - select gift_certificate_id - from ec_gift_certificates_approved - where user_id=:user_id - and current_timestamp - expires < 0 - and amount_remaining_p = 't' - order by expires - - - - - - - - select ec_gift_certificate_balance(:user_id) - - - - - - + + select ec_order_amount_owed(:order_id) - - + + - - - - select gift_certificate_amount_left(:gift_certificate_id) - - + + + select gift_certificate_id, gift_certificate_amount_left(gift_certificate_id) as amount_available + from ec_gift_certificates_approved + where user_id = :user_id + and current_timestamp - expires < 0 + and amount_remaining_p = 't' + and gift_certificate_amount_left(gift_certificate_id) > 0 + order by expires + + - - - + + insert into ec_gift_certificate_usage (gift_certificate_id, order_id, amount_used, used_date) - VALUES + values (:gift_certificate_id, :order_id, - least(:gift_certificate_amount_left,:amount_owed), current_timestamp) - - - + least(:amount_available, :amount_owed), current_timestamp) + + - - - + + select ec_gift_certificate_balance(:user_id) - - + + - - - + + select ec_order_amount_owed(:order_id) - - + + - Index: openacs-4/packages/ecommerce/tcl/ecommerce-state-changes-procs.tcl =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/ecommerce/tcl/ecommerce-state-changes-procs.tcl,v diff -u -r1.4 -r1.5 --- openacs-4/packages/ecommerce/tcl/ecommerce-state-changes-procs.tcl 29 Jan 2002 00:11:46 -0000 1.4 +++ openacs-4/packages/ecommerce/tcl/ecommerce-state-changes-procs.tcl 26 May 2002 04:36:50 -0000 1.5 @@ -1,121 +1,164 @@ -# /tcl/ecommerce-state-changes.tcl ad_library { @author Eve Andersson (eveander@arsdigita.com) @creation-date Summer 1999 - @cvs-id ecommerce-state-changes.tcl,v 3.1.2.4 2000/08/17 17:37:16 seb Exp @author ported by Jerry Asher (jerry@theashergroup.com) + @author revised by Bart Teeuwisse + @revision-date March 2002 + } -ad_proc ec_update_state_to_in_basket { order_id } { -If a credit card failure occurs, the following actions - need to be taken: - 1. ec_orders.order_state becomes in_basket - 2. ec_creditcards.failed_p becomes t - 3. any gift certificates used should be reinstated - 4. confirmed_date is set to null (because we use existence of - confirmed_date to see if order is confirmed yet) - Call this procedure from within a transaction +ad_proc ec_update_state_to_in_basket { + order_id +} { + + If a credit card failure occurs, the following actions + need to be taken: + + 1. ec_orders.order_state becomes in_basket + 2. ec_creditcards.failed_p becomes t + 3. any gift certificates used should be reinstated + 4. confirmed_date is set to null (because we use existence of + confirmed_date to see if order is confirmed yet) + + Call this procedure from within a transaction + } { - db_1row credit_user_select "select creditcard_id, user_id from ec_orders where order_id=:order_id" - db_dml order_state_update "update ec_orders set order_state='in_basket', confirmed_date=null where order_id=:order_id" - db_dml creditcard_update "update ec_creditcards set failed_p='t' where creditcard_id=:creditcard_id" - db_exec_plsql reinst_gift_cert_on_order "declare begin ec_reinst_gift_cert_on_order (:order_id); end;" + db_1row credit_user_select " + select creditcard_id, user_id + from ec_orders + where order_id=:order_id" + db_dml order_state_update " + update ec_orders + set order_state='in_basket', confirmed_date=null + where order_id=:order_id" + db_dml creditcard_update " + update ec_creditcards + set failed_p='t' + where creditcard_id=:creditcard_id" + db_exec_plsql reinst_gift_cert_on_order " + declare + begin + ec_reinst_gift_cert_on_order (:order_id); + end;" } -ad_proc ec_update_state_to_authorized {order_id plus_avs_p} { - If a credit card authorization occurs, the following actions - need to be taken: - 1. ec_orders.order_state becomes authorized_plus/minus_avs - 2. ec_orders.authorized_date is filled in - 3. all items in ec_items in that order need to have their state - updated to to_be_shipped +ad_proc ec_update_state_to_authorized { + order_id } { - if {$plus_avs_p == "t"} { - set new_state "authorized_plus_avs" - } else { - set new_state "authorized_minus_avs" - } - # if the total order cost is more than 0, there should be a row in ec_financial_transactions - # for this order - if { [db_string order_cost_select "select ec_order_cost(:order_id) from dual"] > 0 } { - set transaction_id [db_string transaction_select "select max(transaction_id) from ec_financial_transactions where order_id=:order_id"] - db_dml authorized_date_update "update ec_financial_transactions set authorized_date=sysdate where transaction_id=:transaction_id" - } + If a credit card authorization occurs, the following actions + need to be taken: - db_dml order_state_update "update ec_orders set order_state=:new_state, authorized_date=sysdate where order_id=:order_id" - db_dml set_to_be_shipped "update ec_items set item_state='to_be_shipped' where order_id=:order_id" + 1. ec_orders.order_state becomes authorized + 2. ec_orders.authorized_date is filled in + 3. all items in ec_items in that order need to have their state + updated to to_be_shipped + +} { + + db_dml set_order_authorized " + update ec_orders + set order_state = 'authorized', authorized_date = sysdate + where order_id = :order_id" + + # Soft goods don't require shipping and can go directly to the + # 'shipped' state. + + if {[db_0or1row order_contains_soft_goods " + select item_id + from ec_items i, ec_products p + where i.order_id = :order_id + and i.product_id = p.product_id + and p.no_shipping_avail_p = 't' + limit 1"]} { + set peeraddr [ns_conn peeraddr] + set shipment_id [db_nextval ec_shipment_id_sequence] + db_dml record_soft_goods_shipment " + insert into ec_shipments + (shipment_id, order_id, shipment_date, expected_arrival_date, carrier, shippable_p, last_modified, last_modifying_user, modified_ip_address) + select :shipment_id, order_id, sysdate, sysdate, 'none', 'f', sysdate, user_id, :peeraddr from ec_orders where order_id = :order_id" + + db_dml set_soft_goods_shipped " + update ec_items + set item_state = 'shipped', shipment_id = :shipment_id + from ec_products p + where ec_items.order_id = :order_id + and ec_items.product_id = p.product_id + and p.no_shipping_avail_p = 't'" + } + # Update the state of all hard goods from 'in_basket' to + # 'to_be_shipped'. + + db_dml set_hard_goods_to_be_shipped " + update ec_items + set item_state = 'to_be_shipped' + from ec_products p + where ec_items.order_id = :order_id + and ec_items.product_id = p.product_id + and p.no_shipping_avail_p = 'f'" + } -ad_proc ec_update_state_to_confirmed {order_id} { - If an order is confirmed, the following actions need to be taken: - 1. ec_orders.order_state becomes confirmed - 2. ec_orders.confirmed_date is filled in - 3. gift_certificate needs to be applied - 4. if the total order cost is greater than 0, a row needs to be added to ec_financial_transactions - Note: call this from within a transaction +ad_proc ec_update_state_to_confirmed { + order_id } { - set user_id [db_string user_id_select "select user_id from ec_orders where order_id=:order_id"] - ns_log Notice "before ec_apply_gift_cert_balance($order_id,$user_id)" - # db_dml unused "declare begin ec_apply_gift_cert_balance($order_id, $user_id); end;" - ec_apply_gift_certificate_balance $order_id $user_id - ns_log Notice "end ec_apply_gift_cert_balance" + If an order is confirmed, the following actions need to be taken: - db_dml order_state_update "update ec_orders set order_state='confirmed', confirmed_date=sysdate where order_id=:order_id" + 1. ec_orders.order_state becomes confirmed + 2. ec_orders.confirmed_date is filled in + 3. gift_certificate needs to be applied + 4. If the total order cost is greater than 0, a row needs to be + added to ec_financial_transactions - set total_amount [db_string total_amount_select "select ec_order_cost(:order_id) from dual"] - if { $total_amount > 0 } { - # create a new financial transaction - set transaction_id [db_nextval ec_transaction_id_sequence] - db_dml financial_transaction_insert "insert into ec_financial_transactions - (transaction_id, order_id, transaction_amount, transaction_type, inserted_date) - values - (:transaction_id, :order_id, :total_amount, 'charge', sysdate)" - } + Note: call this from within a transaction + +} { + + set user_id [db_string user_id_select " + select user_id + from ec_orders + where order_id=:order_id"] + + ec_apply_gift_certificate_balance $order_id $user_id + + db_dml order_state_update " + update ec_orders + set order_state = 'confirmed', confirmed_date = sysdate + where order_id = :order_id" } -ad_proc ec_apply_gift_certificate_balance { order_id user_id } { this takes the place of the pl/sql procedure ec_apply_gift_cert_balance } { - set certificates_to_use [db_list certificates_to_use_select " - select gift_certificate_id - from ec_gift_certificates_approved - where user_id=:user_id - and sysdate - expires < 0 - and amount_remaining_p = 't' - order by expires - "] +ad_proc ec_apply_gift_certificate_balance { + order_id + user_id +} { - set gift_certificate_balance [db_string gift_certificate_balance_select "select ec_gift_certificate_balance(:user_id) from dual"] - set amount_owed [db_string amount_owed_select "select ec_order_amount_owed(:order_id) from dual"] + This proc takes the place of the pl/sql procedure + ec_apply_gift_cert_balance - set counter 0 - while { $amount_owed > 0 && $gift_certificate_balance > 0 && [llength $certificates_to_use] > $counter} { - ns_log Notice "ec_apply_gift_certificate_balance iteration $counter: gift_certificate_balance=$gift_certificate_balance, amount_owed=$amount_owed" - set gift_certificate_id [lindex $certificates_to_use $counter] - set gift_certificate_amount_left [db_string gift_certificate_amount_left_select "select gift_certificate_amount_left(:gift_certificate_id) from dual"] - - if { $gift_certificate_amount_left > 0 } { -# http://www.arsdigita.com/bboard/q-and-a-fetch-msg?msg_id=000YLy&topic_id=21&topic=web%2fdb -# db_dml gift_certificate_usage_insert "insert into ec_gift_certificate_usage -# (gift_certificate_id, order_id, amount_used, used_date) -# VALUES -# (:gift_certificate_id, :order_id, least(:gift_certificate_amount_left, :amount_owed), sysdate) -# " +} { + set amount_owed [db_string amount_owed_select " + select ec_order_amount_owed(:order_id) + from dual"] - db_dml gift_certificate_usage_insert "insert into ec_gift_certificate_usage - (gift_certificate_id, order_id, amount_used, used_date) - VALUES - (:gift_certificate_id, :order_id, least(to_number(:gift_certificate_amount_left), - to_number(:amount_owed)), sysdate) - " - - set gift_certificate_balance [db_string gift_certificate_balance_select "select ec_gift_certificate_balance(:user_id) from dual"] - set amount_owed [db_string amount_owed_select "select ec_order_amount_owed(:order_id) from dual"] - } + db_foreach available_gift_certificates " + select gift_certificate_id, gift_certificate_amount_left(gift_certificate_id) as amount_available + from ec_gift_certificates_approved + where user_id = :user_id + and sysdate - expires < 0 + and amount_remaining_p = 't' + and gift_certificate_amount_left(gift_certificate_id) > 0 + order by expires" { - incr counter - } - if { [llength $certificates_to_use] <= $counter } { - ns_log Notice "ec_apply_gift_certificate_balance ran out of gift certificates to use before the gift certificate balance was supposedly used up!" - } + if {$amount_owed > 0} { + db_dml gift_certificate_usage_insert " + insert into ec_gift_certificate_usage + (gift_certificate_id, order_id, amount_used, used_date) + values + (:gift_certificate_id, :order_id, least(to_number(:amount_available), to_number(:amount_owed)), sysdate)" + set amount_owed [db_string amount_owed_select " + select ec_order_amount_owed(:order_id) + from dual"] + } + } } Index: openacs-4/packages/ecommerce/tcl/ecommerce-state-changes-procs.xql =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/ecommerce/tcl/ecommerce-state-changes-procs.xql,v diff -u -r1.1 -r1.2 --- openacs-4/packages/ecommerce/tcl/ecommerce-state-changes-procs.xql 10 Jul 2001 20:38:43 -0000 1.1 +++ openacs-4/packages/ecommerce/tcl/ecommerce-state-changes-procs.xql 26 May 2002 04:36:50 -0000 1.2 @@ -1,60 +1,83 @@ + - - - select creditcard_id, user_id from ec_orders where order_id=:order_id - - + + + select creditcard_id, user_id + from ec_orders + where order_id=:order_id + + + + + + update ec_orders + set order_state='in_basket', confirmed_date=null + where order_id=:order_id + + + + + + update ec_creditcards + set failed_p='t' + where creditcard_id=:creditcard_id + + + + + + select max(transaction_id) + from ec_financial_transactions + where order_id=:order_id + + + + + + update ec_orders + set order_state='in_basket', confirmed_date=null + where order_id=:order_id + + + + + + update ec_items + set item_state = 'shipped', shipment_id = :shipment_id + from ec_products p + where ec_items.order_id = :order_id + and ec_items.product_id = p.product_id + and p.no_shipping_avail_p = 't' + + - - - - update ec_orders set order_state='in_basket', confirmed_date=null where order_id=:order_id - - + + + update ec_items + set item_state = 'to_be_shipped' + from ec_products p + where ec_items.order_id = :order_id + and ec_items.product_id = p.product_id + and p.no_shipping_avail_p = 'f' + + - - - - update ec_creditcards set failed_p='t' where creditcard_id=:creditcard_id - - - - - - - select max(transaction_id) from ec_financial_transactions where order_id=:order_id - - - - - - - update ec_orders set order_state='in_basket', confirmed_date=null where order_id=:order_id - - - - - - - update ec_items set item_state='to_be_shipped' where order_id=:order_id - - - - - - - select user_id from ec_orders where order_id=:order_id - - - - - - - update ec_orders set order_state='in_basket', confirmed_date=null where order_id=:order_id - - - - + + + select user_id + from ec_orders + where order_id=:order_id + + + + + + update ec_orders + set order_state='in_basket', confirmed_date=null + where order_id=:order_id + + + Index: openacs-4/packages/ecommerce/tcl/ecommerce-user-contributions-summary-procs-oracle.xql =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/ecommerce/tcl/ecommerce-user-contributions-summary-procs-oracle.xql,v diff -u -r1.1 -r1.2 --- openacs-4/packages/ecommerce/tcl/ecommerce-user-contributions-summary-procs-oracle.xql 10 Jul 2001 20:38:43 -0000 1.1 +++ openacs-4/packages/ecommerce/tcl/ecommerce-user-contributions-summary-procs-oracle.xql 26 May 2002 04:36:50 -0000 1.2 @@ -1,13 +1,15 @@ - oracle8.1.6 + + oracle + 8.1.6 + - - + + select ec_gift_certificate_balance(:user_id) from dual - - - - + + + Index: openacs-4/packages/ecommerce/tcl/ecommerce-user-contributions-summary-procs-postgresql.xql =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/ecommerce/tcl/ecommerce-user-contributions-summary-procs-postgresql.xql,v diff -u -r1.1 -r1.2 --- openacs-4/packages/ecommerce/tcl/ecommerce-user-contributions-summary-procs-postgresql.xql 10 Jul 2001 20:38:43 -0000 1.1 +++ openacs-4/packages/ecommerce/tcl/ecommerce-user-contributions-summary-procs-postgresql.xql 26 May 2002 04:36:50 -0000 1.2 @@ -1,13 +1,15 @@ - postgresql7.1 + + postgresql + 7.1 + - - + + select ec_gift_certificate_balance(:user_id) - - - - + + + Index: openacs-4/packages/ecommerce/tcl/ecommerce-user-contributions-summary-procs.xql =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/ecommerce/tcl/ecommerce-user-contributions-summary-procs.xql,v diff -u -r1.1 -r1.2 --- openacs-4/packages/ecommerce/tcl/ecommerce-user-contributions-summary-procs.xql 10 Jul 2001 20:38:43 -0000 1.1 +++ openacs-4/packages/ecommerce/tcl/ecommerce-user-contributions-summary-procs.xql 26 May 2002 04:36:50 -0000 1.2 @@ -1,22 +1,21 @@ + - - + + select address_id -from ec_addresses where user_id = :user_id - - - - - - + from ec_addresses where user_id = :user_id + + + + + select c.comment_id, p.product_name, comment_date - from ec_product_comments c, ec_products p - where c.product_id = p.product_id - and user_id = :user_id - - - - + from ec_product_comments c, ec_products p + where c.product_id = p.product_id + and user_id = :user_id + + + Index: openacs-4/packages/ecommerce/tcl/ecommerce-utilities-procs.tcl =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/ecommerce/tcl/ecommerce-utilities-procs.tcl,v diff -u -r1.8 -r1.9 --- openacs-4/packages/ecommerce/tcl/ecommerce-utilities-procs.tcl 16 Feb 2002 23:32:06 -0000 1.8 +++ openacs-4/packages/ecommerce/tcl/ecommerce-utilities-procs.tcl 26 May 2002 04:36:50 -0000 1.9 @@ -1,43 +1,69 @@ -# /tcl/ecommerce-utilities.tcl ad_library { Utilities for the ecommerce module. @author Eve Andersson (eveander@arsdigita.com) @creation-date April, 1999 - @cvs-id ecommerce-utilities.tcl,v 3.3.2.6 2000/08/17 17:37:17 seb Exp @author ported by Jerry Asher (jerry@theashergroup.com) + @author revised by Bart Teeuwisse + @revision-date March 2002 + } -ad_proc ec_zero_if_null { the_value } { Returns Zero if Null } { +ad_proc ec_zero_if_null { + the_value +} { + + Returns Zero if Null. + +} { if { [empty_string_p $the_value] } { return "0" } else { return $the_value } } -ad_proc ec_na_if_null { the_value } { Returns N/A if Null } { +ad_proc ec_na_if_null { + the_value +} { + + Returns N/A if Null. + +} { if { [empty_string_p $the_value] } { return "N/A" } else { return $the_value } } -ad_proc ec_nbsp_if_null {the_value} { Return nonbreaking space } { +ad_proc ec_nbsp_if_null { + the_value +} { + + Return nonbreaking space. + +} { if { [empty_string_p $the_value] } { return " " } else { return $the_value } } -ad_proc ec_pretty_price { the_price {currency ""} {zero_if_null_p "f"} } { - returns a nicely formatted price } { +ad_proc ec_pretty_price { + the_price + {currency ""} + {zero_if_null_p "f"} +} { - if { [empty_string_p $currency] } { - set currency [ad_parameter -package_id [ec_id] Currency ecommerce] + Returns a nicely formatted price. + +} { + + if { [empty_string_p $currency] } { + set currency [ad_parameter -package_id [ec_id] Currency ecommerce] } if { [empty_string_p $the_price] } { if { $zero_if_null_p == "t" } { @@ -47,37 +73,71 @@ } } else { set formatted_price [format "%0.2f" $the_price] - # if the formatted price is negative but rounds to zero, it shows up as -0.00, + + # If the formatted price is negative but rounds to zero, it shows up as -0.00, # so in that case I'll bash it to 0.00 + if { [string compare $formatted_price "-0.00"] == 0 } { set formatted_price "0.00" } } - + if { $currency == "USD" } { return "\$$formatted_price" } else { return "$formatted_price $currency" } } -ad_proc ec_pretty_column_type { column_type } { Get Pretty Column Type } { - if { $column_type == "integer" } { - return "Integer" - } elseif { $column_type == "number" } { - return "Real Number" - } elseif { $column_type == "date" } { - return "Date" - } elseif { $column_type == "varchar(200)" } { - return "Text - Up to 200 Characters" - } elseif { $column_type == "varchar(4000)" } { - return "Text - Up to 4000 Characters" - } else { - return "Boolean (Yes or No)" +ad_proc ec_pretty_column_type { + column_type +} { + + Get Pretty Column Type. + +} { + switch -exact $column_type { + + "boolean" - + "char(1)" { + return "Boolean (Yes or No)" + } + + "integer" { + return "Integer" + } + + "number" - + "numeric" { + return "Real Number" + } + + "date" - + "timestamp" { + return "Date" + } + + "varchar(200)" { + return "Text - Up to 200 Characters" + } + + "varchar(4000)" { + return "Text - Up to 4000 Characters" + } + + default { + return "Unknown" + } } } -ad_proc ec_custom_product_field_form_element { field_identifier column_type {default_value ""} } { Get Custom Form Element } { +ad_proc ec_custom_product_field_form_element { + field_identifier + column_type + {default_value ""} +} { + Get Custom Form Element. +} { if { $column_type == "integer" || $column_type == "number"} { return "" } elseif { $column_type == "date" } { @@ -87,7 +147,9 @@ } elseif { $column_type == "varchar(4000)" } { return "" } else { - # it's boolean + + # It's a boolean + set to_return "" if { [string tolower $default_value] == "t" || [string tolower $default_value] == "y" || [string tolower $default_value] == "yes"} { append to_return "Yes  " @@ -103,35 +165,62 @@ } } -# the_value should just be a number (no percent sign) -ad_proc ec_percent_to_decimal { the_value } { Converts PCT to dec equiv } { +ad_proc ec_percent_to_decimal { + the_value +} { + + Converts percentage to decimal equiv. The parameter the_value + should just # be a number (no percent sign) + +} { if { [empty_string_p $the_value] } { return "" } else { return [expr double($the_value)/100] } } -# the value returned is just a number (no percent sign) -ad_proc ec_decimal_to_percent { the_decimal_number } { Converts dec to pct } { +ad_proc ec_decimal_to_percent { + the_decimal_number +} { + + Converts decimal to percentage. The the value returned is just a + number (no percent sign) + +} { if { [empty_string_p $the_decimal_number] } { return "" } else { return [expr $the_decimal_number * 100] } } -ad_proc ec_message_if_null { the_value } { Give Null Message } { +ad_proc ec_message_if_null { + the_value +} { + + Give Null Message. + +} { if { [empty_string_p $the_value] } { return "None Defined" } else { return $the_value } } +ad_proc ec_choose_n_random { + choices_list + n_to_choose + chosen_list +} { -ad_proc ec_choose_n_random {choices_list n_to_choose chosen_list} { Get Random Choices } { - if { $n_to_choose == 0 } { return $chosen_list } else { + Get Random Choices. + +} { + if { $n_to_choose == 0 } { + return $chosen_list + } else { set chosen_index [ns_rand [llength $choices_list]] set new_chosen_list [lappend chosen_list [lindex $choices_list $chosen_index]] set new_n_to_choose [expr $n_to_choose - 1] @@ -140,8 +229,16 @@ } } -ad_proc ec_generate_random_string { {string_length 10} } { Returns a random string } { - # leave out characters that might be confusing like l and 1, O and 0, etc. +ad_proc ec_generate_random_string { + {string_length 10} +} { + + Returns a random string + +} { + + # Leave out characters that might be confusing like l and 1, O and 0, etc. + set choices "ABCDEFGHIJKLMNPQRSTUVWXYZabcdefghijmnopqrstuvwxyz23456789" set choices_length [string length $choices] set random_string "" @@ -152,7 +249,13 @@ return $random_string } -ad_proc ec_PrettyBoolean {t_or_f} { Returns Yes or No instead of t/f } { +ad_proc ec_PrettyBoolean { + t_or_f +} { + + Returns Yes or No instead of t/f + +} { if { $t_or_f == "t" || $t_or_f == "T" } { return "Yes" } elseif { $t_or_f == "f" || $t_or_f == "F" } { @@ -162,23 +265,37 @@ } } -ad_proc ec_display_as_html { text_to_display } { Formats text as HTML } { +ad_proc ec_display_as_html { + text_to_display +} { + + Formats text as HTML + +} { regsub -all "\\&" $text_to_display "\\&" html_text regsub -all "\>" $html_text "\\>" html_text regsub -all "\<" $html_text "\\<" html_text regsub -all "\n" $html_text "
    \n" html_text - # get rid of stupid ^M's + + # Get rid of stupid ^M's + regsub -all "\r" $html_text "" html_text return $html_text } +ad_proc ec_linked_thumbnail_if_it_exists { + dirname + {border_p "t"} + {link_to_product_p "f"} +} { -ad_proc ec_linked_thumbnail_if_it_exists { dirname {border_p "t"} {link_to_product_p "f"} } { - This looks at dirname to see if the thumbnail is there and if - so returns an html fragment that links to the bigger version - of the picture (or to product.tcl if link_to_product_p is "t"). - Otherwise it returns the empty string. } { + This looks at dirname to see if the thumbnail is there and if + so returns an html fragment that links to the bigger version + of the picture (or to product.tcl if link_to_product_p is "t"). + Otherwise it returns the empty string. +} { + set linked_thumbnail "" if { $border_p == "f" } { @@ -187,9 +304,9 @@ set border_part_of_img_tag "" } - # see if there's an image file (and thumbnail) - + # See if there's an image file (and thumbnail) # Get the directory where dirname is stored + regsub -all {[a-zA-Z]} $dirname "" product_id set subdirectory [ec_product_file_directory $product_id] set file_path "$subdirectory/$dirname" @@ -201,41 +318,58 @@ set thumbnail_size [ns_jpegsize "$full_dirname/product-thumbnail.jpg"] if { $link_to_product_p == "f" } { - # try to link to a product.jpg or product.gif + # Try to link to a product.jpg or product.gif + if { [file exists "$full_dirname/product.jpg"] } { set linked_thumbnail " - - - - " - + + + " } elseif { [file exists "$full_dirname/product.gif"] } { set linked_thumbnail " - - - " - + + + " } } else { set linked_thumbnail " - - - " - + + + " } } - return $linked_thumbnail } -ad_proc ec_best_price { product_id } { Returns the minimum price offered } { - return [db_string get_min_price "select min(price) from ec_offers where product_id=:product_id"] +ad_proc ec_best_price { + product_id +} { + + Returns the minimum price offered + +} { + return [db_string get_min_price " + select min(price) + from ec_offers + where product_id=:product_id"] } -ad_proc ec_savings { product_id } { Returns savings over Retail price } { - set retailprice [db_string get_retailprice "select retailprice from ec_custom_product_field_values where product_id=:product_id" -default ""] - set bestprice [db_string get_best_price "select min(price) from ec_offers where product_id=:product_id"] +ad_proc ec_savings { + product_id +} { + + Returns savings over Retail price + +} { + set retailprice [db_string get_retailprice " + select retailprice + from ec_custom_product_field_values + where product_id=:product_id" -default ""] + set bestprice [db_string get_best_price " + select min(price) + from ec_offers + where product_id=:product_id"] if { ![empty_string_p $retailprice] && ![empty_string_p $bestprice] } { set savings [expr $retailprice - $bestprice] } else { @@ -244,41 +378,71 @@ return $savings } -ad_proc ec_date_with_time_stripped { the_date } {Removes the time part of the date stamp (useful when using util_AnsiDatetoPrettyDate)} { +ad_proc ec_date_with_time_stripped { + the_date +} { + + Removes the time part of the date stamp (useful when using + util_AnsiDatetoPrettyDate) + +} { + + # If the date isn't formatted like YYYY-MM-DD HH:MI:SS, then just + # return what we got in + if { [regexp {[^\ ]+} $the_date stripped_date ] } { return $stripped_date } else { - # if the date isn't formatted like YYYY-MM-DD HH:MI:SS, then just return what we got in return $the_date } } -ad_proc ec_user_audit_info { } {Returns User ID, IP Address, and date for audit trails} { +ad_proc ec_user_audit_info { +} { + + Returns User ID, IP Address, and date for audit trails + +} { return [list $user_id [ns_conn peeraddr] sysdate] } -ad_proc ec_pretty_creditcard_type { creditcard_type } "Returns the credit card type based on the one-or-two-letter code for that type." { - if { $creditcard_type == "a" || $creditcard_type == "ax"} { - return "American Express" - } elseif { $creditcard_type == "v" || $creditcard_type == "vs"} { - return "Visa" - } elseif { $creditcard_type == "m" || $creditcard_type == "mc"} { - return "MasterCard" +ad_proc ec_pretty_creditcard_type { + creditcard_type +} { + + Returns the credit card type based on the one-or-two-letter code + for that type. + +} { + set pretty_creditcard_type [string map [list m MasterCard v VISA a {American Express} n {Discover/Novus} j JCB d {Diners Club} c {Carte Blanche}] $creditcard_type] + if { $pretty_creditcard_type == $creditcard_type } { + return "unknown" } else { - return "Unknown" + return $pretty_creditcard_type } } -ad_proc ec_decode {args} { like decode in sql - Takes the place of an if (or switch) statement -- convenient because it's compact and - you don't have to break out of an append doc_body if you're in one. - args: same order as in sql: first the unknown value, then any number of pairs denoting - if the unknown value is equal to first element of pair, then return second element, then -if the unknown value is not equal to any of the first elements, return the last arg } { +ad_proc ec_decode { + args +} { + + This proc is modelled after the decode in sql. Takes the place of + an if (or switch) statement -- convenient because it's compact + and there is no need to break out of an append doc_body if + called from with in one. + + args: same order as in sql: first the unknown value, then any + number of pairs denoting. If the unknown value is equal to first + element of pair, then return second element, then if the unknown + value is not equal to any of the first elements, return the last + arg + +} { set args_length [llength $args] set unknown_value [lindex $args 0] - # we want to skip the first & last values of args + # Skip the first & last values of args + set counter 1 while { $counter < [expr $args_length -2] } { if { [string compare $unknown_value [lindex $args $counter]] == 0 } { @@ -289,24 +453,42 @@ return [lindex $args [expr $args_length -1]] } -ad_proc ec_last_second_in_the_day { the_date } "Returns the last second of the given day's date. Input date should be in format YYYY-MM-DD HH24:MI:SS or YYYY-MM-DD." { +ad_proc ec_last_second_in_the_day { + the_date +} { + + Returns the last second of the given day's date. Input date + should be in format YYYY-MM-DD HH24:MI:SS or YYYY-MM-DD. + +} { regexp {^(....)-(..)-(..)} $the_date garbage year month day return "$year-$month-$day 23:59:59" } -ad_proc ec_user_identification_summary { user_identification_id {link_to_new_window_p "f"} } { Get user Info } { +ad_proc ec_user_identification_summary { + user_identification_id + {link_to_new_window_p "f"} +} { + + Get user Info +} { if { $link_to_new_window_p == "t" } { set target_tag "target=user_window" } else { set target_tag "" } - if { [db_0or1row get_row_exists "select user_id,first_names,last_name,email,other_id_info,postal_code from ec_user_identification where user_identification_id=:user_identification_id"]==0 } { - + if { [db_0or1row get_row_exists " + select user_id,first_names, last_name, email, other_id_info, postal_code + from ec_user_identification + where user_identification_id=:user_identification_id"]==0 } { return "" } if { ![empty_string_p $user_id] } { - set user_name [db_string get_user_name "select first_names || ' ' || last_name from cc_users where user_id=:user_id"] + set user_name [db_string get_user_name " + select first_names || ' ' || last_name + from cc_users + where user_id=:user_id"] return "Registered user: $user_name." } @@ -339,8 +521,16 @@ return "$name_part_to_return $email_part_to_return $postal_code_part_to_return $other_id_info_part_to_return $link_part_to_return" } -ad_proc ec_export_entire_form_except args { Exports all but part of a form } { - # exports entire form except the variables specified in args +ad_proc ec_export_entire_form_except { + args +} { + + Exports all but part of a form + +} { + + # Exports entire form except the variables specified in args + set hidden "" set the_form [ns_getform] for {set i 0} {$i<[ns_set size $the_form]} {incr i} { @@ -353,26 +543,39 @@ return $hidden } -# produces a safe-for-browsers hidden variable, i.e., one where -# " has been replaced by " - -# a recreation of philg_hidden_input, since deprecated. - -ad_proc ec_hidden_input {name value} { - Returns a safe-for-browsers hidden variable, i.e. one where " has +ad_proc ec_hidden_input { + name + value +} { + Returns a safe-for-browsers hidden variable, i.e. one where \" has been replaced by "e } { - #" return "" } -# ugly_date should be in the format YYYY-MM-DD HH24:MI:SS -ad_proc ec_formatted_full_date { ugly_date } { Format Ugly Date to Pretty } { - return "[util_AnsiDatetoPrettyDate [lindex [split $ugly_date " "] 0]] [lindex [split $ugly_date " "] 1]" +ad_proc ec_formatted_full_date { + ugly_date +} { + + Format Ugly Date to Pretty Date. The ugly_date parameter should + be in the format YYYY-MM-DD HH24:MI:SS-TZ. + +} { + if { [llength [split $ugly_date " "]] == 2 } { + return [clock format [clock scan $ugly_date] -format "%B %d, %Y %r" -gmt true] + } else { + return + } } -# ugly_date shoud be in the format YYYY-MM-DD HH24:MI:SS or just YYYY-MM-DD -ad_proc ec_formatted_date { ugly_date } { Format Ugly Date } { +ad_proc ec_formatted_date { + ugly_date +} { + + Format Ugly Date ugly_date shoud be in the format YYYY-MM-DD + HH24:MI:SS or just YYYY-MM-DD + +} { set split_date [split $ugly_date " "] if { [llength $split_date] == 1 } { return [util_AnsiDatetoPrettyDate $ugly_date] @@ -381,37 +584,61 @@ } } -ad_proc ec_location_based_on_zip_code { zip_code } { Get location } { +ad_proc ec_location_based_on_zip_code { + zip_code +} { + + Get location + +} { set sql " - select state_code, city_name, county_name - from zip_codes - where zip_code=:zip_code" + select state_code, city_name, county_name + from zip_codes + where zip_code=:zip_code" set city_list [list] if { [catch { db_foreach get_city_list $sql { - lappend city_list "$city_name, $county_name County, $state_code" - } } errmsg] } { return "Zip Code Table Not Installed" } - + } } errmsg] } { + return "Zip Code Table Not Installed" + } return "[join $city_list " or "]" } -ad_proc ec_country_name_from_country_code { country_code } { - gets country name from country code +ad_proc ec_country_name_from_country_code { + country_code } { + + Gets country name from country code. + +} { if [catch { - db_1row country_name { - select default_name from countries where iso=:country_code - } - } errmsg] { + db_1row country_name " + select default_name + from countries + where iso=:country_code"} errmsg] { return "Country not found" } return $default_name } -ad_proc ec_pretty_mailing_address_from_args { line1 line2 city usps_abbrev zip_code country_code full_state_name attn phone phone_time } { get Pretty Mailing Address } { +ad_proc ec_pretty_mailing_address_from_args { + line1 + line2 + city + usps_abbrev + zip_code + country_code + full_state_name + attn + phone + phone_time +} { + Get Pretty Mailing Address. + +} { set lines [list $attn] if [empty_string_p $line2] { lappend lines $line1 @@ -421,41 +648,60 @@ lappend lines $line1 lappend lines $line2 } - - if { ![empty_string_p $country_code] && $country_code != "us" } { + if { ![empty_string_p $country_code] && $country_code != "US" } { lappend lines "$city, $full_state_name $zip_code" - lappend lines [ec_country_name_from_country_code $country_code] } else { lappend lines "$city, $usps_abbrev $zip_code" } - - lappend lines "$phone ([ec_decode $phone_time "D" "day" "E" "evening" ""])" - - return [join $lines "\n"] + lappend lines "$phone ([ec_decode $phone_time "d" "day" "e" "evening" ""])" + return [join $lines "\n"] } -ad_proc ec_pretty_mailing_address_from_ec_addresses { address_id } { Gets Pretty Mailing Address } { +ad_proc ec_pretty_mailing_address_from_ec_addresses { + address_id +} { + + Gets Pretty Mailing Address. + +} { if { [empty_string_p $address_id] } { return "" } - - if { [db_0or1row get_row_exists_p "select line1, line2, city, usps_abbrev, zip_code, country_code, full_state_name, attn, phone, phone_time from ec_addresses where address_id=:address_id"]==0 } { + if { [db_0or1row get_row_exists_p " + select line1, line2, city, usps_abbrev, zip_code, country_code, full_state_name, attn, phone, phone_time + from ec_addresses + where address_id=:address_id"]==0 } { return "" - } - + } return [ec_pretty_mailing_address_from_args $line1 $line2 $city $usps_abbrev $zip_code $country_code $full_state_name $attn $phone $phone_time] } -ad_proc ec_creditcard_summary { creditcard_id } { Returns Credit Card info } { - - if { [db_0or1row get_creditcard_summary "select creditcard_type, creditcard_last_four, creditcard_expire, billing_zip_code from ec_creditcards where creditcard_id=:creditcard_id"] == 0 } { +ad_proc ec_creditcard_summary { + creditcard_id +} { + + Returns Credit Card info + +} { + if { [db_0or1row get_creditcard_summary " + select c.creditcard_type, c.creditcard_last_four, c.creditcard_expire, a.address_id + from ec_creditcards c, ec_addresses a + where creditcard_id = :creditcard_id + and c.billing_address = a.address_id"] == 0 } { return "" } - return "[ec_pretty_creditcard_type $creditcard_type]\nxxxxxxxxxxxx$creditcard_last_four\nexp: $creditcard_expire\nzip: $billing_zip_code" + return "[ec_pretty_creditcard_type $creditcard_type]\nxxxxxxxxxxxx$creditcard_last_four\nexp: $creditcard_expire" } -ad_proc ec_elements_of_list_a_that_arent_in_list_b { list_a list_b } { Do a check and return list of a that are not in b } { +ad_proc ec_elements_of_list_a_that_arent_in_list_b { + list_a + list_b +} { + + Do a check and return list of a that are not in b + +} { set list_to_return [list] foreach list_a_element $list_a { if { [lsearch -exact $list_b $list_a_element] == -1 } { @@ -465,7 +711,14 @@ return $list_to_return } -ad_proc ec_first_element_of_list_a_that_isnt_in_list_b { list_a list_b } { Get First Element of A not in B} { +ad_proc ec_first_element_of_list_a_that_isnt_in_list_b { + list_a + list_b +} { + + Get First Element of A not in B + +} { foreach list_a_element $list_a { if { [lsearch -exact $list_b $list_a_element] == -1 } { return $list_a_element @@ -474,17 +727,23 @@ return "" } -# Gets the start and end date when the dates are supplied by ec_report_date_range_widget; -# if they're not supplied, it makes the first of this month be the start date and today -# be the end date. -# This proc uses uplevel and assumes the existence of db. -# If the date is supplied incorrectly or not supplied at all, it just returns the default -# dates (above), unless return_date_error_p (in the calling environment) is "t", in which case -# it returns 0 -ad_proc ec_report_get_start_date_and_end_date { } { Report Get Start and End Date from Widgets } { +ad_proc ec_report_get_start_date_and_end_date { +} { + + Gets the start and end date when the dates are supplied by + ec_report_date_range_widget; if they're not supplied, it makes + the first of this month be the start date and today be the end + date. + + This proc uses uplevel and assumes the existence of db. If the + date is supplied incorrectly or not supplied at all, it just + returns the default dates (above), unless return_date_error_p + (in the calling environment) is "t", in which case it returns 0 + +} { uplevel { - # get rid of leading zeroes in start%5fdate.day and + # Get rid of leading zeroes in start%5fdate.day and # end%5fdate.day because it can't interpret 08 and # 09 (It thinks they're octal numbers) @@ -494,14 +753,14 @@ ns_set update $form "start%5fdate.day" [set start%5fdate.day] ns_set update $form "end%5fdate.day" [set end%5fdate.day] } - set current_year [ns_fmttime [ns_time] "%Y"] set current_month [ns_fmttime [ns_time] "%m"] set current_date [ns_fmttime [ns_time] "%d"] - # it there's no time connected to the date, just the date argument to ns_dbformvalue, + # It there's no time connected to the date, just the date argument to ns_dbformvalue, # otherwise use the datetime argument + if [catch { ns_dbformvalue [ns_conn form] start_date date start_date} errmsg ] { if { ![info exists return_date_error_p] || $return_date_error_p == "f" } { set start_date(date) "$current_year-$current_month-01" @@ -516,7 +775,6 @@ set end_date(date) "0" } } - if { [string compare $start_date(date) ""] == 0 } { if { ![info exists return_date_error_p] || $return_date_error_p == "f" } { set start_date(date) "$current_year-$current_month-01" @@ -534,28 +792,39 @@ } } +ad_proc ec_order_status { + order_id +} { -ad_proc ec_order_status { order_id } { returns the status of the order for the customer } { - # check shipping_method to see whether this was a shippable order - set shippable_p [db_string get_shippable_p "select decode(shipping_method,'no shipping',0,1) as shippable_p from ec_orders where order_id=:order_id"] + Returns the status of the order for the customer - # we have to look at individual items +} { + + # Check shipping_method to see whether this was a shippable order + + set shippable_p [db_string get_shippable_p " + select decode(shipping_method,'no shipping',0,1) as shippable_p + from ec_orders + where order_id=:order_id"] + + # Look at individual items set n_shipped_items 0 set n_received_back_items 0 set n_total_items 0 - set sql "select item_state, count(*) as n_items - from ec_items - where order_id=$order_id - group by item_state" + set sql " + select item_state, count(*) as n_items + from ec_items + where order_id=$order_id + group by item_state" db_foreach get_individual_items $sql { - if { $item_state == "shipped" || $item_state == "arrived" } { set n_shipped_items [expr $n_shipped_items + $n_items] } elseif { $item_state == "received_back" } { set n_received_back_items $n_items } set n_total_items [expr $n_total_items + $n_items] } + # Possible combinations: # returned | shipped | blank | order status # ---------|---------|-------|------------- @@ -566,6 +835,7 @@ # some some 0 Some Items Returned # 0 some some Partial Shipment Made # some 0 some Some Items Returned + # # * Note: some of the above wording is changed if it # is a non shippable order @@ -588,16 +858,18 @@ } } +ad_proc ec_gift_certificate_status { + gift_certificate_id +} { -ad_proc ec_gift_certificate_status { gift_certificate_id } { - returns the status of the gift certificate for the customer } { - db_1row get_gift_certificate_info "select - gift_certificate_state, user_id - from ec_gift_certificates - where gift_certificate_id=:gift_certificate_id" + Returns the status of the gift certificate for the customer +} { + db_1row get_gift_certificate_info " + select gift_certificate_state, user_id + from ec_gift_certificates + where gift_certificate_id=:gift_certificate_id" - if { $gift_certificate_state == "confirmed" } { return "Not Yet Authorized" } @@ -606,7 +878,7 @@ return "Failed Authorization" } - if { $gift_certificate_state == "authorized_plus_avs" || $gift_certificate_state == "authorized_minus_avs" } { + if { $gift_certificate_state == "authorized" } { if { [empty_string_p $user_id] } { return "Authorized (not yet claimed)" } else { @@ -621,59 +893,105 @@ return "Unknown" } -ad_proc ec_max { a b } { returns a if a>=b or b if b>a } { +ad_proc ec_max { + a + b +} { + + Returns a if a>=b or b if b>a + +} { if { $a >= $b } { return $a } else { return $b } } -ad_proc ec_min { a b } { returns b if a>=b or b if b>a } { +ad_proc ec_min { + a + b +} { + + Returns b if a>=b or b if b>a + +} { if { $a >= $b } { return $b } else { return $a } } -ad_proc ec_product_file_directory { product_id } { +ad_proc ec_product_file_directory { + product_id +} { + Returns the directory that that the product files are located -under the ecommerce product data directory. This is the two lowest -order digits of the product_id. + under the ecommerce product data directory. This is the two + lowest order digits of the product_id. + } { set id_length [string length $product_id] if { $id_length == 1 } { - # zero pad the product_id + + # Zero pad the product_id + return "0$product_id" } else { - # return the lowest two digits + + # Return the lowest two digits + return [string range $product_id [expr $id_length - 2] [expr $id_length - 1]] } } -ad_proc ec_assert_directory {dir_path} "Checks that directory exists, if not creates it" { +ad_proc ec_assert_directory { + dir_path +} { + + Checks that directory exists, if not creates it + +} { if { [file exists $dir_path] } { + # Everything okay + return 1 } else { - # wtem@olywa.net -- 03-12-2001 - # we need a recursive mkdir - # but we will hold off for now - # create a list of directories - # each element in the list must have the full path - # then run file exists and ns_mkdir foreach path + + # wtem@olywa.net -- 03-12-2001 we need a recursive mkdir but + # we will hold off for now create a list of directories each + # element in the list must have the full path then run file + # exists and ns_mkdir foreach path + ns_mkdir $dir_path return 1 } } -ad_proc ec_leading_zeros {the_integer n_desired_digits} "Adds leading zeros to an integer to give it the desired number of digits" { +ad_proc ec_leading_zeros { + the_integer + n_desired_digits +} { + + Adds leading zeros to an integer to give it the desired number + of digits. + +} { return [format "%0${n_desired_digits}d" $the_integer] } -ad_proc ec_leading_nbsp {the_integer n_desired_digits} "Adds leading nbsps to an integer to give it the desired number of digits" { +ad_proc ec_leading_nbsp { + the_integer + n_desired_digits +} { + + Adds leading nbsps to an integer to give it the desired number + of digits + +} { set n_digits_to_add [expr $n_desired_digits - [string length $the_integer]] if {$n_digits_to_add <= 0} { return $the_integer @@ -682,37 +1000,17 @@ } } +ad_proc ecGetUserAgentHeader { +} { + + Gets user agent header -ad_proc ecGetUserAgentHeader {} { gets user agent header } { +} { set header [ns_conn headers] - # note that this MUST be case-insensitive search (iget) - # due to a NaviServer bug -- philg 2/1/96 + # Note that this MUST be case-insensitive search (iget) due to a + # NaviServer bug -- philg 2/1/96 set userag [ns_set iget $header "USER-AGENT"] return $userag } - -ad_proc util_decode args { - like decode in sql - Takes the place of an if (or switch) statement -- convenient because it's - compact and you don't have to break out of an ns_write if you're in one. - args: same order as in sql: first the unknown value, then any number of - pairs denoting "if the unknown value is equal to first element of pair, - then return second element", then if the unknown value is not equal to any - of the first elements, return the last arg -} { - set args_length [llength $args] - set unknown_value [lindex $args 0] - - # we want to skip the first & last values of args - set counter 1 - while { $counter < [expr $args_length -2] } { - if { [string compare $unknown_value [lindex $args $counter]] == 0 } { - return [lindex $args [expr $counter + 1]] - } - set counter [expr $counter + 2] - } - return [lindex $args [expr $args_length -1]] -} - Index: openacs-4/packages/ecommerce/tcl/ecommerce-utilities-procs.xql =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/ecommerce/tcl/ecommerce-utilities-procs.xql,v diff -u -r1.3 -r1.4 --- openacs-4/packages/ecommerce/tcl/ecommerce-utilities-procs.xql 23 Oct 2001 05:07:14 -0000 1.3 +++ openacs-4/packages/ecommerce/tcl/ecommerce-utilities-procs.xql 26 May 2002 04:36:50 -0000 1.4 @@ -1,77 +1,86 @@ + - - - select min(price) from ec_offers where product_id=:product_id - - + + + select min(price) + from ec_offers + where product_id = :product_id + + + + + + select retailprice + from ec_custom_product_field_values + where product_id = :product_id + + + + + + select min(price) + from ec_offers + where product_id = :product_id + + + + + + select user_id, first_names, last_name, email, other_id_info, postal_code + from ec_user_identification + where user_identification_id = :user_identification_id + + - - - - select retailprice from ec_custom_product_field_values where product_id=:product_id - - + + + + select first_names || ' ' || last_name + from cc_users + where user_id = :user_id + + + + + + select line1, line2, city, usps_abbrev, zip_code, country_code, full_state_name, attn, phone, phone_time + from ec_addresses + where address_id = :address_id + + + + + + select c.creditcard_type, c.creditcard_last_four, c.creditcard_expire, a.address_id + from ec_creditcards c, ec_addresses a + where creditcard_id = :creditcard_id + and c.billing_address = a.address_id + + - - - - select min(price) from ec_offers where product_id=:product_id - - - - - - - select user_id,first_names,last_name,email,other_id_info,postal_code from ec_user_identification where user_identification_id=:user_identification_id - - - - - - - select first_names || ' ' || last_name from cc_users where user_id=:user_id - - - - - - - select line1, line2, city, usps_abbrev, zip_code, country_code, full_state_name, attn, phone, phone_time from ec_addresses where address_id=:address_id - - - - - - - select creditcard_type, creditcard_last_four, creditcard_expire, billing_zip_code from ec_creditcards where creditcard_id=:creditcard_id - - - - - - - select default_name from countries where iso=:country_code - - - - - - - select case when shipping_method = 'no shipping' then 0 else 1 end as shippable_p from ec_orders where order_id=:order_id - - - - - - + + + select default_name from countries where iso = :country_code + + + + + + select case when shipping_method = 'no shipping' then 0 else 1 end as shippable_p + from ec_orders + where order_id = :order_id + + + + + select - gift_certificate_state, user_id - from ec_gift_certificates - where gift_certificate_id=:gift_certificate_id - - - - + gift_certificate_state, user_id + from ec_gift_certificates + where gift_certificate_id = :gift_certificate_id + + + Index: openacs-4/packages/ecommerce/tcl/ecommerce-widgets-procs-oracle.xql =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/ecommerce/tcl/ecommerce-widgets-procs-oracle.xql,v diff -u -r1.4 -r1.5 --- openacs-4/packages/ecommerce/tcl/ecommerce-widgets-procs-oracle.xql 29 Jan 2002 00:11:46 -0000 1.4 +++ openacs-4/packages/ecommerce/tcl/ecommerce-widgets-procs-oracle.xql 26 May 2002 04:36:50 -0000 1.5 @@ -1,8 +1,12 @@ - oracle8.1.6 + + oracle + 8.1.6 + + sysdate Index: openacs-4/packages/ecommerce/tcl/ecommerce-widgets-procs-postgresql.xql =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/ecommerce/tcl/ecommerce-widgets-procs-postgresql.xql,v diff -u -r1.4 -r1.5 --- openacs-4/packages/ecommerce/tcl/ecommerce-widgets-procs-postgresql.xql 29 Jan 2002 00:11:46 -0000 1.4 +++ openacs-4/packages/ecommerce/tcl/ecommerce-widgets-procs-postgresql.xql 26 May 2002 04:36:50 -0000 1.5 @@ -1,7 +1,10 @@ - postgresql7.1 + + postgresql + 7.1 + @@ -27,8 +30,8 @@ s.subcategory_id, s.subcategory_name, ss.subsubcategory_id, ss.subsubcategory_name from ec_categories c - LEFT JOIN ec_subcategories s using (category_id) - LEFT JOIN ec_subsubcategories ss on (s.subcategory_id = ss.subcategory_id) + left join ec_subcategories s using (category_id) + left join ec_subsubcategories ss on (s.subcategory_id = ss.subcategory_id) order by c.sort_key, s.sort_key, ss.sort_key
    @@ -37,9 +40,9 @@ select c.category_id, c.category_name, s.subcategory_id, s.subcategory_name, ss.subsubcategory_id, ss.subsubcategory_name from ec_cat_mailing_lists m - LEFT JOIN ec_categories c on (m.category_id=c.category_id) - LEFT JOIN ec_subcategories s on (m.subcategory_id=s.subcategory_id) - LEFT JOIN ec_subsubcategories ss on (m.subsubcategory_id=ss.subsubcategory_id) + left join ec_categories c on (m.category_id=c.category_id) + left join ec_subcategories s on (m.subcategory_id=s.subcategory_id) + left join ec_subsubcategories ss on (m.subsubcategory_id=ss.subsubcategory_id) order by case when c.category_id is null then 0 else c.sort_key end, case when s.subcategory_id is null then 0 else s.sort_key end, Index: openacs-4/packages/ecommerce/tcl/ecommerce-widgets-procs.tcl =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/ecommerce/tcl/ecommerce-widgets-procs.tcl,v diff -u -r1.12 -r1.13 --- openacs-4/packages/ecommerce/tcl/ecommerce-widgets-procs.tcl 16 Feb 2002 23:32:06 -0000 1.12 +++ openacs-4/packages/ecommerce/tcl/ecommerce-widgets-procs.tcl 26 May 2002 04:36:50 -0000 1.13 @@ -8,15 +8,36 @@ @author ported by Jerry Asher (jerry@theashergroup.com) } -ad_proc ec_search_widget { {combocategory_id ""} {search_text ""} } { creates an ecommerce search widget, using the specified category id and search text if necessary } { - return "
    -Search: [ec_combocategory_widget "f" $combocategory_id] - -
    -" +ad_proc ec_search_widget { + {combocategory_id ""} + {search_text ""} +} { + Creates an ecommerce search widget, using the specified category id and search text if necessary +} { + return " +
    + + + + + + +
    + Search: + [ec_combocategory_widget "f" $combocategory_id] + for + + +
    +
    " } -ad_proc ec_combocategory_widget { {multiple_p "f"} {default ""} } { Category widget combining categories and subcategories } { +ad_proc ec_combocategory_widget { + {multiple_p "f"} + {default ""} +} { + Category widget combining categories and subcategories +} { if { $multiple_p == "f" } { set select_tag "\n" } else { @@ -159,53 +192,81 @@ return $to_return } -ad_proc ec_column_type_widget { {default ""} } { column type widget } { +ad_proc ec_column_type_widget { + {default ""} +} { + Column type widget +} { - ### number and date types for oracle and postgresql - if [string match [db_type] "oracle"] { - set date "date" - set number "number" - set boolean "char(1)" - } elseif [string match [db_type] "postgresql"] { - set date "timestamp" - set number "numeric" - set boolean "boolean" + set database_type [db_type] + + # Set database specific types + + switch -exact $database_type { + "oracle" { + set date "date" + set number "number" + set boolean "char(1)" + } + + "postgresql" - + default { + set date "timestamp" + set number "numeric" + set boolean "boolean" + } } - # boolean will be the default unless specified otherwise - # if it's boolean, the check constraint will be added at the end so that it can be named - set to_return "\n" - - return $to_return + + return " + " } ad_proc ec_multiple_state_widget { {default_list ""} {select_name "usps_abbrev"} } "Returns a state multiple selection box" { @@ -509,24 +570,30 @@ } ad_proc ec_continue_shopping_options { } { returns continue shopping options } { - return "
    -Continue Shopping for [ec_only_category_widget] - -
    -" + return " +
    + Continue Shopping for [ec_only_category_widget] + +
    " } -ad_proc ec_country_widget { {default ""} {select_name "country_code"} {size_subtag "size=4"}} "Just like country_widget, except it's not United States centric." { +ad_proc ec_country_widget { + {default ""} + {select_name "country_code"} + {size_subtag "size=4"} +} { + Just like country_widget, except it's not United States centric. +} { set widget_value "\n" - set footer "\n" - set defaulted_flag 0 - foreach size [list "01" "02" "03" "04" "05" "06" "07" "08" "09" "10" "11" "12"] { - if { $size == $default } { - append options " + " + set default_matched_p 1 } else { - append options " + " } } - if $defaulted_flag { - return "$header$options$footer" + if $default_matched_p { + return " + $header + $options + $footer" } else { - return "${header}" + set default_matched_p 1 } else { - append options "
    [ec_linked_thumbnail_if_it_exists $dirname "f" "t"]$product_name +

    $recommendation_text

    +
    [ec_price_line $product_id $user_id $offer_code]
    "]} { + set recommendations "" +} else { + append recommendations "
    " +} + #============================== # products @@ -140,22 +136,31 @@ " } -set products "" +set products "" set have_how_many_more_p f set count 0 -db_foreach get_regular_product_list "select p.product_id, p.product_name, p.one_line_description -from ec_products_searchable p, $product_map($sub) m -where p.product_id = m.product_id -and m.${sub}category_id = :${sub}category_id -$exclude_subproducts -order by p.product_name -" { +db_foreach get_regular_product_list " + select p.product_id, p.product_name, p.one_line_description, o.offer_code + from $product_map($sub) m, ec_products_searchable p left outer join ec_user_session_offer_codes o on (p.product_id = o.product_id and user_session_id = :user_session_id) + where p.product_id = m.product_id + and m.${sub}category_id = :${sub}category_id + $exclude_subproducts + order by p.product_name" { if { $count >= $start && [expr $count - $start] < $how_many } { - append products "
    [expr $count + 1]$product_name
    $one_line_description
    \n" + append products " + + [expr $count + 1] + $product_name + + + + $one_line_description + [ec_price_line $product_id $user_id $offer_code] + " } incr count if { $count > [expr $start + (2 * $how_many)] } { @@ -167,7 +172,7 @@ } } -append products "" +append products "" if { $start >= $how_many } { set prev_link "Previous $how_many" @@ -213,21 +218,7 @@ } } -set the_category_id [eval "ident \$${sub}category_id"] +set the_category_id $category_id set the_category_name [eval "ident \$${sub}category_name"] db_release_unused_handles -ec_return_template - - - - - - - - - - - - - - +ad_return_template Index: openacs-4/packages/ecommerce/www/category-browse-subcategory.xql =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/ecommerce/www/category-browse-subcategory.xql,v diff -u -r1.1 -r1.2 --- openacs-4/packages/ecommerce/www/category-browse-subcategory.xql 10 Jul 2001 20:42:02 -0000 1.1 +++ openacs-4/packages/ecommerce/www/category-browse-subcategory.xql 26 May 2002 04:36:50 -0000 1.2 @@ -1,89 +1,86 @@ + - - - select first_names || ' ' || last_name from cc_users where user_id=:user_id - - + + + select first_names || ' ' || last_name + from cc_users + where user_id=:user_id + + - - - - - insert into ec_user_session_info (user_session_id, category_id) - values (:user_session_id, :category_id) - - - + + + insert into ec_user_session_info + (user_session_id, category_id) + values + (:user_session_id, :category_id) + + - - - - select category_name from ec_categories where category_id=:category_id - - + + + select category_name + from ec_categories + where category_id=:category_id + + - - - - select subcategory_name from ec_subcategories where subcategory_id=:subcategory_id - - + + + select subcategory_name + from ec_subcategories + where subcategory_id=:subcategory_id + + - - - - select subsubcategory_name from ec_subsubcategories where subsubcategory_id=:subsubcategory_id - - + + + select subsubcategory_name + from ec_subsubcategories + where subsubcategory_id=:subsubcategory_id + + - - - - select - p.product_name, p.product_id, p.dirname, r.recommendation_text -from ec_products_displayable p, ec_product_recommendations r -where p.product_id = r.product_id -and r.${sub}category_id=:${sub}category_id -and r.active_p='t' -and (r.user_class_id is null or r.user_class_id in - (select user_class_id - from ec_user_class_user_map m - where user_id=:user_id - $user_class_approved_p_clause)) -order by p.product_name - - + + + select p.product_id, p.product_name, p.dirname, r.recommendation_text, o.offer_code + from ec_product_recommendations r, ec_products_displayable p left outer join ec_user_session_offer_codes o on + (p.product_id = o.product_id and user_session_id = :user_session_id) + where p.product_id = r.product_id + and r.${sub}category_id=:${sub}category_id + and r.active_p='t' + and (r.user_class_id is null or r.user_class_id in (select user_class_id + from ec_user_class_user_map m + where user_id=:user_id + $user_class_approved_p_clause)) + order by p.product_name + + - - - - select p.product_id, p.product_name, p.one_line_description -from ec_products_searchable p, $product_map($sub) m -where p.product_id = m.product_id -and m.${sub}category_id = :${sub}category_id -$exclude_subproducts -order by p.product_name + + + select p.product_id, p.product_name, p.one_line_description, o.offer_code + from $product_map($sub) m, ec_products_searchable p left outer join ec_user_session_offer_codes o on + (p.product_id = o.product_id and user_session_id = :user_session_id) + where p.product_id = m.product_id + and m.${sub}category_id = :${sub}category_id + $exclude_subproducts + order by p.product_name + + - - + + + select * from ec_sub${sub}categories c + where ${sub}category_id = :${sub}category_id + and exists (select 'x' + from ec_products_displayable p, $product_map(sub$sub) s + where p.product_id = s.product_id + and s.sub${sub}category_id = c.sub${sub}category_id) + order by sort_key, sub${sub}category_name + + - - - - -SELECT * from ec_sub${sub}categories c - WHERE ${sub}category_id = :${sub}category_id - AND exists ( - SELECT 'x' from ec_products_displayable p, $product_map(sub$sub) s - where p.product_id = s.product_id - and s.sub${sub}category_id = c.sub${sub}category_id - ) - ORDER BY sort_key, sub${sub}category_name - - - - - Index: openacs-4/packages/ecommerce/www/category-browse-subsubcategory.tcl =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/ecommerce/www/category-browse-subsubcategory.tcl,v diff -u -r1.2 -r1.3 --- openacs-4/packages/ecommerce/www/category-browse-subsubcategory.tcl 31 Jan 2002 22:43:54 -0000 1.2 +++ openacs-4/packages/ecommerce/www/category-browse-subsubcategory.tcl 26 May 2002 04:36:50 -0000 1.3 @@ -1,8 +1,7 @@ -# www/ecommerce/category-browse-subsubcategory.tcl ad_page_contract { - This one file is used to browse not only categories, but also subcategories and subsubcategories. - + This one file is used to browse not only categories, but also subcategories and subsubcategories. + @param category_id The ID of the category @param subcategory_id The ID of the subcategory @param subsubcategory_id The ID of the subsubcategory @@ -12,8 +11,9 @@ @author @creation-date - @cvs-id category-browse-subsubcategory.tcl,v 3.2.2.7 2000/08/18 21:46:31 stevenp Exp @author ported by Jerry Asher (jerry@theashergroup.com) + @author revision Bart Teeuwisse + @revision-date May 2002 } { category_id:naturalnum,notnull subcategory_id:optional,naturalnum @@ -39,9 +39,8 @@ set user_session_id [ec_get_user_session_id] +# See if they're logged in - -# see if they're logged in set user_id [ad_verify_and_get_user_id] if { $user_id != 0 } { set user_name [db_string get_full_name "select first_names || ' ' || last_name from cc_users where user_id=:user_id"] @@ -83,45 +82,40 @@ # Recommended products in this category -set recommendations "" +set recommendations "" -set header_to_print "We Recommend

    " -set header_printed 0 - if { [ad_parameter -package_id [ec_id] UserClassApproveP ecommerce] } { set user_class_approved_p_clause "and user_class_approved_p = 't'" } else { set user_class_approved_p_clause "" } -db_foreach get_recommended_products "select - p.product_name, p.product_id, p.dirname, r.recommendation_text -from ec_products_displayable p, ec_product_recommendations r -where p.product_id = r.product_id -and r.${sub}category_id=:${sub}category_id -and r.active_p='t' -and (r.user_class_id is null or r.user_class_id in - (select user_class_id - from ec_user_class_user_map m - where user_id=:user_id - $user_class_approved_p_clause)) -order by p.product_name" { +db_foreach get_recommended_products " + select p.product_id, p.product_name, p.dirname, r.recommendation_text, o.offer_code + from ec_product_recommendations r, ec_products_displayable p left outer join ec_user_session_offer_codes o on (p.product_id = o.product_id and user_session_id = :user_session_id) + where p.product_id = r.product_id + and r.${sub}category_id=:${sub}category_id + and r.active_p='t' + and (r.user_class_id is null or r.user_class_id in (select user_class_id + from ec_user_class_user_map m + where user_id=:user_id + $user_class_approved_p_clause)) + order by p.product_name" { - if { !$header_printed } { - append recommendations $header_to_print - incr header_printed - } - append recommendations "

    - - - - -
    [ec_linked_thumbnail_if_it_exists $dirname "f" "t"]$product_name -

    -$recommendation_text -

    -" + append recommendations " + + [ec_linked_thumbnail_if_it_exists $dirname "f" "t"] + $product_name +

    $recommendation_text

    + + [ec_price_line $product_id $user_id $offer_code] + " } +if {[string equal $recommendations ""]} { + set recommendations "" +} else { + append recommendations "
    " +} #============================== # products @@ -130,31 +124,40 @@ set exclude_subproducts "" if ![at_bottom_level_p] { - set exclude_subproducts " + set exclude_subproducts " and not exists ( -select 'x' from $product_map(sub$sub) s, ec_sub${sub}categories c - where p.product_id = s.product_id - and s.sub${sub}category_id = c.sub${sub}category_id - and c.${sub}category_id = :${sub}category_id) + select 'x' from $product_map(sub$sub) s, ec_sub${sub}categories c + where p.product_id = s.product_id + and s.sub${sub}category_id = c.sub${sub}category_id + and c.${sub}category_id = :${sub}category_id) " } -set products "" +set products "" set have_how_many_more_p f set count 0 -db_foreach get_regular_product_list "select p.product_id, p.product_name, p.one_line_description -from ec_products_searchable p, $product_map($sub) m -where p.product_id = m.product_id -and m.${sub}category_id = :${sub}category_id -$exclude_subproducts -order by p.product_name -" { +db_foreach get_regular_product_list " + select p.product_id, p.product_name, p.one_line_description, o.offer_code + from $product_map($sub) m, ec_products_searchable p left outer join ec_user_session_offer_codes o on (p.product_id = o.product_id and user_session_id = :user_session_id) + where p.product_id = m.product_id + and m.${sub}category_id = :${sub}category_id + $exclude_subproducts + order by p.product_name" { if { $count >= $start && [expr $count - $start] < $how_many } { - append products "
    [expr $count + 1]$product_name
    $one_line_description
    \n" + append products " + + [expr $count + 1] + $product_name + + + + $one_line_description + [ec_price_line $product_id $user_id $offer_code] + " } incr count if { $count > [expr $start + (2 * $how_many)] } { @@ -166,7 +169,7 @@ } } -append products "" +append products "" if { $start >= $how_many } { set prev_link "Previous $how_many" @@ -196,7 +199,7 @@ set subcategories "" if ![at_bottom_level_p] { - db_foreach get_subcategories " + db_foreach get_subcategories " SELECT * from ec_sub${sub}categories c WHERE ${sub}category_id = :${sub}category_id AND exists ( @@ -207,14 +210,12 @@ ORDER BY sort_key, sub${sub}category_name " { - - append subcategories "
  • [eval "ident \$sub${sub}category_name"]" - } + + append subcategories "
  • [eval "ident \$sub${sub}category_name"]" } +} -set the_category_id [eval "ident \$${sub}category_id"] +set the_category_id $category_id set the_category_name [eval "ident \$${sub}category_name"] db_release_unused_handles -ec_return_template - - +ad_return_template Index: openacs-4/packages/ecommerce/www/category-browse-subsubcategory.xql =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/ecommerce/www/category-browse-subsubcategory.xql,v diff -u -r1.1 -r1.2 --- openacs-4/packages/ecommerce/www/category-browse-subsubcategory.xql 10 Jul 2001 20:42:02 -0000 1.1 +++ openacs-4/packages/ecommerce/www/category-browse-subsubcategory.xql 26 May 2002 04:36:50 -0000 1.2 @@ -1,86 +1,86 @@ + - - - select first_names || ' ' || last_name from cc_users where user_id=:user_id - - + + + select first_names || ' ' || last_name + from cc_users + where user_id=:user_id + + - - - - insert into ec_user_session_info (user_session_id, category_id) values (:user_session_id, :category_id) - - + + + insert into ec_user_session_info + (user_session_id, category_id) + values + (:user_session_id, :category_id) + + - - - - select category_name from ec_categories where category_id=:category_id - - + + + select category_name + from ec_categories + where category_id=:category_id + + - - - - select subcategory_name from ec_subcategories where subcategory_id=:subcategory_id - - + + + select subcategory_name + from ec_subcategories + where subcategory_id=:subcategory_id + + - - - - select subsubcategory_name from ec_subsubcategories where subsubcategory_id=:subsubcategory_id - - + + + select subsubcategory_name + from ec_subsubcategories + where subsubcategory_id=:subsubcategory_id + + - - - - select - p.product_name, p.product_id, p.dirname, r.recommendation_text -from ec_products_displayable p, ec_product_recommendations r -where p.product_id = r.product_id -and r.${sub}category_id=:${sub}category_id -and r.active_p='t' -and (r.user_class_id is null or r.user_class_id in - (select user_class_id - from ec_user_class_user_map m - where user_id=:user_id - $user_class_approved_p_clause)) -order by p.product_name - - + + + select p.product_id, p.product_name, p.dirname, r.recommendation_text, o.offer_code + from ec_product_recommendations r, ec_products_displayable p left outer join ec_user_session_offer_codes o on + (p.product_id = o.product_id and user_session_id = :user_session_id) + where p.product_id = r.product_id + and r.${sub}category_id=:${sub}category_id + and r.active_p='t' + and (r.user_class_id is null or r.user_class_id in (select user_class_id + from ec_user_class_user_map m + where user_id=:user_id + $user_class_approved_p_clause)) + order by p.product_name + + - - - - select p.product_id, p.product_name, p.one_line_description -from ec_products_searchable p, $product_map($sub) m -where p.product_id = m.product_id -and m.${sub}category_id = :${sub}category_id -$exclude_subproducts -order by p.product_name + + + select p.product_id, p.product_name, p.one_line_description, o.offer_code + from $product_map($sub) m, ec_products_searchable p left outer join ec_user_session_offer_codes o on + (p.product_id = o.product_id and user_session_id = :user_session_id) + where p.product_id = m.product_id + and m.${sub}category_id = :${sub}category_id + $exclude_subproducts + order by p.product_name + + - - + + + select * from ec_sub${sub}categories c + where ${sub}category_id = :${sub}category_id + and exists (select 'x' + from ec_products_displayable p, $product_map(sub$sub) s + where p.product_id = s.product_id + and s.sub${sub}category_id = c.sub${sub}category_id) + order by sort_key, sub${sub}category_name + + - - - - -SELECT * from ec_sub${sub}categories c - WHERE ${sub}category_id = :${sub}category_id - AND exists ( - SELECT 'x' from ec_products_displayable p, $product_map(sub$sub) s - where p.product_id = s.product_id - and s.sub${sub}category_id = c.sub${sub}category_id - ) - ORDER BY sort_key, sub${sub}category_name - - - - - Index: openacs-4/packages/ecommerce/www/category-browse.tcl =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/ecommerce/www/category-browse.tcl,v diff -u -r1.2 -r1.3 --- openacs-4/packages/ecommerce/www/category-browse.tcl 31 Jan 2002 22:43:54 -0000 1.2 +++ openacs-4/packages/ecommerce/www/category-browse.tcl 26 May 2002 04:36:50 -0000 1.3 @@ -1,4 +1,3 @@ -# www/ecommerce/category-browse.tcl ad_page_contract { This one file is used to browse not only categories, but also subcategories and subsubcategories. @@ -12,27 +11,57 @@ @author @creation-date - @cvs-id category-browse.tcl,v 3.2.2.7 2000/08/18 21:46:31 stevenp Exp @author ported by Jerry Asher (jerry@theashergroup.com) + @author revised by Bart Teeuwisse + @revision-date May 2002 } { - category_id:notnull,naturalnum + category_id:optional,naturalnum subcategory_id:optional,naturalnum subsubcategory_id:optional,naturalnum {how_many:naturalnum {[ad_parameter -package_id [ec_id] ProductsToDisplayPerPage ecommerce]}} {start:naturalnum "0"} usca_p:optional } +# Redirect the visitor the store home page if no category_id has been +# selected. -proc ident {x} {return $x} -proc have {var} { upvar $var x; return [expr {[info exists x] && [string compare $x "0"] != 0}]} -proc in_subcat {} {return [uplevel {have subcategory_id}]} -proc in_subsubcat {} {return [uplevel {have subsubcategory_id}]} -proc at_bottom_level_p {} {return [uplevel in_subsubcat]} +if {![info exists category_id] || ([info exists category_id] && [empty_string_p $category_id])} { + ad_returnredirect index +} +proc ident {x} { + return $x +} + +proc have {var} { + upvar $var x + return [expr {[info exists x] && [string compare $x "0"] != 0}] +} + +proc in_subcat {} { + return [uplevel {have subcategory_id}] +} + +proc in_subsubcat {} { + return [uplevel {have subsubcategory_id}] +} + +proc at_bottom_level_p {} { + return [uplevel in_subsubcat] +} + set sub "" -if [in_subcat] {append sub "sub"} else {set subcategory_id 0} -if [in_subsubcat] {append sub "sub"} else {set subsubcategory_id 0} +if {[in_subcat]} { + append sub "sub" +} else { + set subcategory_id 0 +} +if {[in_subsubcat]} { + append sub "sub" +} else { + set subsubcategory_id 0 +} set product_map() "ec_category_product_map" set product_map(sub) "ec_subcategory_product_map" @@ -59,68 +88,75 @@ # 4. Log this category_id into the user session ec_create_new_session_if_necessary [export_url_vars category_id subcategory_id subsubcategory_id how_many start] cookies_are_not_required -# type4 if { [string compare $user_session_id "0"] != 0 } { - db_dml grab_new_session_id "insert into ec_user_session_info (user_session_id, category_id) values (:user_session_id, :category_id)" + db_dml grab_new_session_id " + insert into ec_user_session_info + (user_session_id, category_id) + values + (:user_session_id, :category_id)" } -set category_name [db_string get_category_name "select category_name from ec_categories where category_id=:category_id"] +set category_name [db_string get_category_name " + select category_name + from ec_categories + where category_id=:category_id"] set subcategory_name "" if [have subcategory_id] { - set subcategory_name [db_string get_subcat_name "select subcategory_name from ec_subcategories where subcategory_id=:subcategory_id"] + set subcategory_name [db_string get_subcat_name " + select subcategory_name + from ec_subcategories + where subcategory_id = :subcategory_id"] } set subsubcategory_name "" if [have subsubcategory_id] { - set subsubcategory_name [db_string get_subsubcat_name "select subsubcategory_name from ec_subsubcategories where subsubcategory_id=:subsubcategory_id"] + set subsubcategory_name [db_string get_subsubcat_name " + select subsubcategory_name + from ec_subsubcategories + where subsubcategory_id = :subsubcategory_id"] } #============================== # recommendations # Recommended products in this category -set recommendations "" +set recommendations "" -set header_to_print "We Recommend

    " -set header_printed 0 - if { [ad_parameter -package_id [ec_id] UserClassApproveP ecommerce] } { set user_class_approved_p_clause "and user_class_approved_p = 't'" } else { set user_class_approved_p_clause "" } -db_foreach get_recommended_products "select - p.product_name, p.product_id, p.dirname, r.recommendation_text -from ec_products_displayable p, ec_product_recommendations r -where p.product_id = r.product_id -and r.${sub}category_id=:${sub}category_id -and r.active_p='t' -and (r.user_class_id is null or r.user_class_id in - (select user_class_id - from ec_user_class_user_map m - where user_id=:user_id - $user_class_approved_p_clause)) -order by p.product_name" { +db_foreach get_recommended_products " + select p.product_id, p.product_name, p.dirname, r.recommendation_text, o.offer_code + from ec_product_recommendations r, ec_products_displayable p left outer join ec_user_session_offer_codes o on (p.product_id = o.product_id and user_session_id = :user_session_id) + where p.product_id = r.product_id + and r.${sub}category_id=:${sub}category_id + and r.active_p='t' + and (r.user_class_id is null or r.user_class_id in (select user_class_id + from ec_user_class_user_map m + where user_id=:user_id + $user_class_approved_p_clause)) + order by p.product_name" { - if { !$header_printed } { - append recommendations $header_to_print - incr header_printed - } - append recommendations "

    - - - - -
    [ec_linked_thumbnail_if_it_exists $dirname "f" "t"]$product_name -

    -$recommendation_text -

    -" + append recommendations " + + [ec_linked_thumbnail_if_it_exists $dirname "f" "t"] + $product_name +

    $recommendation_text

    + + [ec_price_line $product_id $user_id $offer_code] + " } +if {[string equal $recommendations ""]} { + set recommendations "" +} else { + append recommendations "
    " +} #============================== # products @@ -129,43 +165,53 @@ set exclude_subproducts "" if ![at_bottom_level_p] { - set exclude_subproducts " -and not exists ( -select 'x' from $product_map(sub$sub) s, ec_sub${sub}categories c - where p.product_id = s.product_id - and s.sub${sub}category_id = c.sub${sub}category_id - and c.${sub}category_id = :${sub}category_id) -" + set exclude_subproducts " + and not exists (select 'x' from $product_map(sub$sub) s, ec_sub${sub}categories c + where p.product_id = s.product_id + and s.sub${sub}category_id = c.sub${sub}category_id + and c.${sub}category_id = :${sub}category_id)" } -set products "" +set products "" set have_how_many_more_p f set count 0 -db_foreach get_regular_product_list "select p.product_id, p.product_name, p.one_line_description -from ec_products_searchable p, $product_map($sub) m -where p.product_id = m.product_id -and m.${sub}category_id = :${sub}category_id -$exclude_subproducts -order by p.product_name -" { +db_foreach get_regular_product_list " + select p.product_id, p.product_name, p.one_line_description, o.offer_code + from $product_map($sub) m, ec_products_searchable p left outer join ec_user_session_offer_codes o on (p.product_id = o.product_id and user_session_id = :user_session_id) + where p.product_id = m.product_id + and m.${sub}category_id = :${sub}category_id + $exclude_subproducts + order by p.product_name" { if { $count >= $start && [expr $count - $start] < $how_many } { - append products "
    [expr $count + 1]$product_name
    $one_line_description
    \n" + append products " + + [expr $count + 1] + $product_name + + + + $one_line_description + [ec_price_line $product_id $user_id $offer_code] + " } incr count if { $count > [expr $start + (2 * $how_many)] } { - # we know there are at least how_many more items to display next time + + # We know there are at least how_many more items to display + # next time + set have_how_many_more_p t break } else { set have_how_many_more_p f } } -append products "" +append products "" if { $start >= $how_many } { set prev_link "Previous $how_many" @@ -195,25 +241,20 @@ set subcategories "" if ![at_bottom_level_p] { - db_foreach get_subcategories " -SELECT * from ec_sub${sub}categories c - WHERE ${sub}category_id = :${sub}category_id - AND exists ( - SELECT 'x' from ec_products_displayable p, $product_map(sub$sub) s - where p.product_id = s.product_id - and s.sub${sub}category_id = c.sub${sub}category_id - ) - ORDER BY sort_key, sub${sub}category_name -" { + db_foreach get_subcategories " + select * from ec_sub${sub}categories c + where ${sub}category_id = :${sub}category_id + and exists (select 'x' from ec_products_displayable p, $product_map(sub$sub) s + where p.product_id = s.product_id + and s.sub${sub}category_id = c.sub${sub}category_id) + order by sort_key, sub${sub}category_name" { - - append subcategories "
  • [eval "ident \$sub${sub}category_name"]" + append subcategories " +
  • [eval "ident \$sub${sub}category_name"]
  • " } } set the_category_id [eval "ident \$${sub}category_id"] set the_category_name [eval "ident \$${sub}category_name"] db_release_unused_handles -ec_return_template - - +ad_return_template Index: openacs-4/packages/ecommerce/www/category-browse.xql =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/ecommerce/www/category-browse.xql,v diff -u -r1.1 -r1.2 --- openacs-4/packages/ecommerce/www/category-browse.xql 10 Jul 2001 20:42:02 -0000 1.1 +++ openacs-4/packages/ecommerce/www/category-browse.xql 26 May 2002 04:36:50 -0000 1.2 @@ -1,86 +1,86 @@ + - - - select first_names || ' ' || last_name from cc_users where user_id=:user_id - - + + + select first_names || ' ' || last_name + from cc_users + where user_id=:user_id + + - - - - insert into ec_user_session_info (user_session_id, category_id) values (:user_session_id, :category_id) - - + + + insert into ec_user_session_info + (user_session_id, category_id) + values + (:user_session_id, :category_id) + + - - - - select category_name from ec_categories where category_id=:category_id - - + + + select category_name + from ec_categories + where category_id=:category_id + + - - - - select subcategory_name from ec_subcategories where subcategory_id=:subcategory_id - - + + + select subcategory_name + from ec_subcategories + where subcategory_id=:subcategory_id + + - - - - select subsubcategory_name from ec_subsubcategories where subsubcategory_id=:subsubcategory_id - - + + + select subsubcategory_name + from ec_subsubcategories + where subsubcategory_id=:subsubcategory_id + + - - - - select - p.product_name, p.product_id, p.dirname, r.recommendation_text -from ec_products_displayable p, ec_product_recommendations r -where p.product_id = r.product_id -and r.${sub}category_id=:${sub}category_id -and r.active_p='t' -and (r.user_class_id is null or r.user_class_id in - (select user_class_id - from ec_user_class_user_map m - where user_id=:user_id - $user_class_approved_p_clause)) -order by p.product_name - - + + + select p.product_id, p.product_name, p.dirname, r.recommendation_text, o.offer_code + from ec_product_recommendations r, + ec_products_displayable p left outer join ec_user_session_offer_codes o on + (p.product_id = o.product_id and user_session_id = :user_session_id) + where p.product_id = r.product_id + and r.${sub}category_id=:${sub}category_id + and r.active_p='t' + and (r.user_class_id is null or r.user_class_id in (select user_class_id + from ec_user_class_user_map m + where user_id=:user_id + $user_class_approved_p_clause)) + order by p.product_name + + - - - - select p.product_id, p.product_name, p.one_line_description -from ec_products_searchable p, $product_map($sub) m -where p.product_id = m.product_id -and m.${sub}category_id = :${sub}category_id -$exclude_subproducts -order by p.product_name + + + select p.product_id, p.product_name, p.one_line_description, o.offer_code + from $product_map($sub) m, ec_products_searchable p left outer join ec_user_session_offer_codes o on (p.product_id = o.product_id and user_session_id = :user_session_id) + where p.product_id = m.product_id + and m.${sub}category_id = :${sub}category_id + $exclude_subproducts + order by p.product_name + + - - + + + select * from ec_sub${sub}categories c + where ${sub}category_id = :${sub}category_id + and exists (select 'x' + from ec_products_displayable p, $product_map(sub$sub) s + where p.product_id = s.product_id + and s.sub${sub}category_id = c.sub${sub}category_id) + order by sort_key, sub${sub}category_name + + - - - - -SELECT * from ec_sub${sub}categories c - WHERE ${sub}category_id = :${sub}category_id - AND exists ( - SELECT 'x' from ec_products_displayable p, $product_map(sub$sub) s - where p.product_id = s.product_id - and s.sub${sub}category_id = c.sub${sub}category_id - ) - ORDER BY sort_key, sub${sub}category_name - - - - - Index: openacs-4/packages/ecommerce/www/checkout-2-oracle.xql =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/ecommerce/www/checkout-2-oracle.xql,v diff -u -r1.1 -r1.2 --- openacs-4/packages/ecommerce/www/checkout-2-oracle.xql 10 Jul 2001 20:42:02 -0000 1.1 +++ openacs-4/packages/ecommerce/www/checkout-2-oracle.xql 26 May 2002 04:36:50 -0000 1.2 @@ -1,28 +1,23 @@ - oracle8.1.6 + + 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 - - + + + 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 + + - Index: openacs-4/packages/ecommerce/www/checkout-2.tcl =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/ecommerce/www/checkout-2.tcl,v diff -u -r1.5 -r1.6 --- openacs-4/packages/ecommerce/www/checkout-2.tcl 16 Feb 2002 23:32:06 -0000 1.5 +++ openacs-4/packages/ecommerce/www/checkout-2.tcl 26 May 2002 04:36:50 -0000 1.6 @@ -1,121 +1,153 @@ -# /www/ecommerce/checkout-2.tcl ad_page_contract { @param address_id a stored address @param usca_p User session started or not @author @creation-date - @cvs-id checkout-2.tcl,v 3.7.2.13 2000/08/18 21:46:32 stevenp Exp @author ported by Jerry Asher (jerry@theashergroup.com) @author Bart Teeuwisse + @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 +# 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]" return } -# user sessions: +# 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 +# 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' "] + +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 + + # No rows came back, so they probably got here by pushing "Back", + # so just redirect them to index.tcl + ad_returnredirect [ec_url]index.tcl return } 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; + # 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] return } -# 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 } { +# 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 } { ad_returnredirect [ec_url]shopping-cart return } -# either address_id should be a form variable, or it should already -# be in the database for this order +# 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 +# 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 +# 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 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"] + 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] return } - # it checks out ok - db_dml update_ec_order_address "update ec_orders set shipping_address=:address_id where order_id=:order_id" + + # 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 ""] + + 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] } { - ad_returnredirect [ec_securelink [ec_url]checkout] - return + + # 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] + return + } } } -# 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 -if { [ad_parameter -package_id [ec_id] ExpressShippingP ecommerce] } { - set form_action [ec_securelink [ec_url]select-shipping] -} else { - set form_action [ec_securelink [ec_url]process-order-quantity-shipping] -} +# 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" { + 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 @@ -133,26 +165,26 @@ } 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 " - - $product_name[ec_decode $options "" "" ", $options"]
    - [ec_price_line $product_id $user_id $offer_code] - - " + # 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 " + + + $product_name[ec_decode $options "" "" ", $options"]
    + [ec_price_line $product_id $user_id $offer_code] + " } -set checkout_step {Verify Order} set tax_exempt_options "" if { [ad_parameter -package_id [ec_id] OfferTaxExemptStatusP ecommerce 0] } { - append tax_exempt_options "

    -

  • Is your organization tax exempt? (If so, we will ask you to - provide us with an exemption certificate.) -

    - Yes
    - No" + append tax_exempt_options " +

  • Is your organization tax exempt? (If so, we will ask you to + provide us with an exemption certificate.)

    + Yes
    + No" } db_release_unused_handles -ec_return_template +ad_return_template Index: openacs-4/packages/ecommerce/www/checkout-2.xql =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/ecommerce/www/checkout-2.xql,v diff -u -r1.2 -r1.3 --- openacs-4/packages/ecommerce/www/checkout-2.xql 11 Jul 2001 04:52:04 -0000 1.2 +++ openacs-4/packages/ecommerce/www/checkout-2.xql 26 May 2002 04:36:50 -0000 1.3 @@ -1,68 +1,63 @@ + - - - - select order_id, - user_id as order_owner - 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 count(*) from ec_items 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 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 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 + + + 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 + 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/ecommerce/www/checkout-3-oracle.xql =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/ecommerce/www/checkout-3-oracle.xql,v diff -u -r1.1 -r1.2 --- openacs-4/packages/ecommerce/www/checkout-3-oracle.xql 10 Jul 2001 20:42:02 -0000 1.1 +++ openacs-4/packages/ecommerce/www/checkout-3-oracle.xql 26 May 2002 04:36:50 -0000 1.2 @@ -1,20 +1,23 @@ - oracle8.1.6 + + oracle + 8.1.6 + - - - select ec_order_cost(:order_id) from dual - - + + + select ec_order_cost(:order_id) + from dual + + - - - - select ec_gift_certificate_balance(:user_id) from dual - - + + + select ec_gift_certificate_balance(:user_id) + from dual + + - Index: openacs-4/packages/ecommerce/www/checkout-3-postgresql.xql =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/ecommerce/www/checkout-3-postgresql.xql,v diff -u -r1.1 -r1.2 --- openacs-4/packages/ecommerce/www/checkout-3-postgresql.xql 10 Jul 2001 20:42:02 -0000 1.1 +++ openacs-4/packages/ecommerce/www/checkout-3-postgresql.xql 26 May 2002 04:36:50 -0000 1.2 @@ -1,20 +1,21 @@ - postgresql7.1 + + postgresql + 7.1 + - - - select ec_order_cost(:order_id) - - + + + select ec_order_cost(:order_id) + + - - - - select ec_gift_certificate_balance(:user_id) - - + + + select ec_gift_certificate_balance(:user_id) + + - Index: openacs-4/packages/ecommerce/www/checkout-3.tcl =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/ecommerce/www/checkout-3.tcl,v diff -u -r1.2 -r1.3 --- openacs-4/packages/ecommerce/www/checkout-3.tcl 16 Feb 2002 23:32:06 -0000 1.2 +++ openacs-4/packages/ecommerce/www/checkout-3.tcl 26 May 2002 04:36:50 -0000 1.3 @@ -1,13 +1,17 @@ -# /www/ecommerce/checkout-3.tcl ad_page_contract { - Users should get here from process-order-quantity-payment-shipping.tcl; this page just summarizes their order before they submit it. + 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 @author @creation-date - @cvs-id checkout-3.tcl,v 3.2.6.7 2000/08/18 21:46:32 stevenp Exp @author ported by Jerry Asher (jerry@theashergroup.com) + @author revised by Bart Teeuwisse + @revision-date April 2002 + } { usca_p:optional } @@ -23,80 +27,123 @@ # 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] +# 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]" return } -# make sure they have an in_basket order, otherwise they've probably +# 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 ""] +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 + + # Then they probably got here by pushing "Back", so just redirect + # them to index.tcl + ad_returnredirect index return } -# make sure there's something in their shopping cart, otherwise -# redirect them to their shopping cart which will tell them -# that it's empty. +# 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 } { +if { [db_string get_ec_item_count " + select count(*) + from ec_items + where order_id=:order_id"] == 0 } { ad_returnredirect shopping-cart return } -# 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"] +# 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 } { ad_returnredirect checkout return } -# 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 ""] +# 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] } { - ad_returnredirect checkout - return + + # 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] + return + } } -# 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 ""] +# 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"] + # 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 ""] +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")) } { ad_returnredirect checkout-2 return } -# done with all the checks -# their order is ready to go! -# now show them a summary before they submit their order +# Done with all the checks. Their order is ready to go! Now show +# them a summary before they submit their order + set order_summary [ec_order_summary_for_customer $order_id $user_id] db_release_unused_handles - -ec_return_template \ No newline at end of file Index: openacs-4/packages/ecommerce/www/checkout-3.xql =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/ecommerce/www/checkout-3.xql,v diff -u -r1.1 -r1.2 --- openacs-4/packages/ecommerce/www/checkout-3.xql 10 Jul 2001 20:42:02 -0000 1.1 +++ openacs-4/packages/ecommerce/www/checkout-3.xql 26 May 2002 04:36:50 -0000 1.2 @@ -1,46 +1,54 @@ + - - - 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_session_id=:user_session_id + and order_state='in_basket' + + - - - - select count(*) from ec_items where order_id=:order_id - - + + + select count(*) + from ec_items + where order_id=:order_id + + - - - - select user_id from ec_orders 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 shipping_address + from ec_orders + where order_id=$order_id + + - - - - select creditcard_id 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 - - + + + select shipping_method + from ec_orders + where order_id=:order_id + + - Index: openacs-4/packages/ecommerce/www/checkout-oracle.xql =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/ecommerce/www/checkout-oracle.xql,v diff -u -r1.1 -r1.2 --- openacs-4/packages/ecommerce/www/checkout-oracle.xql 10 Jul 2001 20:42:02 -0000 1.1 +++ openacs-4/packages/ecommerce/www/checkout-oracle.xql 26 May 2002 04:36:50 -0000 1.2 @@ -1,20 +1,21 @@ - oracle8.1.6 + + 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') - - + + + 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/ecommerce/www/checkout-postgresql.xql =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/ecommerce/www/checkout-postgresql.xql,v diff -u -r1.1 -r1.2 --- openacs-4/packages/ecommerce/www/checkout-postgresql.xql 10 Jul 2001 20:42:02 -0000 1.1 +++ openacs-4/packages/ecommerce/www/checkout-postgresql.xql 26 May 2002 04:36:50 -0000 1.2 @@ -1,20 +1,20 @@ - postgresql7.1 + + 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') - - + + + 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/ecommerce/www/checkout.tcl =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/ecommerce/www/checkout.tcl,v diff -u -r1.3 -r1.4 --- openacs-4/packages/ecommerce/www/checkout.tcl 16 Feb 2002 23:32:06 -0000 1.3 +++ openacs-4/packages/ecommerce/www/checkout.tcl 26 May 2002 04:36:50 -0000 1.4 @@ -1,19 +1,18 @@ -# /www/ecommerce/checkout.tcl ad_page_contract { @param usca_p:optional @author @creation-date - @cvs-id checkout.tcl,v 3.4.2.10 2000/10/31 14:03:13 elorenzo Exp @author ported by Jerry Asher (jerry@theashergroup.com) + @author revised by Bart Teeuwisse + @revision-date April 2002 } { usca_p:optional } -# rolled login requirement into ec_redirect_to_https_if_possible_and_necessary ec_redirect_to_https_if_possible_and_necessary -# make sure they have an in_basket order, otherwise they've probably +# 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_verify_and_get_user_id] @@ -22,66 +21,62 @@ 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 "" ] +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 + + # Then they probably got here by pushing "Back", so just redirect + # them to index.tcl + ad_returnredirect index template::adp_abort } else { - db_dml update_ec_order_set_uid "update ec_orders set user_id=:user_id where order_id=:order_id" + db_dml update_ec_order_set_uid " + update ec_orders + set user_id = :user_id + where order_id = :order_id" } -# check whether or not shipping is available -set shipping_unavail_p [db_string check_order_shippable " - 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')"] +# See if there are any saved shipping addresses for this user -# see if there are any saved shipping addresses for this user -set saved_addresses " -You can select an address listed below or enter a new address. - -" +set address_type "shipping" -# Present all saved addresses -db_foreach get_user_addresses " -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' -" { +# Check if the order requires shipping - # Present a single saved address - append saved_addresses " - - - - - " +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"]} { -} if_no_rows { - set saved_addresses "" -} + set shipping_required true -# Add closing table tag if there are saved addresses -if {![empty_string_p $saved_addresses] } { - append saved_addresses " -
    [ec_display_as_html [ec_pretty_mailing_address_from_args $line1 $line2 $city $usps_abbrev $zip_code $country_code $full_state_name $attn $phone $phone_time]]

    \[use this address\]
    - \[edit this address\]
    - \[delete this address\]

    - " + # 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]" + set row(edit) "[export_form_vars address_id address_type]" + set row(use) "[export_form_vars address_id]" + } + set hidden_form_vars [export_form_vars address_type] +} else { + set address_id "" + set hidden_form_vars [export_form_vars address_id address_type] + set shipping_required false } db_release_unused_handles -ec_return_template Index: openacs-4/packages/ecommerce/www/checkout.xql =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/ecommerce/www/checkout.xql,v diff -u -r1.1 -r1.2 --- openacs-4/packages/ecommerce/www/checkout.xql 10 Jul 2001 20:42:02 -0000 1.1 +++ openacs-4/packages/ecommerce/www/checkout.xql 26 May 2002 04:36:50 -0000 1.2 @@ -1,35 +1,31 @@ + - - - 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_session_id=:user_session_id + and order_state='in_basket' + + - - - - update ec_orders set user_id=:user_id where order_id=:order_id - - + + + 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' + + + 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/ecommerce/www/credit-card-correction-2.tcl =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/ecommerce/www/credit-card-correction-2.tcl,v diff -u -r1.2 -r1.3 --- openacs-4/packages/ecommerce/www/credit-card-correction-2.tcl 29 Jan 2002 00:11:46 -0000 1.2 +++ openacs-4/packages/ecommerce/www/credit-card-correction-2.tcl 26 May 2002 04:36:50 -0000 1.3 @@ -1,95 +1,110 @@ -# /www/ecommerce/credit-card-correction-2.tcl ad_page_contract { - 1. do the normal url/cookie surgery checks - 2. insert credit card data into ec_creditcards - 3. update orders to use this credit card - 4. redirect to finalize-order.tcl to process this info + 1. do the normal url/cookie surgery checks + 2. insert credit card data into ec_creditcards + 3. update orders to use this credit card + 4. redirect to finalize-order.tcl to process this info + @param creditcard_number Their credit card number @param creditcard_type The brand of credit card @param creditcard_expire_1 The month of expiration @param creditcard_expire_2 The year of expiration - @param billing_zip_code The zip code of the billing address @author @creation-date - @cvs-id credit-card-correction-2.tcl,v 3.3.2.8 2000/08/18 21:46:32 stevenp Exp @author ported by Jerry Asher (jerry@theashergroup.com) + @author revised by Bart Teeuwisse + @revision-date April 2002 + } { + address_id:notnull creditcard_number:notnull creditcard_type:notnull creditcard_expire_1:notnull creditcard_expire_2:notnull - billing_zip_code:notnull } -# Doubleclick problem: -# There is a small but finite amount of time between the time that the user runs -# this script and the time that their order goes into the 'confirmed' state. -# During this time, it is possible for the user to submit their credit card info -# twice, thereby adding rows to ec_creditcards. -# However, no order will be updated after it's confirmed, so this credit card info -# will be unreferenced by any order and we can delete it with a cron job. +# Doubleclick problem: There is a small but finite amount of time +# between the time that the user runs this script and the time that +# their order goes into the 'confirmed' state. During this time, it +# is possible for the user to submit their credit card info twice, +# thereby adding rows to ec_creditcards. However, no order will be +# updated after it's confirmed, so this credit card info will be +# unreferenced by any order and we can delete it with a cron job. -# first do the basic error checking -# also get rid of spaces and dashes in the credit card number +# First do the basic error checking. Also get rid of spaces and +# dashes in the credit card number + if { [info exists creditcard_number] } { - # get rid of spaces and dashes + + # Get rid of spaces and dashes + regsub -all -- "-" $creditcard_number "" creditcard_number - regsub -all " " $creditcard_number "" creditcard_number + regsub -all -- " " $creditcard_number "" creditcard_number } 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 + + # I've already removed spaces and dashes, so only numbers should + # remain + incr exception_count - append exception_text "
  • Your credit card number contains invalid characters." + append exception_text "
  • Your credit card number contains invalid characters.
  • " } -# 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] +# 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 { $exception_count > 0 } { ad_return_complaint $exception_count $exception_text return } -# then do all the normal checks to make sure nobody is doing url -# or cookie surgery to get here +# Then 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] +# 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]?[export_url_vars creditcard_number creditcard_type creditcard_expire_1 creditcard_expire_2 billing_zip_code]" - + set return_url "[ad_conn url]?[export_url_vars creditcard_number creditcard_type creditcard_expire_1 creditcard_expire_2]." ad_returnredirect "/register?[export_url_vars return_url]" return } -# 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 +# 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 set user_session_id [ec_get_user_session_id] +set order_id [db_string get_order_id_from_basket " + select order_id + from ec_orders + where user_session_id = :user_session_id + and order_state = 'in_basket'" -default ""] -set order_id [db_string get_order_id_from_basket "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 ""] + # 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] } { ad_returnredirect index } else { @@ -98,45 +113,56 @@ return } -# make sure there's something in their shopping cart, otherwise -# redirect them to their shopping cart which will tell them -# that it's empty. +# 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 } { +if { [db_string get_ec_item_count " + select count(*) + from ec_items + where order_id=:order_id"] == 0 } { ad_returnredirect shopping-cart return } -# 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"] +# 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 } { ad_returnredirect checkout return } -# done with all the checks! +# Done with all the checks! -# do some inserts -set creditcard_id [db_nextval ec_creditcard_id_sequence] +# Do some inserts +set creditcard_id [db_nextval ec_creditcard_id_sequence] db_transaction { -set cc_fmt "[string range $creditcard_number [expr [string length $creditcard_number] -4] [expr [string length $creditcard_number] -1]]" -set expiry "$creditcard_expire_1/$creditcard_expire_2" + set cc_fmt "[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_creditcard "insert into ec_creditcards -(creditcard_id, user_id, creditcard_number, creditcard_last_four, creditcard_type, creditcard_expire, billing_zip_code) -values -(:creditcard_id, :user_id, :creditcard_number,:cc_fmt , :creditcard_type,:expiry,:billing_zip_code) -" + db_dml insert_new_creditcard " + 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_fmt , :creditcard_type, :expiry, :address_id)" -# make sure order is still in the 'in_basket' state while doing the -# insert because it could have been confirmed in the (small) time -# it took to get from "set order_id ..." to here -# if not, no harm done; no rows will be updated + # Make sure order is still in the 'in_basket' state while doing + # the insert because it could have been confirmed in the (small) + # time it took to get from "set order_id ..." to here if not, no + # harm done; no rows will be updated -db_dml update_order_cc_info "update ec_orders set creditcard_id=:creditcard_id where order_id=:order_id and order_state='in_basket'" + db_dml update_order_cc_info " + update ec_orders + set creditcard_id = :creditcard_id + where order_id = :order_id + and order_state = 'in_basket'" } db_release_unused_handles Index: openacs-4/packages/ecommerce/www/credit-card-correction-2.xql =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/ecommerce/www/credit-card-correction-2.xql,v diff -u -r1.1 -r1.2 --- openacs-4/packages/ecommerce/www/credit-card-correction-2.xql 10 Jul 2001 20:42:02 -0000 1.1 +++ openacs-4/packages/ecommerce/www/credit-card-correction-2.xql 26 May 2002 04:36:50 -0000 1.2 @@ -1,50 +1,61 @@ + - - - 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_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 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 count(*) + from ec_items + where order_id = :order_id + + - - - - select user_id from ec_orders where order_id=:order_id - - + + + select user_id + from ec_orders + where order_id = :order_id + + - - - + + insert into ec_creditcards -(creditcard_id, user_id, creditcard_number, creditcard_last_four, creditcard_type, creditcard_expire, billing_zip_code) -values -(:creditcard_id, :user_id, :creditcard_number,:cc_fmt , :creditcard_type,:expiry,:billing_zip_code) + (creditcard_id, user_id, creditcard_number, creditcard_last_four, creditcard_type, creditcard_expire, billing_address) + values + (:creditcard_id, :user_id, :creditcard_number,:cc_fmt , :creditcard_type, :expiry, :address_id) + + - - + + + update ec_orders + set creditcard_id = :creditcard_id + where order_id = :order_id + and order_state = 'in_basket' + + - - - - update ec_orders set creditcard_id=:creditcard_id where order_id=:order_id and order_state='in_basket' - - - - Index: openacs-4/packages/ecommerce/www/credit-card-correction.tcl =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/ecommerce/www/credit-card-correction.tcl,v diff -u -r1.1 -r1.2 --- openacs-4/packages/ecommerce/www/credit-card-correction.tcl 20 Apr 2001 20:51:13 -0000 1.1 +++ openacs-4/packages/ecommerce/www/credit-card-correction.tcl 26 May 2002 04:36:50 -0000 1.2 @@ -1,100 +1,106 @@ -# /www/ecommerce/credit-card-correction.tcl ad_page_contract { - Gives them a chance to correct the information for a credit card that CyberCash rejected + + Gives them a chance to correct the information for a credit card + that the payment gateway rejected. + @param usca_p User session started or not @author @creation-date - @cvs-id credit-card-correction.tcl,v 3.3.2.9 2000/08/18 21:46:32 stevenp Exp @author ported by Jerry Asher (jerry@theashergroup.com) + @author revised by Bart Teeuwisse + @revision-date April 2002 + } { usca_p:optional } -# The order that we're trying to reauthorize is the 'in_basket' order for their user_session_id -# because orders are put back into the 'in_basket' state when their authorization fails +# The order that we're trying to reauthorize is the 'in_basket' order +# for their user_session_id because orders are put back into the +# 'in_basket' state when their authorization fails -# We can't just update ec_creditcards with the new info because there might be a previous -# order which points to this credit card, so insert a new row into ec_creditcards. -# Obvious mistypes (wrong # of digits, etc.) will be weeded out before this point anyway, -# so the ec_creditcards table shouldn't get too huge. +# We can't just update ec_creditcards with the new info because there +# might be a previous order which points to this credit card, so +# insert a new row into ec_creditcards. Obvious mistypes (wrong # of +# digits, etc.) will be weeded out before this point anyway, so the +# ec_creditcards table shouldn't get too huge. -# do all the normal url/cookie surgery checks -# except don't bother with the ones unneccessary for security (like "did they put in an address for -# this order?") because finalize-order.tcl (which they'll be going through to authorize their credit -# card) will take care of those. +# do all the normal url/cookie surgery checks except don't bother with +# the ones unneccessary for security (like "did they put in an address +# for this order?") because finalize-order.tcl (which they'll be going +# through to authorize their credit card) will take care of those. -# we need them to be logged in -set user_id [ad_verify_and_get_user_id] +# 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]" return } -# make sure they have an in_basket order +# Make sure they have an in_basket order set user_session_id [ec_get_user_session_id] - - ec_create_new_session_if_necessary -# type1 - 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 ""] - +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] } { ad_returnredirect index return } -# this isn't necessary for security, but might as well do it anyway, -# so they don't get confused thinking the order they probably -# just submitted before pressing Back failed again: -# make sure there's something in their shopping cart, otherwise -# redirect them to their shopping cart which will tell them -# that it's empty. +# This isn't necessary for security, but might as well do it anyway, +# so they don't get confused thinking the order they probably just +# submitted before pressing Back failed again: 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_inbasket "select count(*) from ec_items where order_id=:order_id"] == 0 } { +if { [db_string get_ec_item_count_inbasket " + select count(*) + from ec_items + where order_id = :order_id"] == 0 } { ad_returnredirect shopping-cart return } -# 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"] +# 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 } { ad_returnredirect checkout return } -# make sure there is a credit card for this order, otherwise -# they've probably gotten here via url surgery, so redirect them to checkout-2.tcl -# and while we're here, get the credit card info to pre-fill the form +# Make sure there is a credit card for this order, otherwise they've +# probably gotten here via url surgery, so redirect them to +# checkout-2.tcl and while we're here, get the credit card info to +# pre-fill the form -if { [db_0or1row get_cc_info "select creditcard_type, creditcard_number, creditcard_expire, billing_zip_code from -ec_creditcards, ec_orders -where ec_creditcards.creditcard_id=ec_orders.creditcard_id -and order_id=:order_id"] == 0 } { +if { [db_0or1row get_cc_info " + select c.creditcard_type, c.creditcard_number, c.creditcard_expire, a.* + from ec_creditcards c, ec_addresses a, ec_orders o + where c.creditcard_id = o.creditcard_id + and order_id = :order_id + and c.billing_address = a.address_id"] == 0 } { ad_returnredirect checkout-2 return } -# check done -# set the credit card variables +# Check done. Set the credit card variables - set ec_creditcard_widget [ec_creditcard_widget $creditcard_type] set ec_expires_widget "[ec_creditcard_expire_1_widget [string range $creditcard_expire 0 1]] [ec_creditcard_expire_2_widget [string range $creditcard_expire 3 4]]" +set formatted_address [ec_display_as_html [ec_pretty_mailing_address_from_args $line1 $line2 $city $usps_abbrev $zip_code $country_code $full_state_name $attn $phone $phone_time]] +set international_address [string equal $country_code 'US'] db_release_unused_handles -ec_return_template - - - - - Index: openacs-4/packages/ecommerce/www/credit-card-correction.xql =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/ecommerce/www/credit-card-correction.xql,v diff -u -r1.1 -r1.2 --- openacs-4/packages/ecommerce/www/credit-card-correction.xql 10 Jul 2001 20:42:02 -0000 1.1 +++ openacs-4/packages/ecommerce/www/credit-card-correction.xql 26 May 2002 04:36:50 -0000 1.2 @@ -1,35 +1,40 @@ + - - - 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_session_id=:user_session_id + and order_state='in_basket' + + - - - - select count(*) from ec_items where order_id=:order_id - - + + + select count(*) + from ec_items + where order_id=:order_id + + - - - - select user_id from ec_orders where order_id=:order_id - - + + + select user_id + from ec_orders + where order_id=:order_id + + - - - - select creditcard_type, creditcard_number, creditcard_expire, billing_zip_code from -ec_creditcards, ec_orders -where ec_creditcards.creditcard_id=ec_orders.creditcard_id -and order_id=:order_id - - + + + select c.creditcard_type, c.creditcard_number, c.creditcard_expire, a.* + from ec_creditcards c, ec_addresses a, ec_orders o + where c.creditcard_id = o.creditcard_id + and order_id = :order_id + and c.billing_address = a.address_id + + - Index: openacs-4/packages/ecommerce/www/finalize-order-oracle.xql =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/ecommerce/www/finalize-order-oracle.xql,v diff -u -r1.1 -r1.2 --- openacs-4/packages/ecommerce/www/finalize-order-oracle.xql 10 Jul 2001 20:42:02 -0000 1.1 +++ openacs-4/packages/ecommerce/www/finalize-order-oracle.xql 26 May 2002 04:36:50 -0000 1.2 @@ -1,13 +1,95 @@ - oracle8.1.6 + + oracle + 8.1.6 + - - - select ec_gift_certificate_balance(:user_id) from dual - - + + + 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 + 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 + 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 + + + Index: openacs-4/packages/ecommerce/www/finalize-order-postgresql.xql =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/ecommerce/www/finalize-order-postgresql.xql,v diff -u -r1.1 -r1.2 --- openacs-4/packages/ecommerce/www/finalize-order-postgresql.xql 10 Jul 2001 20:42:02 -0000 1.1 +++ openacs-4/packages/ecommerce/www/finalize-order-postgresql.xql 26 May 2002 04:36:50 -0000 1.2 @@ -1,13 +1,93 @@ - postgresql7.1 + + postgresql + 7.1 + - - - select ec_gift_certificate_balance(:user_id) - - + + + 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 + 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 + 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 + *op + + + + + 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 + + + Index: openacs-4/packages/ecommerce/www/finalize-order.tcl =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/ecommerce/www/finalize-order.tcl,v diff -u -r1.2 -r1.3 --- openacs-4/packages/ecommerce/www/finalize-order.tcl 21 Aug 2001 04:42:27 -0000 1.2 +++ openacs-4/packages/ecommerce/www/finalize-order.tcl 26 May 2002 04:36:50 -0000 1.3 @@ -1,31 +1,34 @@ -# www/ecommerce/finalize-order.tcl 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 + 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 - @cvs-id finalize-order.tcl,v 3.3.6.9 2000/09/22 01:37:30 kevin Exp @author ported by Jerry Asher (jerry@theashergroup.com) @author and Walter McGinnis (wtem@olywa.net) + @author revised by Bart Teeuwisse + @revision-date April 2002 + } { } # 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_cybercash_zombies, which will try to authorize -# any 'confirmed' orders over half an hour old. +# 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 @@ -56,22 +59,25 @@ 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 ""] +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 + + # Find their most recently confirmed order + set most_recently_confirmed_order [db_string get_mrc_order " - select order_id + 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 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 ""] + and o2.confirmed_date is not null)" -default ""] if { [empty_string_p $most_recently_confirmed_order] } { ad_returnredirect index @@ -81,115 +87,738 @@ template::adp_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. +# 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 } { +# 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 } { ad_returnredirect shopping-cart template::adp_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"] +# 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 } { ad_returnredirect checkout template::adp_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 +# 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 ""] +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] } { - ad_returnredirect checkout - template::adp_abort + + # 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] + return + } } -# 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 +# 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 ""] +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]] + # We only want price and shipping from this (to determine whether + # gift_certificate covers cost) - set gift_certificate_balance [db_string get_gc_balance "select ec_gift_certificate_balance(:user_id) from dual"] - + 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" - - ### gilbertw: removed the next three lines - ### the openacs 3.2.5 code does not have the next 2/3 lines - ### instead it uses ec_update_state_to_confirmed 20 lines later - ### which handles the gift certificate amounts - ### if ec_update_state_to_authorized is used, the gift certificate - ### amounts do not get subtracted - # ec_update_state_to_authorized $order_id "authorized_plus_avs" - #ad_returnredirect thank-you - #template::adp_abort } } -set shipping_method [db_string get_shipping_method "select shipping_method from ec_orders where order_id=:order_id" -default ""] - - +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")) } { ad_returnredirect checkout-2 template::adp_abort } +# Done with all the checks! -# done with all the checks! - # (1) put this order into the 'confirmed' state db_transaction { - -ec_update_state_to_confirmed $order_id - + ec_update_state_to_confirmed $order_id } -# (2) try to authorize the user's credit card info and either +# (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 cc_result [ec_creditcard_authorization $order_id] +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)"] -if { [string equal $cc_result "authorized_plus_avs"] || [string equal $cc_result "authorized_minus_avs"] } { - ec_email_new_order $order_id - ec_update_state_to_authorized $order_id [ec_decode $cc_result "authorized_plus_avs" "t" "f"] -} +# 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. -# wtem@olywa.net, 2001-03-21 -# replaced string1 == string2 with [string equal string1 string2] -if { [string equal $cc_result "authorized_plus_avs"] || [string equal $cc_result "authorized_minus_avs"] || [string equal $cc_result "no_recommendation"] } { - ad_returnredirect thank-you - template::adp_abort -} elseif { [string equal $cc_result "failed_authorization"] } { - # updates everything that needs to be updated if a confirmed offer fails - ec_update_state_to_in_basket $order_id +if {$hard_goods_cost > 0} { - ad_returnredirect credit-card-correction - template::adp_abort + # 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 thank-you + + } 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 thank-you + template::adp_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 + + ad_returnredirect credit-card-correction + template::adp_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" " +

    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 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 thank-you + + } 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 + + ad_returnredirect credit-card-correction + template::adp_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" " +

    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 thank-you + + } 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 + ad_returnredirect 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" " +

    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 + + ad_returnredirect credit-card-correction + template::adp_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" " +

    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 thank-you + + } 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 thank-you + template::adp_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 + + ad_returnredirect credit-card-correction + template::adp_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" " +

    Sorry

    +

    There has been an error in the processing of your credit card information. + Please contact [ec_system_owner] to report the error.

    " + } + } + } } else { - # Then cc_result is probably "invalid_input". - # This should never occur - ns_log Notice "Order $order_id received a cc_result of $cc_result" - ad_return_error "Sorry" " -

    Sorry

    -There has been an error in the processing of your credit card information. Please contact
    [ec_system_owner]
    to report the error. -[ad_footer] -" -} + + # 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 thank-you + + } 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_capture_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 thank-you + } + + 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 + + ad_returnredirect credit-card-correction + template::adp_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" " +

    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 thank-you + } +} Index: openacs-4/packages/ecommerce/www/finalize-order.xql =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/ecommerce/www/finalize-order.xql,v diff -u -r1.1 -r1.2 --- openacs-4/packages/ecommerce/www/finalize-order.xql 10 Jul 2001 20:42:02 -0000 1.1 +++ openacs-4/packages/ecommerce/www/finalize-order.xql 26 May 2002 04:36:50 -0000 1.2 @@ -1,64 +1,83 @@ + - - - 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_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 - ) - - - + 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 count(*) + from ec_items + where order_id=:order_id + + - - - - select user_id from ec_orders 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 shipping_address + from ec_orders + where order_id=:order_id + + - - - - select creditcard_id 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 - - + + + 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/ecommerce/www/gift-certificate-claim-2-oracle.xql =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/ecommerce/www/gift-certificate-claim-2-oracle.xql,v diff -u -r1.1 -r1.2 --- openacs-4/packages/ecommerce/www/gift-certificate-claim-2-oracle.xql 10 Jul 2001 20:42:02 -0000 1.1 +++ openacs-4/packages/ecommerce/www/gift-certificate-claim-2-oracle.xql 26 May 2002 04:36:50 -0000 1.2 @@ -1,35 +1,33 @@ - oracle8.1.6 + + oracle + 8.1.6 + - - + + insert into ec_problems_log - (problem_id, problem_date, problem_details) - values - (ec_problem_id_sequence.nextval, sysdate,:prob_details ) - - - + (problem_id, problem_date, problem_details) + values + (ec_problem_id_sequence.nextval, sysdate,:prob_details ) + + - - - + + update ec_gift_certificates set user_id=:user_id, claimed_date=sysdate 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, sysdate, :gift_certificate_id, :prob_details) - - - + (problem_id, problem_date, gift_certificate_id, problem_details) + values + (ec_problem_id_sequence.nextval, sysdate, :gift_certificate_id, :prob_details) + + - Index: openacs-4/packages/ecommerce/www/gift-certificate-claim-2-postgresql.xql =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/ecommerce/www/gift-certificate-claim-2-postgresql.xql,v diff -u -r1.1 -r1.2 --- openacs-4/packages/ecommerce/www/gift-certificate-claim-2-postgresql.xql 10 Jul 2001 20:42:02 -0000 1.1 +++ openacs-4/packages/ecommerce/www/gift-certificate-claim-2-postgresql.xql 26 May 2002 04:36:50 -0000 1.2 @@ -1,35 +1,33 @@ - postgresql7.1 + + postgresql + 7.1 + - - + + insert into ec_problems_log - (problem_id, problem_date, problem_details) - values - (ec_problem_id_sequence.nextval, current_timestamp,:prob_details ) - - - + (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) - - - + (problem_id, problem_date, gift_certificate_id, problem_details) + values + (ec_problem_id_sequence.nextval, current_timestamp, :gift_certificate_id, :prob_details) + + - Index: openacs-4/packages/ecommerce/www/gift-certificate-claim-2.tcl =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/ecommerce/www/gift-certificate-claim-2.tcl,v diff -u -r1.1 -r1.2 --- openacs-4/packages/ecommerce/www/gift-certificate-claim-2.tcl 20 Apr 2001 20:51:13 -0000 1.1 +++ openacs-4/packages/ecommerce/www/gift-certificate-claim-2.tcl 26 May 2002 04:36:50 -0000 1.2 @@ -1,115 +1,120 @@ -# www/ecommerce/gift-certificate-claim-2.tcl ad_page_contract { @param claim_check the string used to claim the certificate @author @creation-date - @cvs-id gift-certificate-claim-2.tcl,v 3.2.6.9 2000/09/22 01:37:31 kevin Exp @author ported by Jerry Asher (jerry@theashergroup.com) + @author revised by Bart Teeuwisse + @revision-date April 2002 + } { claim_check:notnull + address_id:notnull } - - # 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]?[export_entire_form_as_url_vars]" - ad_returnredirect "/register?[export_url_vars return_url]" return } -# make sure they have an in_basket order and a user_session_id; -# this will make it more annoying for someone who just wants to -# come to this page and try random number after random number +# Make sure they have an in_basket order and a user_session_id; this +# will make it more annoying for someone who just wants to come to +# this page and try random number after random number set user_session_id [ec_get_user_session_id] - if { $user_session_id == 0 } { ad_returnredirect "index" return } - - -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 ""] +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] } { ad_returnredirect "index" return } -# see if there's a gift certificate with that claim check +# See if there's a gift certificate with that 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 ""] - +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_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 )" return } -# there is a gift certificate with that claim check; +# 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" +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" - - doc_return 200 text/html "[ad_header "Gift Certificate Claimed"] - [ec_header_image]
    -
    - [ec_pretty_price $amount] has been added to your gift certificate account! -

    - Continue with your order -

    - [ec_footer] - " - return + # 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" + doc_return 200 text/html " + [ad_header "Gift Certificate Claimed"] + [ec_header_image]
    +
    +

    [ec_pretty_price $amount] has been added to your gift certificate account!

    +

    Continue with your order

    +
    + [ec_footer]" + } else { - # it's already been claimed - - set page_html "[ad_header "Gift Certificate Already Claimed"] - [ec_header_image]
    -
    - Your gift certificate has already been claimed. Either you hit submit twice on the form, or it - was claimed previously. Once you claim it, it goes into your gift - certificate balance and you don't have to claim it again. -

    - Continue with your order -

    - [ec_footer] - " - # see if it was claimed by a different user and, if so, record the problem + # 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." + 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) - " + 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)" } + db_release_unused_handles - doc_return 200 text/html $page_html + doc_return 200 text/html " + [ad_header "Gift Certificate Already Claimed"] + [ec_header_image]
    +
    +

    Your gift certificate has already been claimed. Either you hit submit twice on the form, or it + was claimed previously. Once you claim it, it goes into your gift certificate balance and you don't have to claim it again.

    +

    Continue with your order

    +
    + [ec_footer]" - } - Index: openacs-4/packages/ecommerce/www/gift-certificate-claim-2.xql =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/ecommerce/www/gift-certificate-claim-2.xql,v diff -u -r1.1 -r1.2 --- openacs-4/packages/ecommerce/www/gift-certificate-claim-2.xql 10 Jul 2001 20:42:02 -0000 1.1 +++ openacs-4/packages/ecommerce/www/gift-certificate-claim-2.xql 26 May 2002 04:36:50 -0000 1.2 @@ -1,25 +1,30 @@ + - - - 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_session_id=:user_session_id + and order_state='in_basket' + + - - - - select gift_certificate_id from ec_gift_certificates where claim_check=:claim_check - - + + + 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 as gift_certificate_user_id, amount + from ec_gift_certificates + where gift_certificate_id=:gift_certificate_id + + - Index: openacs-4/packages/ecommerce/www/gift-certificate-claim.tcl =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/ecommerce/www/gift-certificate-claim.tcl,v diff -u -r1.1 -r1.2 --- openacs-4/packages/ecommerce/www/gift-certificate-claim.tcl 20 Apr 2001 20:51:13 -0000 1.1 +++ openacs-4/packages/ecommerce/www/gift-certificate-claim.tcl 26 May 2002 04:36:50 -0000 1.2 @@ -1,41 +1,39 @@ -# www/ecommerce/gift-certificate-claim.tcl ad_page_contract { - @author - @creation-date - @cvs-id gift-certificate-claim.tcl,v 3.1.6.6 2000/08/18 21:46:33 stevenp Exp - @author ported by Jerry Asher (jerry@theashergroup.com) + @author + @creation-date + @author ported by Jerry Asher (jerry@theashergroup.com) + @author revised by Bart Teeuwisse + @revision-date April 2002 + } { + address_id:notnull } - -# we need them to be logged in +# 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]" return } +# Make sure they have an in_basket order and a user_session_id; this +# will make it more annoying for someone who just wants to come to +# this page and try random number after random number - -# make sure they have an in_basket order and a user_session_id; -# this will make it more annoying for someone who just wants to -# come to this page and try random number after random number - set user_session_id [ec_get_user_session_id] - if { $user_session_id == 0 } { ad_returnredirect "index" return } -set order_id [db_string get_order_id_for_claim "select order_id from ec_orders where user_session_id=:user_session_id and order_state='in_basket'" -default ""] +set order_id [db_string get_order_id_for_claim " + 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] } { ad_returnredirect "index" return } - -ec_return_template Index: openacs-4/packages/ecommerce/www/gift-certificate-claim.xql =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/ecommerce/www/gift-certificate-claim.xql,v diff -u -r1.1 -r1.2 --- openacs-4/packages/ecommerce/www/gift-certificate-claim.xql 10 Jul 2001 20:42:02 -0000 1.1 +++ openacs-4/packages/ecommerce/www/gift-certificate-claim.xql 26 May 2002 04:36:50 -0000 1.2 @@ -1,11 +1,14 @@ + - - - 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_session_id=:user_session_id + and order_state='in_basket' + + - Index: openacs-4/packages/ecommerce/www/gift-certificate-finalize-order-oracle.xql =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/ecommerce/www/gift-certificate-finalize-order-oracle.xql,v diff -u -r1.2 -r1.3 --- openacs-4/packages/ecommerce/www/gift-certificate-finalize-order-oracle.xql 29 Jan 2002 00:11:46 -0000 1.2 +++ openacs-4/packages/ecommerce/www/gift-certificate-finalize-order-oracle.xql 26 May 2002 04:36:50 -0000 1.3 @@ -1,60 +1,63 @@ - oracle8.1.6 + + oracle + 8.1.6 + - - + + insert into ec_problems_log - (problem_id, problem_date, problem_details, gift_certificate_id) - values - (ec_problem_id_sequence.nextval, sysdate, 'Customer pushed reload on gift-certificate-finalize-order.tcl but gift_certificate_state wasn't authorized_plus_avs, authorized_minus_avs, failed_authorization, or confirmed',:gift_certificate_id) - - - + (problem_id, problem_date, problem_details, gift_certificate_id) + values + (ec_problem_id_sequence.nextval, sysdate, + 'Customer pushed reload on gift-certificate-finalize-order.tcl but gift_certificate_state wasn't authorized or failed',:gift_certificate_id) + + - - - + + insert into ec_gift_certificates - (gift_certificate_id, gift_certificate_state, amount, issue_date, purchased_by, expires, claim_check, certificate_message, certificate_to, certificate_from, recipient_email, last_modified, last_modifying_user, modified_ip_address) - values - (:gift_certificate_id, 'confirmed', :amount, sysdate, :user_id, add_months(sysdate,:gc_months),:claim_check, :certificate_message, :certificate_to, :certificate_from, :recipient_email, sysdate, :user_id, :peeraddr) - - - + (gift_certificate_id, gift_certificate_state, amount, issue_date, purchased_by, expires, claim_check, certificate_message, + certificate_to, certificate_from, recipient_email, last_modified, last_modifying_user, modified_ip_address) + values + (:gift_certificate_id, 'confirmed', :amount, sysdate, :user_id, add_months(sysdate,:gc_months),:claim_check, :certificate_message, + :certificate_to, :certificate_from, :recipient_email, sysdate, :user_id, :peeraddr) + + - - - + + insert into ec_financial_transactions - (transaction_id, gift_certificate_id, creditcard_id, transaction_amount, transaction_type, inserted_date) - values - (:transaction_id, :gift_certificate_id, :creditcard_id, :amount, 'charge', sysdate) - - - + (transaction_id, gift_certificate_id, creditcard_id, transaction_amount, transaction_type, inserted_date) + values + (:transaction_id, :gift_certificate_id, :creditcard_id, :amount, 'charge', sysdate) + + - - - - update ec_financial_transactions set authorized_date=sysdate, to_be_captured_p='t' where transaction_id=:transaction_id - - + + + update ec_financial_transactions + set authorized_date=sysdate, to_be_captured_p='t', transaction_id = :pgw_transaction_id + where transaction_id=:transaction_id + + - - - - update ec_gift_certificates set authorized_date=sysdate, gift_certificate_state=:cc_result where gift_certificate_id=:gift_certificate_id - - + + + update ec_gift_certificates + set authorized_date=sysdate, gift_certificate_state='authorized' + where gift_certificate_id=:gift_certificate_id + + - - - - select round((sysdate-issue_date)*86400) as n_seconds from ec_gift_certificates where gift_certificate_id = :gift_certificate_id - - + + + select round((sysdate-issue_date)*86400) as n_seconds + from ec_gift_certificates + where gift_certificate_id = :gift_certificate_id + + - Index: openacs-4/packages/ecommerce/www/gift-certificate-finalize-order-postgresql.xql =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/ecommerce/www/gift-certificate-finalize-order-postgresql.xql,v diff -u -r1.3 -r1.4 --- openacs-4/packages/ecommerce/www/gift-certificate-finalize-order-postgresql.xql 29 Jan 2002 00:11:46 -0000 1.3 +++ openacs-4/packages/ecommerce/www/gift-certificate-finalize-order-postgresql.xql 26 May 2002 04:36:50 -0000 1.4 @@ -1,75 +1,93 @@ - postgresql7.1 + + postgresql + 7.1 + - - + + insert into ec_problems_log - (problem_id, problem_date, problem_details, gift_certificate_id) - values - (ec_problem_id_sequence.nextval, current_timestamp, 'Customer pushed reload on gift-certificate-finalize-order.tcl but gift_certificate_state wasn't authorized_plus_avs, authorized_minus_avs, failed_authorization, or confirmed',:gift_certificate_id) - - - + (problem_id, problem_date, problem_details, gift_certificate_id) + values + (ec_problem_id_sequence.nextval, current_timestamp, 'Customer pushed reload on gift-certificate-finalize-order.tcl but gift_certificate_state wasn't authorized or failed',:gift_certificate_id) + + + + + insert into ec_problems_log + (problem_id, problem_date, problem_details, gift_certificate_id) + values + (ec_problem_id_sequence.nextval, current_timestamp, 'gift-certificate-finalize-order.tcl could not authorize a gift certificate as no payment gateway was selected.' ,:gift_certificate_id) + + - - + + + insert into ec_problems_log + (problem_id, problem_date, problem_details, gift_certificate_id) + values + (ec_problem_id_sequence.nextval, current_timestamp, 'gift-certificate-finalize-order.tcl could not authorize a gift certificate as payment gateway $payment_gateway is unbound.',:gift_certificate_id) + + + + insert into ec_gift_certificates - (gift_certificate_id, gift_certificate_state, amount, issue_date, purchased_by, expires, claim_check, certificate_message, certificate_to, certificate_from, recipient_email, last_modified, last_modifying_user, modified_ip_address) - values - (:gift_certificate_id, 'confirmed', :amount, current_timestamp, :user_id, current_timestamp + ':gc_months months'::interval,:claim_check, :certificate_message, :certificate_to, :certificate_from, :recipient_email, current_timestamp, :user_id, :peeraddr) - - - - - - - - insert into ec_gift_certificates - (gift_certificate_id, gift_certificate_state, amount, issue_date, purchased_by, expires, claim_check, certificate_message, certificate_to, certificate_from, recipient_email, last_modified, last_modifying_user, modified_ip_address) + (gift_certificate_id, gift_certificate_state, amount, issue_date, purchased_by, expires, claim_check, + certificate_message, certificate_to, certificate_from, recipient_email, last_modified, last_modifying_user, modified_ip_address) values - (:gift_certificate_id, 'confirmed', :amount, current_timestamp, :user_id, current_timestamp + '$gc_months months'::interval,:claim_check, :certificate_message, :certificate_to, :certificate_from, :recipient_email, current_timestamp, :user_id, :peeraddr) - - - + (:gift_certificate_id, 'confirmed', :amount, current_timestamp, :user_id, current_timestamp + '$gc_months months'::interval,:claim_check, + :certificate_message, :certificate_to, :certificate_from, :recipient_email, current_timestamp, :user_id, :peeraddr) + + - - - + + insert into ec_financial_transactions - (transaction_id, gift_certificate_id, creditcard_id, transaction_amount, transaction_type, inserted_date) - values - (:transaction_id, :gift_certificate_id, :creditcard_id, :amount, 'charge', current_timestamp) - - - + (transaction_id, gift_certificate_id, creditcard_id, transaction_amount, transaction_type, inserted_date) + values + (:transaction_id, :gift_certificate_id, :creditcard_id, :amount, 'charge', current_timestamp) + + - - - - update ec_financial_transactions set authorized_date=current_timestamp, to_be_captured_p='t' where transaction_id=:transaction_id - - + + + update ec_financial_transactions + set authorized_date=current_timestamp, to_be_captured_p='t', transaction_id = :pgw_transaction_id + where transaction_id=:transaction_id + + - - - - update ec_gift_certificates set authorized_date=current_timestamp, gift_certificate_state=:cc_result where gift_certificate_id=:gift_certificate_id - - + + + update ec_gift_certificates + set authorized_date=current_timestamp, gift_certificate_state='authorized' + where gift_certificate_id=:gift_certificate_id + + - - - + + + insert into ec_problems_log + (problem_id, problem_date, problem_details, gift_certificate_id) + values + (ec_problem_id_sequence.nextval, sysdate, + 'Gift-certificate-finalize-order.tcl called payment gateway :payment_gateway for authorizion, which returned: :response_code.', :gift_certificate_id) + + + + + select extract(day from (current_timestamp-issue_date))*86400 + extract(hour from (current_timestamp-issue_date))*3600 + extract(min from (current_timestamp-issue_date))*60 + - extract(sec from (current_timestamp-issue_date)) as n_seconds from ec_gift_certificates where gift_certificate_id = :gift_certificate_id - - + extract(sec from (current_timestamp-issue_date)) as n_seconds + from ec_gift_certificates + where gift_certificate_id = :gift_certificate_id + + - Index: openacs-4/packages/ecommerce/www/gift-certificate-finalize-order.tcl =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/ecommerce/www/gift-certificate-finalize-order.tcl,v diff -u -r1.3 -r1.4 --- openacs-4/packages/ecommerce/www/gift-certificate-finalize-order.tcl 31 Jan 2002 22:43:54 -0000 1.3 +++ openacs-4/packages/ecommerce/www/gift-certificate-finalize-order.tcl 26 May 2002 04:36:50 -0000 1.4 @@ -1,4 +1,3 @@ -# www/ecommerce/gift-certificate-finalize-order.tcl ad_page_contract { this script will: @@ -16,9 +15,10 @@ 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_cybercash_zombies, which will try to authorize + ec_query_for_payment_zombies, which will try to authorize any 'confirmed' orders over half an hour old. + @param address_id @param gift_certificate_id @param certificate_to @param certificate_from @@ -31,13 +31,15 @@ @param creditcard_expire_1 @param creditcard_expire_2 - @param billing_zip_code @author @creation-date - @cvs-id gift-certificate-finalize-order.tcl,v 3.4.6.7 2000/09/22 01:37:31 kevin Exp @author ported by Jerry Asher (jerry@theashergroup.com) + @author revised by Bart Teeuwisse + @revision-date March 2002 + } { + address_id gift_certificate_id certificate_to certificate_from @@ -50,18 +52,15 @@ creditcard_expire_1:notnull creditcard_expire_2:notnull - billing_zip_code:notnull } ec_redirect_to_https_if_possible_and_necessary -# user must be logged in -set user_id [ad_verify_and_get_user_id] +# User must be logged in +set user_id [ad_verify_and_get_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]" return } @@ -71,54 +70,65 @@ set exception_count 0 set exception_text "" - if { [string length $certificate_message] > 200 } { incr exception_count - append exception_text "
  • The message you entered was too long. It needs to contain fewer than 200 characters (the current length is [string length $certificate_message] characters)." + append exception_text " +
  • + The message you entered was too long. + It needs to contain fewer than 200 characters (the current length is [string length $certificate_message] characters). +
  • " } elseif { [string length $certificate_to] > 100 } { incr exception_count - append exception_text "
  • What you entered in the \"To\" field, $certificate_to is too long. It needs to contain fewer than 100 characters (the current length is [string length $certificate_to] characters)." + append exception_text " +
  • + What you entered in the \"To\" field, $certificate_to is too long. + It needs to contain fewer than 100 characters (the current length is [string length $certificate_to] characters). +
  • " } elseif { [string length $certificate_from] > 100 } { incr exception_count - append exception_text "
  • What you entered in the \"From\" field, $certificate_from is too long. It needs to contain fewer than 100 characters (the current length is [string length $certificate_from] characters)." + append exception_text " +
  • + What you entered in the \"From\" field, $certificate_from is too long. + It needs to contain fewer than 100 characters (the current length is [string length $certificate_from] characters). +
  • " } elseif { [string length $recipient_email] > 100 } { incr exception_count - append exception_text "
  • The recipient email address, $recipient_email you entered is too long. It needs to contain fewer than 100 characters (the current length is [string length $recipient_email] characters)." + append exception_text " +
  • + The recipient email address, $recipient_email you entered is too long. + It needs to contain fewer than 100 characters (the current length is [string length $recipient_email] characters). +
  • " } -# if { [regexp {[^0-9]} $amount] } { -# incr exception_count -# append exception_text "
  • The amount, $amount needs to be a number with no special characters." -# } elseif if { $amount < [ad_parameter -package_id [ec_id] MinGiftCertificateAmount ecommerce] } { incr exception_count - append exception_text "
  • The amount, $amount needs to be at least [ec_pretty_price [ad_parameter -package_id [ec_id] MinGiftCertificateAmount ecommerce]]" + append exception_text " +
  • + The amount, $amount needs to be at least [ec_pretty_price [ad_parameter -package_id [ec_id] MinGiftCertificateAmount ecommerce]] +
  • " } elseif { $amount > [ad_parameter -package_id [ec_id] MaxGiftCertificateAmount ecommerce] } { incr exception_count - append exception_text "
  • The amount, $amount cannot be higher than [ec_pretty_price [ad_parameter -package_id [ec_id] MaxGiftCertificateAmount ecommerce]]" + append exception_text " +
  • + The amount, $amount cannot be higher than [ec_pretty_price [ad_parameter -package_id [ec_id] MaxGiftCertificateAmount ecommerce]] +
  • " } -# if {![philg_email_valid_p $recipient_email]} { -# incr exception_count -# append exception_text "
  • The recipient's email address that you typed doesn't look right to us. Examples of valid email addresses are -#
      -#
    • Alice1234@aol.com -#
    • joe_smith@hp.com -#
    • pierre@inria.fr -#
    -# " -# } - if { [regexp {[^0-9]} $creditcard_number] } { + # I've already removed spaces and dashes, so only numbers should remain + incr exception_count - append exception_text "
  • Your credit card number contains invalid characters." + append exception_text " +
  • + Your credit card number contains invalid characters. +
  • " } -# make sure the credit card type is right & that it has the right number +# 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 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] @@ -132,248 +142,382 @@ return } -# user session tracking -set user_session_id [ec_get_user_session_id] +# User session tracking +set user_session_id [ec_get_user_session_id] ec_log_user_as_user_id_for_this_session -# doubleclick protection -if { [db_string get_gift_c_id "select count(*) from ec_gift_certificates where gift_certificate_id=:gift_certificate_id"] > 0 } { +# Doubleclick protection - # query the status of the gift certificate in the database - set gift_certificate_state [db_string get_gift_c_status "select gift_certificate_state from ec_gift_certificates where gift_certificate_id=:gift_certificate_id"] +if { [db_string get_gift_c_id " + select count(*) + from ec_gift_certificates + where gift_certificate_id=:gift_certificate_id"] > 0 } { - if { $gift_certificate_state == "authorized_plus_avs" || $gift_certificate_state == "authorized_minus_avs" } { - set cybercash_status "success-reload" - } elseif { $gift_certificate_state == "failed_authorization" } { - set cybercash_status "failure-reload" - } elseif { $gift_certificate_state == "confirmed" } { - set cybercash_status "unknown-reload" - } else { - db_dml report_gc_error_into_log "insert into ec_problems_log - (problem_id, problem_date, problem_details, gift_certificate_id) - values - (ec_problem_id_sequence.nextval, sysdate, 'Customer pushed reload on gift-certificate-finalize-order.tcl but gift_certificate_state wasn't authorized_plus_avs, authorized_minus_avs, failed_authorization, or confirmed',:gift_certificate_id) - " + # Query the status of the gift certificate in the database - ad_return_error "Unexpected Result" "We received an unexpected result when querying for the status of your gift certificate. This problem has been logged. However, it would be helpful if you could email [ad_system_owner] with the events that led up to this occurrence. We apologize for this problem and we will correct it as soon as we can." - return + set gift_certificate_state [db_string get_gift_c_status " + select gift_certificate_state + from ec_gift_certificates + where gift_certificate_id=:gift_certificate_id"] + + switch -exact $gift_certificate_state { + + "authorized" { + + # Present a thank you page + + ad_returnredirect "gift-certificate-thank-you" + return + } + + "failed_authorization" { + + # Present a new gift_certificate_id and a new form + + set gift_certificate_id [db_nextval ec_gift_cert_id_sequence] + + set title "Credit Card Correction Needed" + set page " +
    +

    At this time we are unable to receive authorization to charge your + credit card. Please check the number and the expiration date and + try again or use a different credit card.

    +
    + [export_form_vars gift_certificate_id certificate_to certificate_from certificate_message amount recipient_email] + + + + + + + + + + + + +
    Credit card number:
    Type:[ec_creditcard_widget $creditcard_type]
    Expires:[ec_creditcard_expire_1_widget $creditcard_expire_1] [ec_creditcard_expire_2_widget $creditcard_expire_2]
    +
    + +
    +
    +
    " + } + + "confirmed" { + set n_seconds [db_string get_n_seconds " + select round((sysdate-issue_date)*86400) as n_seconds + from ec_gift_certificates + where gift_certificate_id = :gift_certificate_id"] + set title "Gift Certificate Order Already Processed" + set page " +

    You've probably hit submit twice from the same form. We are already + in possession of a gift certificate order with id # $gift_certificate_id (placed $n_seconds + seconds ago) and it is being processed. You can + check on the status of this gift certificate order if you like.

    " + } + + default { + db_dml report_gc_error_into_log " + insert into ec_problems_log + (problem_id, problem_date, problem_details, gift_certificate_id) + values + (ec_problem_id_sequence.nextval, sysdate, + 'Customer pushed reload on gift-certificate-finalize-order.tcl but gift_certificate_state wasn't authorized or failed.',:gift_certificate_id)" + set title "Unexpected Result" + set page " +

    We received an unexpected result when querying for the status of your gift certificate. + This problem has been logged. However, it would be helpful if you could email + [ad_system_owner] with the events that led up to this occurrence. + We apologize for this problem and we will correct it as soon as we can.

    " + } } } else { - # put in the credit card - # put in the gift certificate - # put in the transaction - # try to auth transaction + # Put in the credit card + # Put in the gift certificate + # Put in the transaction + # Try to auth transaction db_transaction { set creditcard_id [db_nextval ec_creditcard_id_sequence] - set ccstuff_1 "[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 get_ec_credit_card "insert into ec_creditcards - (creditcard_id, user_id, creditcard_number, creditcard_last_four, creditcard_type, creditcard_expire, billing_zip_code) - values - (:creditcard_id, :user_id, :creditcard_number, :ccstuff_1, :creditcard_type,:expiry,:billing_zip_code) - " + db_dml get_ec_credit_card " + 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, :ccstuff_1, :creditcard_type, :expiry, :address_id)" # claim check is generated as follows: - # 1. username of recipient (part of email address up to the @ symbol) up to 10 characters + # 1. username of recipient (part of email address up to the @ + # symbol) up to 10 characters # 2. 10 character random string # 3. gift_certificate_id # all separated by dashes - # The username is added as protection in case someone cracks the random number algorithm. - # The gift_certificate_id is added as a guarantee of uniqueness. + # The username is added as protection in case someone cracks + # the random number algorithm. The gift_certificate_id is + # added as a guarantee of uniqueness. - # philg_email_valid_p ensures that there will be an @ sign, thus a username will be set - regexp {(.+)@} $recipient_email match username + # philg_email_valid_p ensures that there will be an @ sign, + # thus a username will be set + regexp {(.+)@} $recipient_email match username if { [string length $username] > 10 } { set username [string range $username 0 9] } set random_string [ec_generate_random_string 10] - set claim_check "$username-$random_string-$gift_certificate_id" - - set peeraddr [ns_conn peeraddr] set gc_months [ad_parameter -package_id [ec_id] GiftCertificateMonths ecommerce] - db_dml insert_new_gc_into_db "insert into ec_gift_certificates - (gift_certificate_id, gift_certificate_state, amount, issue_date, purchased_by, expires, claim_check, certificate_message, certificate_to, certificate_from, recipient_email, last_modified, last_modifying_user, modified_ip_address) - values - (:gift_certificate_id, 'confirmed', :amount, sysdate, :user_id, add_months(sysdate,:gc_months),:claim_check, :certificate_message, :certificate_to, :certificate_from, :recipient_email, sysdate, :user_id, :peeraddr) - " + db_dml insert_new_gc_into_db " + insert into ec_gift_certificates + (gift_certificate_id, gift_certificate_state, amount, issue_date, purchased_by, expires, claim_check, + certificate_message, certificate_to, certificate_from, recipient_email, last_modified, last_modifying_user, modified_ip_address) + values + (:gift_certificate_id, 'confirmed', :amount, sysdate, :user_id, add_months(sysdate,:gc_months),:claim_check, + :certificate_message, :certificate_to, :certificate_from, :recipient_email, sysdate, :user_id, :peeraddr)" set transaction_id [db_nextval ec_transaction_id_sequence] - - db_dml insert_ec_financial_trans "insert into ec_financial_transactions - (transaction_id, gift_certificate_id, creditcard_id, transaction_amount, transaction_type, inserted_date) - values - (:transaction_id, :gift_certificate_id, :creditcard_id, :amount, 'charge', sysdate) - " - + db_dml insert_ec_financial_trans " + insert into ec_financial_transactions + (transaction_id, gift_certificate_id, creditcard_id, transaction_amount, transaction_type, inserted_date) + values + (:transaction_id, :gift_certificate_id, :creditcard_id, :amount, 'charge', sysdate)" } # try to authorize the transaction - set cc_args [ns_set new] - - ns_set put $cc_args "amount" "[ad_parameter -package_id [ec_id] Currency ecommerce] $amount" - ns_set put $cc_args "card-number" "$creditcard_number" - ns_set put $cc_args "card-exp" "$creditcard_expire_1/$creditcard_expire_2" - ns_set put $cc_args "card-zip" "$billing_zip_code" - ns_set put $cc_args "order-id" "$transaction_id" - - set ttcc_output [ec_talk_to_cybercash "mauthonly" $cc_args] - - # We're interested in the txn_status, errmsg (if any) and avs_code - set txn_status [ns_set get $ttcc_output "txn_status"] - set errmsg [ns_set get $ttcc_output "errmsg"] - set avs_code [ns_set get $ttcc_output "avs_code"] - - # If we get a txn_status of failure-q-or-cancel, it means there was a communications - # failure and we can retry it (right away). - - if { [empty_string_p $txn_status] } { - # that means we didn't hear back from CyberCash - set cybercash_status "unknown-no-response" - } elseif { $txn_status == "success" || $txn_status == "success-duplicate" } { - set cybercash_status "success" - } elseif { $txn_status == "failure-q-or-cancel" || $txn_status == "pending" } { - # we'll retry once - ns_log Notice "Retrying failure-q-or-cancel gift certificate # $gift_certificate_id (transaction # $transaction_id)" - - set cc_args [ns_set new] - - ns_set put $cc_args "txn-type" "auth" - ns_set put $cc_args "order-id" "$transaction_id" - - set ttcc_output [ec_talk_to_cybercash "retry" $cc_args] - set txn_status [ns_set get $ttcc_output "txn_status"] - set errmsg [ns_set get $ttcc_output "errmsg"] - set avs_code [ns_set get $ttcc_output "avs_code"] - - if {[regexp {success} $txn_status]} { - set cybercash_status "success" - } else { - set cybercash_status "failure" - } - } else { - set cybercash_status "failure" - } -} -# Now deal with the cybercash_status: -# 1. If success, update transaction and gift certificate to authorized, -# send gift certificate order email, and give them a thank you page. -# 2. If failure, update gift certificate and transaction to failed, -# create a new gift certificate_id and give them a new credit card form. -# 3. If unknown-no-response, give message saying that we didn't hear back -# from CyberCash and that a cron job will check. -# 4. If unknown-reload, give message saying they're getting this message -# because they pushed reload and that a cron job will check. + # Lookup the selected currency. -if { $cybercash_status == "success" || $cybercash_status == "success-reload" } { - # we only want to make database updates and send email if the user didn't push reload - if { $cybercash_status == "success" } { - if { [ ec_avs_acceptable_p $avs_code ] == 1 } { - set cc_result "authorized_plus_avs" + set currency [ad_parameter Currency ecommerce] + + # Lookup the selected payment gateway + + set payment_gateway [ad_parameter PaymentGateway -default [ad_parameter -package_id [ec_id] PaymentGateway]] + + # Flag an error when no payment gateway has been selected or if + # there is no binding between the selected gateway and the + # PaymentGateway. + + if {[empty_string_p $payment_gateway] } { + db_dml log_empty_gateway_error " + insert into ec_problems_log + (problem_id, problem_date, problem_details, gift_certificate_id) + values + (ec_problem_id_sequence.nextval, sysdate, + 'gift-certificate-finalize-order.tcl could not authorize a gift certificate as no payment gateway was selected.',:gift_certificate_id)" + set title "Unexpected Result" + set page " +

    We received an unexpected result when contacting the payment gateway for credit card authorization. + This problem has been logged. However, it would be helpful if you could email + [ad_system_owner] with the events that led up to this occurrence. + We apologize for this problem and we will correct it as soon as we can.

    " + } else { + if {![acs_sc_binding_exists_p "PaymentGateway" $payment_gateway]} { + db_dml log_unbound_gateway_error " + insert into ec_problems_log + (problem_id, problem_date, problem_details, gift_certificate_id) + values + (ec_problem_id_sequence.nextval, sysdate, + 'gift-certificate-finalize-order.tcl could not authorize a gift certificate as payment gateway $payment_gateway is not bound to the Payment Service Contract.',:gift_certificate_id)" + set title "Unexpected Result" + set page " +

    We received an unexpected result when contacting the payment gateway for credit card authorization. + This problem has been logged. However, it would be helpful if you could email + [ad_system_owner] with the events that led up to this occurrence. + We apologize for this problem and we will correct it as soon as we can.

    " } else { - set cc_result "authorized_minus_avs" - } - - # update transaction and gift certificate to authorized - # setting to_be_captured_p to 't' will cause ec_unmarked_transactions to come along and mark it for capture - db_dml update_ft_set_status "update ec_financial_transactions set authorized_date=sysdate, to_be_captured_p='t' where transaction_id=:transaction_id" - db_dml upate_ec_gc_status "update ec_gift_certificates set authorized_date=sysdate, gift_certificate_state=:cc_result where gift_certificate_id=:gift_certificate_id" - - # send gift certificate order email - ec_email_new_gift_certificate_order $gift_certificate_id - } - # give them a thank you page - ad_returnredirect "gift-certificate-thank-you" - return - -} elseif { $cybercash_status == "failure" || $cybercash_status == "failure-reload" } { - # we only want to make database updates if the user didn't push reload - if { $cybercash_status == "failure" } { - # we probably don't need to do this update of to_be_captured_p because no cron jobs - # distinguish between null and 'f' right now, but it doesn't hurt and it might alleviate - # someone's concern when they're looking at ec_financial_transactions and wondering - # whether they should be concerned that failed_p is 't' - db_dml set_ft_failure "update ec_financial_transactions set failed_p='t', to_be_captured_p='f' where transaction_id=:transaction_id" - db_dml set_gc_failure "update ec_gift_certificates set gift_certificate_state='failed_authorization' where gift_certificate_id=:gift_certificate_id" - } + # Lookup the credit card information for the + # transaction. There will be one since the card has just + # been inserted. - # give them a gift_certificate_id and a new form - set gift_certificate_id [db_nextval ec_gift_cert_id_sequence] - - set page_html "[ad_header "Credit Card Correction Needed"] - [ec_header_image]
    -
    - At this time we are unable to receive authorization to charge your - credit card. Please check the number and the expiration date and - try again or use a different credit card. -

    -

    - [export_form_vars gift_certificate_id certificate_to certificate_from certificate_message amount recipient_email] - - - - - - - - - - - - - - - - -
    Credit card number:
    Type:[ec_creditcard_widget $creditcard_type]
    Expires:[ec_creditcard_expire_1_widget $creditcard_expire_1] [ec_creditcard_expire_2_widget $creditcard_expire_2]
    Billing zip code:
    -
    - -
    -
    -
    - [ec_footer] - " -} elseif { $cybercash_status == "unknown-no-response" } { - - set page_html "[ad_header "No Response from CyberCash"] - [ec_header_image]
    -
    - We didn't receive confirmation from CyberCash about whether they were able to authorize the - payment for your gift certificate order. -

    - We will query CyberCash within the next hour to see if they processed your transaction, and - we'll let you know by email. We apologize for the inconvenience. -

    - You can also check on the status of - this gift certificate order. -

    - [ec_footer] - " -} elseif { $cybercash_status == "unknown-reload" } { - set n_seconds [db_string get_n_seconds "select round((sysdate-issue_date)*86400) as n_seconds from ec_gift_certificates where gift_certificate_id = :gift_certificate_id"] - - set page_html "[ad_header "Gift Certificate Order Already Processed"] - You've probably hit submit twice from the same form. We are already -in possession of a gift certificate order with id # $gift_certificate_id (placed $n_seconds -seconds ago) and it is being processed. You can check on the status of -this gift certificate order if you like. + db_1row creditcard_data_select " + select c.creditcard_number as card_number, substring(creditcard_expire for 2) as card_exp_month, substring(creditcard_expire from 4 for 2) as card_exp_year, c.creditcard_type, + p.first_names || ' ' || p.last_name as card_name, + a.zip_code as billing_zip, + a.line1 as billing_address, + a.city as billing_city, + coalesce(a.usps_abbrev, a.full_state_name) as billing_state, + a.country_code as billing_country + from ec_creditcards c, persons p, ec_addresses a + where c.user_id=p.person_id + and c.creditcard_id = :creditcard_id + and c.billing_address = a.address_id" -[ec_footer] -" -} + # Convert the one digit creditcard abbreviation to the + # standardized name of the card. + set card_type [ec_pretty_creditcard_type $creditcard_type] -doc_return 200 text/html $page_html + # Connect to the payment gateway to authorize the transaction. + + array set response [acs_sc_call "PaymentGateway" "Authorize" \ + [list $transaction_id \ + $amount \ + $card_type \ + $card_number \ + $card_exp_month \ + $card_exp_year \ + $card_name \ + $billing_address \ + $billing_city \ + $billing_state \ + $billing_zip \ + $billing_country] \ + $payment_gateway] + + # Extract response_code, reason and the gateway transaction id + # from the response. The response_code values are defined in + # payment-gateway/tcl/payment-gateway-init.tcl. The reason is a + # human readable description of the response and the + # transaction id is the ID as returned by the payment gateway. + + set response_code $response(response_code) + set reason $response(reason) + set pgw_transaction_id $response(transaction_id) + + # Interpret the response_code. + + switch -exact $response_code { + + "failure" { + + # The payment gateway rejected to authorize the + # transaction. Or is not cable of authorizing + # transactions. + + # Probably don't need to do this update of + # to_be_captured_p because no cron jobs + # distinguish between null and 'f' right now, but + # it doesn't hurt and it might alleviate someone's + # concern when they're looking at + # ec_financial_transactions and wondering whether + # they should be concerned that failed_p is 't' + + db_dml set_ft_failure " + update ec_financial_transactions + set failed_p='t', to_be_captured_p='f' + where transaction_id=:transaction_id" + db_dml set_gc_failure " + update ec_gift_certificates + set gift_certificate_state='failed_authorization' + where gift_certificate_id=:gift_certificate_id" + + # Present a new gift_certificate_id and a new form + + set gift_certificate_id [db_nextval ec_gift_cert_id_sequence] + + set title "Credit Card Correction Needed" + set page " +
    +

    At this time we are unable to receive authorization to charge your + credit card. Please check the number and the expiration date and + try again or use a different credit card.

    +
    + [export_form_vars gift_certificate_id certificate_to certificate_from certificate_message amount recipient_email] + + + + + + + + + + + + +
    Credit card number:
    Type:[ec_creditcard_widget $creditcard_type]
    Expires:[ec_creditcard_expire_1_widget $creditcard_expire_1] [ec_creditcard_expire_2_widget $creditcard_expire_2]
    +
    + +
    +
    +
    " + } + + "failure-retry" { + + # If the response_code is failure-retry, it means + # there was a temporary failure that can be + # retried. The transaction will be retried the + # next time the scheduled procedure + # ec_sweep_for_payment_zombies is run. + + # Present a thank-you page. + + ad_returnredirect "gift-certificate-thank-you" + return + } + + "success" { + + # The payment gateway authorized the transaction. + + # Update transaction and gift certificate to + # authorized setting to_be_captured_p to 't' will + # cause ec_unmarked_transactions to come along and + # mark it for capture + + db_dml update_ft_set_status " + update ec_financial_transactions + set authorized_date=sysdate, to_be_captured_p='t', transaction_id = :pgw_transaction_id + where transaction_id=:transaction_id" + db_dml update_ec_gc_status " + update ec_gift_certificates + set authorized_date=sysdate, gift_certificate_state='authorized' + where gift_certificate_id=:gift_certificate_id" + + # Send gift certificate order email + + ec_email_new_gift_certificate_order $gift_certificate_id + + # Present a thank-you page. + + ad_returnredirect "gift-certificate-thank-you" + return + } + + "not_supported" - + "not_implemented" { + + db_dml log_no_support_error " + insert into ec_problems_log + (problem_id, problem_date, problem_details, gift_certificate_id) + values + (ec_problem_id_sequence.nextval, sysdate, + 'Gift-certificate-finalize-order.tcl called payment gateway :payment_gateway for authorizion, which returned: :response_code.', :gift_certificate_id)" + set title "Unexpected Result" + set page " +

    We received an unexpected result when contacting the payment gateway for credit card authorization. + This problem has been logged. However, it would be helpful if you could email + [ad_system_owner] with the events that led up to this occurrence. + We apologize for this problem and we will correct it as soon as we can.

    " + } + + default { + + # Unknown response_code + + set title "Unknown response from payment gateway" + set page " +
    +

    We didn't receive confirmation from the payment gateway whether they were able to authorize the + payment for your gift certificate order.

    + +

    We will contact the payment gateway to see if they processed your transaction, and + we'll let you know by email. We apologize for the inconvenience.

    + +

    You can also check on the status of + this gift certificate order.

    +
    " + } + } + } + } +} Index: openacs-4/packages/ecommerce/www/gift-certificate-finalize-order.xql =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/ecommerce/www/gift-certificate-finalize-order.xql,v diff -u -r1.1 -r1.2 --- openacs-4/packages/ecommerce/www/gift-certificate-finalize-order.xql 10 Jul 2001 20:42:02 -0000 1.1 +++ openacs-4/packages/ecommerce/www/gift-certificate-finalize-order.xql 26 May 2002 04:36:50 -0000 1.2 @@ -1,43 +1,62 @@ + - - - select count(*) from ec_gift_certificates where gift_certificate_id=:gift_certificate_id - - + + + select count(*) + from ec_gift_certificates + where gift_certificate_id=:gift_certificate_id + + - - - - select gift_certificate_state from ec_gift_certificates where gift_certificate_id=:gift_certificate_id - - + + + select gift_certificate_state + from ec_gift_certificates + where gift_certificate_id=:gift_certificate_id + + - - - + + insert into ec_creditcards - (creditcard_id, user_id, creditcard_number, creditcard_last_four, creditcard_type, creditcard_expire, billing_zip_code) - values - (:creditcard_id, :user_id, :creditcard_number, :ccstuff_1, :creditcard_type,:expiry,:billing_zip_code) - - - + (creditcard_id, user_id, creditcard_number, creditcard_last_four, creditcard_type, creditcard_expire, billing_address) + values + (:creditcard_id, :user_id, :creditcard_number, :ccstuff_1, :creditcard_type, :expiry, :address_id) + + - - - - update ec_financial_transactions set failed_p='t', to_be_captured_p='f' where transaction_id=:transaction_id - - + + + select c.creditcard_number as card_number, substring(creditcard_expire for 2) as card_exp_month, substring(creditcard_expire from 4 for 2) as card_exp_year, c.creditcard_type, + p.first_names || ' ' || p.last_name as card_name, + a.zip_code as billing_zip, + a.line1 as billing_address, + a.city as billing_city, + coalesce(a.usps_abbrev, a.full_state_name) as billing_state, + a.country_code as billing_country + from ec_creditcards c, persons p, ec_addresses a + where c.user_id=p.person_id + and c.creditcard_id = :creditcard_id + and c.billing_address = a.address_id + + - - - - update ec_gift_certificates set gift_certificate_state='failed_authorization' where gift_certificate_id=:gift_certificate_id - - + + + update ec_financial_transactions + set failed_p='t', to_be_captured_p='f' + where transaction_id=:transaction_id + + - + + + update ec_gift_certificates + set gift_certificate_state='failed_authorization' + where gift_certificate_id=:gift_certificate_id + + + Index: openacs-4/packages/ecommerce/www/gift-certificate-order-2.tcl =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/ecommerce/www/gift-certificate-order-2.tcl,v diff -u -r1.2 -r1.3 --- openacs-4/packages/ecommerce/www/gift-certificate-order-2.tcl 31 Jan 2002 22:43:54 -0000 1.2 +++ openacs-4/packages/ecommerce/www/gift-certificate-order-2.tcl 26 May 2002 04:36:50 -0000 1.3 @@ -1,40 +1,38 @@ -# www/ecommerce/gift-certificate-order-2.tcl ad_page_contract { - asks for gift certificate info like message, amount, recipient_email - @author - @creation-date - @cvs-id gift-certificate-order-2.tcl,v 3.2.6.5 2000/08/18 21:46:33 stevenp Exp - @author ported by Jerry Asher (jerry@theashergroup.com) + + Asks for gift certificate info like message, amount, recipient_email + + @author + @creation-date + @author ported by Jerry Asher (jerry@theashergroup.com) + @author revised by Bart Teeuwisse + @revision-date April 2002 + } { } +ec_redirect_to_https_if_possible_and_necessary + +# User must be logged in + +set user_id [ad_verify_and_get_user_id] + set email "" set mightbe "" set user_id [ad_get_user_id] if {$user_id == 0} { set mightbe [ad_get_signed_cookie "ad_user_login"] if {![string equal "" $mightbe]} { set email [db_string gco_email " - select email - from persons, parties - where person_id = :mightbe - and person_id = party_id - " -default ""] + select email + from persons, parties + where person_id = :mightbe + and person_id = party_id" -default ""] } } -ec_redirect_to_https_if_possible_and_necessary - -# user must be logged in -# verify_and -set user_id [ad_verify_and_get_user_id] - -# wtem@olywa.net, 2001-03-29 -# user login rolled into ec_redirect_to_https_if_possible_and_necessary - set currency [ad_parameter -package_id [ec_id] Currency ecommerce] set minimum_amount [ec_pretty_price [ad_parameter -package_id [ec_id] MinGiftCertificateAmount ecommerce]] set maximum_amount [ec_pretty_price [ad_parameter -package_id [ec_id] MaxGiftCertificateAmount ecommerce]] - -ec_return_template +ad_return_template Index: openacs-4/packages/ecommerce/www/gift-certificate-order-2.xql =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/ecommerce/www/gift-certificate-order-2.xql,v diff -u -r1.1 -r1.2 --- openacs-4/packages/ecommerce/www/gift-certificate-order-2.xql 10 Jul 2001 20:42:02 -0000 1.1 +++ openacs-4/packages/ecommerce/www/gift-certificate-order-2.xql 26 May 2002 04:36:50 -0000 1.2 @@ -1,16 +1,14 @@ + - - - - select email - from persons, parties - where person_id = :mightbe - and person_id = party_id - - - + + + select email + from persons, parties + where person_id = :mightbe + and person_id = party_id + + - Index: openacs-4/packages/ecommerce/www/gift-certificate-order-3.tcl =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/ecommerce/www/gift-certificate-order-3.tcl,v diff -u -r1.2 -r1.3 --- openacs-4/packages/ecommerce/www/gift-certificate-order-3.tcl 31 Jan 2002 22:43:54 -0000 1.2 +++ openacs-4/packages/ecommerce/www/gift-certificate-order-3.tcl 26 May 2002 04:36:50 -0000 1.3 @@ -1,86 +1,42 @@ -# www/ecommerce/gift-certificate-order-3.tcl ad_page_contract { -asks for payment info -@param certificate_to -@param certificate_from -@param certificate_message -@param amount -@param recipient_email - @author - @creation-date - @cvs-id gift-certificate-order-3.tcl,v 3.2.6.9 2000/08/18 21:46:33 stevenp Exp - @author ported by Jerry Asher (jerry@theashergroup.com) + + Asks for payment info. + + @param address_id + @param certificate_to + @param certificate_from + @param certificate_message + @param amount + @param recipient_email + + @author + @creation-date + @author ported by Jerry Asher (jerry@theashergroup.com) + @author revised by Bart Teeuwisse + @revision-date April 2002 + } { - certificate_to:optional - certificate_from:optional - certificate_message:optional + address_id + certificate_to + certificate_from + certificate_message amount:notnull recipient_email:notnull,email } ec_redirect_to_https_if_possible_and_necessary -# user must be logged in -set user_id [ad_verify_and_get_user_id] +# User must be logged in -# wtem@olywa.net, 2001-03-29 -# user login rolled into ec_redirect_to_https_if_possible_and_necessary - -# error checking - -set exception_count 0 -set exception_text "" - -if { [string length $certificate_message] > 200 } { - incr exception_count - append exception_text "
  • The message you entered was too long. It needs to contain fewer than 200 characters (the current length is [string length $certificate_message] characters)." -} -if { [string length $certificate_to] > 100 } { - incr exception_count - append exception_text "
  • What you entered in the \"To\" field is too long. It needs to contain fewer than 100 characters (the current length is [string length $certificate_to] characters)." -} -if { [string length $certificate_from] > 100 } { - incr exception_count - append exception_text "
  • What you entered in the \"From\" field is too long. It needs to contain fewer than 100 characters (the current length is [string length $certificate_from] characters)." -} -if { [string length $recipient_email] > 100 } { - incr exception_count - append exception_text "
  • The recipient email address you entered is too long. It needs to contain fewer than 100 characters (the current length is [string length $recipient_email] characters)." -} - -if { $amount < [ad_parameter -package_id [ec_id] MinGiftCertificateAmount ecommerce] } { - incr exception_count - append exception_text "
  • The amount needs to be at least [ec_pretty_price [ad_parameter -package_id [ec_id] MinGiftCertificateAmount ecommerce]]" -} elseif { $amount > [ad_parameter -package_id [ec_id] MaxGiftCertificateAmount ecommerce] } { - incr exception_count - append exception_text "
  • The amount cannot be higher than [ec_pretty_price [ad_parameter -package_id [ec_id] MaxGiftCertificateAmount ecommerce]]" -} - -# if { [empty_string_p $recipient_email] } { -# incr exception_count -# append exception_text "
  • You forgot to specify the recipient's email address (we need it so we can send them their gift certificate!)" -# } elseif {![philg_email_valid_p $recipient_email]} { -# incr exception_count -# append exception_text "
  • The recipient's email address that you typed doesn't look right to us. Examples of valid email addresses are -#
      -#
    • Alice1234@aol.com -#
    • joe_smith@hp.com -#
    • pierre@inria.fr -#
    -# " -# } - -if { $exception_count > 0 } { - ad_return_complaint $exception_count $exception_text +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]" return } - - set ec_creditcard_widget [ec_creditcard_widget] set ec_expires_widget "[ec_creditcard_expire_1_widget] [ec_creditcard_expire_2_widget]" -set zip_code [db_string get_zip_code "select zip_code from ec_addresses where address_id=(select max(address_id) from ec_addresses where user_id=:user_id)" -default ""] -set hidden_form_variables [export_form_vars certificate_to certificate_from certificate_message amount recipient_email] -db_release_unused_handles +set hidden_form_variables [export_form_vars address_id certificate_to certificate_from certificate_message amount recipient_email] -ec_return_template +db_release_unused_handles Index: openacs-4/packages/ecommerce/www/gift-certificate-order-3.xql =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/ecommerce/www/gift-certificate-order-3.xql,v diff -u -r1.1 -r1.2 --- openacs-4/packages/ecommerce/www/gift-certificate-order-3.xql 10 Jul 2001 20:42:02 -0000 1.1 +++ openacs-4/packages/ecommerce/www/gift-certificate-order-3.xql 26 May 2002 04:36:50 -0000 1.2 @@ -1,11 +1,15 @@ + - - - select zip_code from ec_addresses where address_id=(select max(address_id) from ec_addresses where user_id=:user_id) - - + + + select zip_code + from ec_addresses + where address_id=(select max(address_id) + from ec_addresses + where user_id=:user_id) + + - Index: openacs-4/packages/ecommerce/www/gift-certificate-order-4.tcl =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/ecommerce/www/gift-certificate-order-4.tcl,v diff -u -r1.3 -r1.4 --- openacs-4/packages/ecommerce/www/gift-certificate-order-4.tcl 31 Jan 2002 22:43:54 -0000 1.3 +++ openacs-4/packages/ecommerce/www/gift-certificate-order-4.tcl 26 May 2002 04:36:50 -0000 1.4 @@ -1,11 +1,15 @@ -# www/ecommerce/gift-certificate-order-4.tcl ad_page_contract { - dispays order summary - @author - @creation-date - @cvs-id gift-certificate-order-4.tcl,v 3.2.6.6 2000/08/18 21:46:33 stevenp Exp - @author ported by Jerry Asher (jerry@theashergroup.com) + + Dispays order summary + + @author + @creation-date + @author ported by Jerry Asher (jerry@theashergroup.com) + @author revised by Bart Teeuwisse + @revision-date April 2002 + } { + address_id certificate_to certificate_from certificate_message @@ -15,101 +19,114 @@ creditcard_type creditcard_expire_1 creditcard_expire_2 - billing_zip_code } -# - ec_redirect_to_https_if_possible_and_necessary -# get rid of spaces and dashes +# Get rid of spaces and dashes + regsub -all -- "-" $creditcard_number "" creditcard_number regsub -all " " $creditcard_number "" creditcard_number -# user must be logged in +# User must be logged in + set user_id [ad_verify_and_get_user_id] -# wtem@olywa.net, 2001-03-29 -# user login rolled into ec_redirect_to_https_if_possible_and_necessary +# Error checking -# error checking - set exception_count 0 set exception_text "" if { [string length $certificate_message] > 200 } { incr exception_count - append exception_text "
  • The message you entered was too long. It needs to contain fewer than 200 characters (the current length is [string length $certificate_message] characters)." + append exception_text " +
  • + The message you entered was too long. It needs to contain fewer than 200 characters (the current length is [string length $certificate_message] characters). +
  • " } if { [string length $certificate_to] > 100 } { incr exception_count - append exception_text "
  • What you entered in the \"To\" field is too long. It needs to contain fewer than 100 characters (the current length is [string length $certificate_to] characters)." + append exception_text " +
  • + What you entered in the \"To\" field is too long. It needs to contain fewer than 100 characters (the current length is [string length $certificate_to] characters). +
  • " } if { [string length $certificate_from] > 100 } { incr exception_count - append exception_text "
  • What you entered in the \"From\" field is too long. It needs to contain fewer than 100 characters (the current length is [string length $certificate_from] characters)." + append exception_text " +
  • + What you entered in the \"From\" field is too long. It needs to contain fewer than 100 characters (the current length is [string length $certificate_from] characters). +
  • " } if { [string length $recipient_email] > 100 } { incr exception_count - append exception_text "
  • The recipient email address you entered is too long. It needs to contain fewer than 100 characters (the current length is [string length $recipient_email] characters)." + append exception_text " +
  • + The recipient email address you entered is too long. It needs to contain fewer than 100 characters (the current length is [string length $recipient_email] characters). +
  • " } if { $amount < [ad_parameter -package_id [ec_id] MinGiftCertificateAmount ecommerce] } { incr exception_count - append exception_text "
  • The amount needs to be at least [ec_pretty_price [ad_parameter -package_id [ec_id] MinGiftCertificateAmount ecommerce]]" + append exception_text " +
  • + The amount needs to be at least [ec_pretty_price [ad_parameter -package_id [ec_id] MinGiftCertificateAmount ecommerce]] +
  • " } elseif { $amount > [ad_parameter -package_id [ec_id] MaxGiftCertificateAmount ecommerce] } { incr exception_count - append exception_text "
  • The amount cannot be higher than [ec_pretty_price [ad_parameter -package_id [ec_id] MaxGiftCertificateAmount ecommerce]]" + append exception_text " +
  • + The amount cannot be higher than [ec_pretty_price [ad_parameter -package_id [ec_id] MaxGiftCertificateAmount ecommerce]] +
  • " } -# if { [empty_string_p $recipient_email] } { -# incr exception_count -# append exception_text "
  • You forgot to specify the recipient's email address (we need it so we can send them their gift certificate!)" -# } elseif {![philg_email_valid_p $recipient_email]} { -# incr exception_count -# append exception_text "
  • The recipient's email address that you typed doesn't look right to us. Examples of valid email addresses are -#
      -#
    • Alice1234@aol.com -#
    • joe_smith@hp.com -#
    • pierre@inria.fr -#
    -# " -# } - if { [regexp {[^0-9]} $creditcard_number] } { + # I've already removed spaces and dashes, so only numbers should remain + incr exception_count - append exception_text "
  • Your credit card number contains invalid characters." + append exception_text " +
  • + Your credit card number contains invalid characters. +
  • " } if { ![info exists creditcard_type] || [empty_string_p $creditcard_type] } { incr exception_count - append exception_text "
  • You forgot to enter your credit card type." + append exception_text " +
  • + You forgot to enter your credit card type. +
  • " } -# 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] +# Make sure the credit card type is right & that it has the right +# number of digits -# set exception_count [expr $exception_count + [lindex $additional_count_and_text 0]] -# append exception_text [lindex $additional_count_and_text 1] +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 "
  • Please enter your full credit card expiration date (month and year)" + append exception_text " +
  • + Please enter your full credit card expiration date (month and year) +
  • " } if { $exception_count > 0 } { ad_return_complaint $exception_count $exception_text return } - - set gift_certificate_id [db_nextval ec_gift_cert_id_sequence] -set user_email [db_string get_email_for_user "select email from cc_users where user_id=:user_id"] +set user_email [db_string get_email_for_user " + select email + from cc_users + where user_id=:user_id"] -set hidden_form_variables [export_form_vars certificate_to certificate_from certificate_message amount recipient_email creditcard_number creditcard_type creditcard_expire_1 creditcard_expire_2 billing_zip_code gift_certificate_id] +set hidden_form_variables [export_form_vars address_id certificate_to certificate_from certificate_message amount recipient_email creditcard_number creditcard_type \ + creditcard_expire_1 creditcard_expire_2 billing_address gift_certificate_id] if { ![empty_string_p $certificate_to] } { set to_row "To:$certificate_to" @@ -132,5 +149,3 @@ set formatted_amount [ec_pretty_price $amount] set zero_in_the_correct_currency [ec_pretty_price 0] db_release_unused_handles -ec_return_template - Index: openacs-4/packages/ecommerce/www/gift-certificate-order-4.xql =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/ecommerce/www/gift-certificate-order-4.xql,v diff -u -r1.1 -r1.2 --- openacs-4/packages/ecommerce/www/gift-certificate-order-4.xql 10 Jul 2001 20:42:02 -0000 1.1 +++ openacs-4/packages/ecommerce/www/gift-certificate-order-4.xql 26 May 2002 04:36:50 -0000 1.2 @@ -1,11 +1,13 @@ + - - - select email from cc_users where user_id=:user_id - - + + + select email + from cc_users + where user_id=:user_id + + - Index: openacs-4/packages/ecommerce/www/gift-certificate-order.tcl =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/ecommerce/www/gift-certificate-order.tcl,v diff -u -r1.2 -r1.3 --- openacs-4/packages/ecommerce/www/gift-certificate-order.tcl 31 Jan 2002 22:43:54 -0000 1.2 +++ openacs-4/packages/ecommerce/www/gift-certificate-order.tcl 26 May 2002 04:36:50 -0000 1.3 @@ -20,4 +20,4 @@ # from linked to pages set order_url "gift-certificate-order-2" -ec_return_template +ad_return_template Index: openacs-4/packages/ecommerce/www/gift-certificate-thank-you.tcl =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/ecommerce/www/gift-certificate-thank-you.tcl,v diff -u -r1.1 -r1.2 --- openacs-4/packages/ecommerce/www/gift-certificate-thank-you.tcl 20 Apr 2001 20:51:13 -0000 1.1 +++ openacs-4/packages/ecommerce/www/gift-certificate-thank-you.tcl 26 May 2002 04:36:50 -0000 1.2 @@ -1,20 +1,16 @@ -# www/ecommerce/gift-certificate-thank-you.tcl ad_page_contract { - the user is redirected to this page from gift-certificate-finalize-order.tcl if - their gift certificate order has succeeded + The user is redirected to this page from + gift-certificate-finalize-order.tcl if their gift certificate + order has succeeded. This page displays a thank you message. - this page displays a thank you message - @author - @creation-date - @cvs-id gift-certificate-thank-you.tcl,v 3.1.10.4 2000/08/17 21:23:07 seb Exp - @author ported by Jerry Asher (jerry@theashergroup.com) + @author + @creation-date + @author ported by Jerry Asher (jerry@theashergroup.com) + @author revised by Bart Teeuwisse + @revision-date April 2002 + } { } - - set home_page "[ec_insecure_location][ec_url]index" - - - -ec_return_template +ad_return_template Index: openacs-4/packages/ecommerce/www/gift-certificate.tcl =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/ecommerce/www/gift-certificate.tcl,v diff -u -r1.1 -r1.2 --- openacs-4/packages/ecommerce/www/gift-certificate.tcl 20 Apr 2001 20:51:13 -0000 1.1 +++ openacs-4/packages/ecommerce/www/gift-certificate.tcl 26 May 2002 04:36:50 -0000 1.2 @@ -1,22 +1,20 @@ -# www/ecommerce/gift-certificate.tcl ad_page_contract { @param gift_certificate_id @param usca_p - @author - @creation-date - @cvs-id gift-certificate.tcl,v 3.2.2.5 2000/08/18 21:46:33 stevenp Exp - @author ported by Jerry Asher (jerry@theashergroup.com) + @author + @creation-date + @author ported by Jerry Asher (jerry@theashergroup.com) + @author revised by Bart Teeuwisse + @revision-date April 2002 + } { gift_certificate_id:integer usca_p:optional } - - - - # we need them to be logged in + set user_id [ad_verify_and_get_user_id] if {$user_id == 0} { @@ -75,5 +73,5 @@ } } db_release_unused_handles -ec_return_template +ad_return_template Index: openacs-4/packages/ecommerce/www/gift-certificate.xql =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/ecommerce/www/gift-certificate.xql,v diff -u -r1.1 -r1.2 --- openacs-4/packages/ecommerce/www/gift-certificate.xql 10 Jul 2001 20:42:02 -0000 1.1 +++ openacs-4/packages/ecommerce/www/gift-certificate.xql 26 May 2002 04:36:50 -0000 1.2 @@ -1,11 +1,13 @@ + - - - select purchased_by, amount, recipient_email, certificate_to, certificate_from, certificate_message from ec_gift_certificates where gift_certificate_id=:gift_certificate_id - - + + + select purchased_by, amount, recipient_email, certificate_to, certificate_from, certificate_message + from ec_gift_certificates + where gift_certificate_id=:gift_certificate_id + + - Index: openacs-4/packages/ecommerce/www/index-oracle.xql =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/ecommerce/www/index-oracle.xql,v diff -u -r1.1 -r1.2 --- openacs-4/packages/ecommerce/www/index-oracle.xql 10 Jul 2001 20:42:02 -0000 1.1 +++ openacs-4/packages/ecommerce/www/index-oracle.xql 26 May 2002 04:36:50 -0000 1.2 @@ -1,13 +1,18 @@ - oracle8.1.6 + + oracle + 8.1.6 + - - - select 1 from dual where exists (select 1 from ec_categories) - - + + + select 1 + from dual + where exists (select 1 + from ec_categories) + + - Index: openacs-4/packages/ecommerce/www/index-postgresql.xql =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/ecommerce/www/index-postgresql.xql,v diff -u -r1.1 -r1.2 --- openacs-4/packages/ecommerce/www/index-postgresql.xql 10 Jul 2001 20:42:02 -0000 1.1 +++ openacs-4/packages/ecommerce/www/index-postgresql.xql 26 May 2002 04:36:50 -0000 1.2 @@ -1,13 +1,16 @@ - postgresql7.1 + + postgresql + 7.1 + - - - select 1 where exists (select 1 from ec_categories) - - + + + select 1 where exists (select 1 + from ec_categories) + + - Index: openacs-4/packages/ecommerce/www/index.tcl =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/ecommerce/www/index.tcl,v diff -u -r1.2 -r1.3 --- openacs-4/packages/ecommerce/www/index.tcl 31 Jan 2002 22:43:54 -0000 1.2 +++ openacs-4/packages/ecommerce/www/index.tcl 26 May 2002 04:36:50 -0000 1.3 @@ -1,19 +1,25 @@ -# www/ecommerce/index.tcl ad_page_contract { + + Entry page to the ecommerce store. + @param usca_p @param how_many @param start - @author - @creation-date - @cvs-id index.tcl,v 3.4.2.8 2000/08/21 20:14:29 tzumainn Exp - @author ported by Jerry Asher (jerry@theashergroup.com) + + @author + @creation-date + @author ported by Jerry Asher (jerry@theashergroup.com) + @author revised by Bart Teeuwisse + @revision-date April 2002 + } { usca_p:optional {how_many:naturalnum {[ad_parameter -package_id [ec_id] ProductsToDisplayPerPage ecommerce]}} {start "0"} } # see if they're logged in + set user_id [ad_verify_and_get_user_id] if { $user_id != 0 } { set user_name [db_string get_user_name "select first_names || ' ' || last_name from cc_users where user_id=:user_id"] @@ -49,68 +55,74 @@ set search_widget "" } -set recommendations_if_there_are_any "" +set recommendations_if_there_are_any "" -set header_to_print "We Recommend

    " -set header_printed 0 - -if { [ad_parameter -package_id [ec_id] UserClassApproveP ecommerce] } { +if [ad_parameter -package_id [ec_id] UserClassApproveP ecommerce] { set user_class_approved_p_clause "and user_class_approved_p = 't'" } else { set user_class_approved_p_clause "" } -db_foreach get_produc_recs "select p.product_name, p.product_id, p.dirname, r.recommendation_text -from ec_products_displayable p, ec_product_recommendations r -where p.product_id=r.product_id -and category_id is null -and subcategory_id is null -and subsubcategory_id is null -and (r.user_class_id is null or r.user_class_id in (select user_class_id - from ec_user_class_user_map - where user_id = :user_id - $user_class_approved_p_clause)) +db_foreach get_produc_recs " + select p.product_id, p.product_name, p.dirname, r.recommendation_text, o.offer_code + from ec_product_recommendations r, ec_products_displayable p left outer join ec_user_session_offer_codes o on (p.product_id = o.product_id and user_session_id = :user_session_id) + where p.product_id=r.product_id + and category_id is null + and subcategory_id is null + and subsubcategory_id is null + and (r.user_class_id is null or r.user_class_id in (select user_class_id + from ec_user_class_user_map + where user_id = :user_id + $user_class_approved_p_clause)) and r.active_p='t'" { - if { !$header_printed } { - append recommendations_if_there_are_any $header_to_print - set header_printed 1 - } - append recommendations_if_there_are_any "
    - - - - -
    [ec_linked_thumbnail_if_it_exists $dirname "f" "t"]$product_name -

    -$recommendation_text -

    -" + append recommendations_if_there_are_any " + + + + + + " } +if {[string equal $recommendations_if_there_are_any "
    [ec_linked_thumbnail_if_it_exists $dirname "f" "t"]$product_name +

    $recommendation_text

    +
    [ec_price_line $product_id $user_id $offer_code]
    "]} { + set recommendations_if_there_are_any "" +} else { + append recommendations_if_there_are_any "
    " +} -append recommendations_if_there_are_any "" - if { [ad_parameter -package_id [ec_id] SellGiftCertificatesP ecommerce] == 1 } { set gift_certificates_are_allowed 1 } else { set gift_certificates_are_allowed 0 } -set products "" +set products "" set have_how_many_more_p f set count 0 # find all top-level products (those that are uncategorized) -db_foreach get_tl_products "select -p.product_name, p.product_id, p.one_line_description -from ec_products_searchable p -where not exists (select 1 from ec_category_product_map m where p.product_id = m.product_id) -order by p.product_name" { +db_foreach get_tl_products " + select p.product_id, p.product_name, p.one_line_description, o.offer_code + from ec_products_searchable p left outer join ec_user_session_offer_codes o on (p.product_id = o.product_id and user_session_id = :user_session_id) + where not exists (select 1 from ec_category_product_map m where p.product_id = m.product_id) + order by p.product_name" { + if { $count >= $start && [expr $count - $start] < $how_many } { - append products "
    [expr $count + 1]$product_name
    $one_line_description
    \n" + append products " + + [expr $count + 1] + $product_name + + + + $one_line_description + [ec_price_line $product_id $user_id $offer_code] + " } incr count if { $count > [expr $start + (2 * $how_many)] } { @@ -121,9 +133,12 @@ set have_how_many_more_p f } } +if {[string equal $products ""]} { + set products "" +} else { + append products "
    " +} -append products "" - if { $start >= $how_many } { set prev_link "Previous $how_many" } else { @@ -146,6 +161,6 @@ } else { set separator "|" } -db_release_unused_handles -ec_return_template +db_release_unused_handles +ad_return_template Index: openacs-4/packages/ecommerce/www/index.xql =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/ecommerce/www/index.xql,v diff -u -r1.1 -r1.2 --- openacs-4/packages/ecommerce/www/index.xql 10 Jul 2001 20:42:02 -0000 1.1 +++ openacs-4/packages/ecommerce/www/index.xql 26 May 2002 04:36:50 -0000 1.2 @@ -1,46 +1,49 @@ + - - - select first_names || ' ' || last_name from cc_users where user_id=:user_id - - + + + select first_names || ' ' || last_name + from cc_users + where user_id=:user_id + + - - - - update ec_user_sessions set user_id=:user_id where user_session_id = :user_session_id - - + + + update ec_user_sessions + set user_id=:user_id + where user_session_id = :user_session_id + + - - - - select p.product_name, p.product_id, p.dirname, r.recommendation_text -from ec_products_displayable p, ec_product_recommendations r -where p.product_id=r.product_id -and category_id is null -and subcategory_id is null -and subsubcategory_id is null -and (r.user_class_id is null or r.user_class_id in (select user_class_id - from ec_user_class_user_map - where user_id = :user_id - $user_class_approved_p_clause)) -and r.active_p='t' - - + + + select p.product_id, p.product_name, p.dirname, r.recommendation_text, o.offer_code + from ec_product_recommendations r, ec_products_displayable p left outer join ec_user_session_offer_codes o on + (p.product_id = o.product_id and user_session_id = :user_session_id) + where p.product_id=r.product_id + and category_id is null + and subcategory_id is null + and subsubcategory_id is null + and (r.user_class_id is null or r.user_class_id in (select user_class_id + from ec_user_class_user_map + where user_id = :user_id + $user_class_approved_p_clause)) + and r.active_p='t' + + - - - - select -p.product_name, p.product_id, p.one_line_description -from ec_products_searchable p -where not exists (select 1 from ec_category_product_map m where p.product_id = m.product_id) -order by p.product_name - - + + + select p.product_id, p.product_name, p.one_line_description, o.offer_code + from ec_products_searchable p left outer join ec_user_session_offer_codes o on (p.product_id = o.product_id and user_session_id = :user_session_id) + where not exists (select 1 + from ec_category_product_map m + where p.product_id = m.product_id) + order by p.product_name + + - Index: openacs-4/packages/ecommerce/www/mailing-list-add-2.tcl =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/ecommerce/www/mailing-list-add-2.tcl,v diff -u -r1.1 -r1.2 --- openacs-4/packages/ecommerce/www/mailing-list-add-2.tcl 20 Apr 2001 20:51:13 -0000 1.1 +++ openacs-4/packages/ecommerce/www/mailing-list-add-2.tcl 26 May 2002 04:36:50 -0000 1.2 @@ -1,39 +1,37 @@ -# www/ecommerce/mailing-list-add-2.tcl ad_page_contract { + + Add the visitor to the selected mailing list. Mailling list are + organized by (sub)(sub)categories. + @param category_id:integer @param subcategory_id:optional @param subsubcategory_id:optional @param usca_p:optional + @author @creation-date - @cvs-id mailing-list-add-2.tcl,v 3.4.2.7 2000/08/18 21:46:34 stevenp Exp @author ported by Jerry Asher (jerry@theashergroup.com) + @author revised by Bart Teeuwisse + @revision-date April 2002 + } { category_id:integer,notnull subcategory_id:integer,optional subsubcategory_id:integer,optional usca_p:optional } - - - set user_id [ad_verify_and_get_user_id] - if {$user_id == 0} { - set return_url "[ad_conn url]?[export_form_vars category_id subcategory_id subsubcategory_id]" - ad_returnredirect "/register?[export_url_vars return_url]" return } # user session tracking set user_session_id [ec_get_user_session_id] - ec_create_new_session_if_necessary [export_entire_form_as_url_vars] -# type2 if { ![info exists subcategory_id] || [empty_string_p $subcategory_id] } { set check_string "select count(*) from ec_cat_mailing_lists where user_id=:user_id and category_id=:category_id and subcategory_id is null" @@ -63,4 +61,4 @@ set continue_shopping_options [ec_continue_shopping_options] db_release_unused_handles -ec_return_template +ad_return_template Index: openacs-4/packages/ecommerce/www/mailing-list-add-2.xql =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/ecommerce/www/mailing-list-add-2.xql,v diff -u -r1.1 -r1.2 --- openacs-4/packages/ecommerce/www/mailing-list-add-2.xql 10 Jul 2001 20:42:02 -0000 1.1 +++ openacs-4/packages/ecommerce/www/mailing-list-add-2.xql 26 May 2002 04:36:50 -0000 1.2 @@ -1,46 +1,53 @@ + - - - select category_name from ec_categories where category_id=:category_id - - + + + select category_name + from ec_categories + where category_id=:category_id + + - - - - select category_name from ec_categories where category_id=:category_id - - + + + select category_name + from ec_categories + where category_id=:category_id + + - - - - select subcategory_name from ec_subcategories where subcategory_id=:subcategory_id - - + + + select subcategory_name + from ec_subcategories + where subcategory_id=:subcategory_id + + - - - - select category_name from ec_categories where category_id=:category_id - - + + + select category_name + from ec_categories + where category_id=:category_id + + - - - - select subcategory_name from ec_subcategories where subcategory_id=:subcategory_id - - + + + select subcategory_name + from ec_subcategories + where subcategory_id=:subcategory_id + + - - - - select subsubcategory_name from ec_subsubcategories where subsubcategory_id=:subsubcategory_id - - + + + select subsubcategory_name + from ec_subsubcategories + where subsubcategory_id=:subsubcategory_id + + - Index: openacs-4/packages/ecommerce/www/mailing-list-add.tcl =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/ecommerce/www/mailing-list-add.tcl,v diff -u -r1.1 -r1.2 --- openacs-4/packages/ecommerce/www/mailing-list-add.tcl 20 Apr 2001 20:51:13 -0000 1.1 +++ openacs-4/packages/ecommerce/www/mailing-list-add.tcl 26 May 2002 04:36:50 -0000 1.2 @@ -1,64 +1,66 @@ -# www/ecommerce/mailing-list-add.tcl ad_page_contract { + This page either redirects them to log on or asks them to confirm that they are who we think they are. + @param category_id @param subcategory_id:optional @param subsubcategory_id:optional @param usca_p:optional - @author - @creation-date - @cvs-id mailing-list-add.tcl,v 3.2.2.4 2000/08/17 18:01:26 seb Exp - @author ported by Jerry Asher (jerry@theashergroup.com) + + @author + @creation-date + @author ported by Jerry Asher (jerry@theashergroup.com) + @author revised by Bart Teeuwisse + @revision-date April 2002 + } { category_id:integer subcategory_id:optional subsubcategory_id:optional usca_p:optional } - - - set user_id [ad_verify_and_get_user_id] - set return_url "[ec_url]mailing-list-add-2?[export_url_vars category_id subcategory_id subsubcategory_id]" - if {$user_id == 0} { ad_returnredirect "/register?[export_url_vars return_url]" return } # user session tracking -set user_session_id [ec_get_user_session_id] - +set user_session_id [ec_get_user_session_id] ec_create_new_session_if_necessary [export_entire_form_as_url_vars] -# type2 - ec_log_user_as_user_id_for_this_session - set user_name [db_string get_user_name "select first_names || ' ' || last_name as user_name from cc_users where user_id=:user_id"] -# if { [info exists category_id] } { -# set mailing_list_name [db_string get_mailing_list_name "select category_name from ec_categories where category_id=:category_id"] -# } elseif { [info exists subcategory_id] } { -# set mailing_list_name "[db_string get_cat_name "select category_name from ec_categories where category_id=:category_id"]: [db_string get_subcat_id "select subcategory_name from ec_subcategories where subcategory_id=:subcategory_id"]" -# } elseif { [info exists subsubcategory_id] } { -# set mailing_list_name "[db_string get_cat_name "select category_name from ec_categories where category_id=:category_id"]: [db_string get_subcat_name "select subcategory_name from ec_subcategories where subcategory_id=:subcategory_id"]: [db_string get_subsubcat_name "select subsubcategory_name from ec_subsubcategories where subsubcategory_id=:subsubcategory_id"]" -# } else { -# ad_return_complaint 1 "You haven't specified which mailing list you want to be added to." -# return -# } - if { ![info exists subcategory_id] || [empty_string_p $subcategory_id] } { - set mailing_list_name [db_string get_cat_name "select category_name from ec_categories where category_id=:category_id"] + set mailing_list_name [db_string get_cat_name " + select category_name + from ec_categories + where category_id=:category_id"] } elseif { ![info exists subsubcategory_id] || [empty_string_p $subsubcategory_id] } { - set mailing_list_name "[db_string get_cat_name "select category_name from ec_categories where category_id=:category_id"]: [db_string get_subcat_name "select subcategory_name from ec_subcategories where subcategory_id=:subcategory_id"]" + set mailing_list_name "[db_string get_cat_name " + select category_name + from ec_categories + where category_id=:category_id"]: [db_string get_subcat_name " + select subcategory_name + from ec_subcategories + where subcategory_id=:subcategory_id"]" } elseif { [info exists subsubcategory_id] && ![empty_string_p $subsubcategory_id] } { validate_integer "subsubcategory_id" $subsubcategory_id validate_integer "subcategory_id" $subcategory_id - set mailing_list_name "[db_string get_cat_name "select category_name from ec_categories where category_id=:category_id"]: [db_string get_subcat_name "select subcategory_name from ec_subcategories where subcategory_id=:subcategory_id"]: [db_string get_subsubcat_name "select subsubcategory_name from ec_subsubcategories where subsubcategory_id=:subsubcategory_id"]" + set mailing_list_name "[db_string get_cat_name " + select category_name + from ec_categories + where category_id=:category_id"]: [db_string get_subcat_name " + select subcategory_name + from ec_subcategories + where subcategory_id=:subcategory_id"]: [db_string get_subsubcat_name " + select subsubcategory_name + from ec_subsubcategories + where subsubcategory_id=:subsubcategory_id"]" } else { ad_return_complaint 1 "You haven't specified which mailing list you want to be added to." return @@ -67,4 +69,4 @@ set register_link "/register?[export_url_vars return_url]" set hidden_form_variables [export_form_vars category_id subcategory_id subsubcategory_id] db_release_unused_handles -ec_return_template \ No newline at end of file +ad_return_template Index: openacs-4/packages/ecommerce/www/mailing-list-add.xql =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/ecommerce/www/mailing-list-add.xql,v diff -u -r1.1 -r1.2 --- openacs-4/packages/ecommerce/www/mailing-list-add.xql 10 Jul 2001 20:42:02 -0000 1.1 +++ openacs-4/packages/ecommerce/www/mailing-list-add.xql 26 May 2002 04:36:50 -0000 1.2 @@ -1,53 +1,61 @@ + - - - select first_names || ' ' || last_name as user_name from cc_users where user_id=:user_id - - + + + select first_names || ' ' || last_name as user_name + from cc_users + where user_id=:user_id + + - - - - select category_name from ec_categories where category_id=:category_id - - + + + select category_name + from ec_categories + where category_id=:category_id + + - - - - select category_name from ec_categories where category_id=:category_id - - + + + select category_name + from ec_categories + where category_id=:category_id + + - - - - select subcategory_name from ec_subcategories where subcategory_id=:subcategory_id - - + + + select subcategory_name + from ec_subcategories + where subcategory_id=:subcategory_id + + - - - - select category_name from ec_categories where category_id=:category_id - - + + + select category_name + from ec_categories + where category_id=:category_id + + - - - - select subcategory_name from ec_subcategories where subcategory_id=:subcategory_id - - + + + select subcategory_name + from ec_subcategories + where subcategory_id=:subcategory_id + + - - - - select subsubcategory_name from ec_subsubcategories where subsubcategory_id=:subsubcategory_id - - + + + select subsubcategory_name + from ec_subsubcategories + where subsubcategory_id=:subsubcategory_id + + - Index: openacs-4/packages/ecommerce/www/mailing-list-remove.tcl =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/ecommerce/www/mailing-list-remove.tcl,v diff -u -r1.1 -r1.2 --- openacs-4/packages/ecommerce/www/mailing-list-remove.tcl 20 Apr 2001 20:51:13 -0000 1.1 +++ openacs-4/packages/ecommerce/www/mailing-list-remove.tcl 26 May 2002 04:36:50 -0000 1.2 @@ -1,68 +1,73 @@ -# www/ecommerce/mailing-list-remove.tcl ad_page_contract { @param category_id @param subcategory_id:optional @param subsubcategory_id:optional @param usca_p:optional - @author @creation-date - @cvs-id mailing-list-remove.tcl,v 3.4.2.5 2000/08/18 21:46:34 stevenp Exp @author ported by Jerry Asher (jerry@theashergroup.com) + @author revised by Bart Teeuwisse + @revision-date April 2002 + } { category_id:integer subcategory_id:optional subsubcategory_id:optional usca_p:optional - } - - set user_id [ad_verify_and_get_user_id] - if {$user_id == 0} { - set return_url "[ad_conn url]?[export_form_vars category_id subcategory_id subsubcategory_id]" - ad_returnredirect "/register?[export_url_vars return_url]" return } # user session tracking -set user_session_id [ec_get_user_session_id] - +set user_session_id [ec_get_user_session_id] ec_create_new_session_if_necessary [export_entire_form_as_url_vars] -# type2 set delete_string "delete from ec_cat_mailing_lists where user_id=:user_id" if { [info exists category_id] && ![empty_string_p $category_id] } { append delete_string " and category_id=:category_id" - set mailing_list_name [db_string get_mailing_list_name "select category_name from ec_categories where category_id=:category_id"] - + set mailing_list_name [db_string get_mailing_list_name " + select category_name + from ec_categories + where category_id=:category_id"] } else { append delete_string " and category_id is null" } if { [info exists subcategory_id] && ![empty_string_p $subcategory_id] } { validate_integer "subcategory_id" $subcategory_id append delete_string " and subcategory_id=:subcategory_id" - set mailing_list_name "[db_string get_mailing_list_name "select category_name from ec_categories where category_id=:category_id"]: [db_string get_subcat_ml_name "select subcategory_name from ec_subcategories where subcategory_id=:subcategory_id"]" - + set mailing_list_name "[db_string get_mailing_list_name " + select category_name + from ec_categories + where category_id=:category_id"]: [db_string get_subcat_ml_name " + select subcategory_name + from ec_subcategories + where subcategory_id=:subcategory_id"]" } else { append delete_string " and subcategory_id is null" } - if { [info exists subsubcategory_id] && ![empty_string_p $subsubcategory_id] } { validate_integer "subsubcategory_id" $subsubcategory_id - append delete_string " and subsubcategory_id=:subsubcategory_id" - set mailing_list_name "[db_string get_cat_ml_name "select category_name from ec_categories where category_id=:category_id"]: [db_string get_ml_subcat_name "select subcategory_name from ec_subcategories where subcategory_id=:subcategory_id"]: [db_string get_subsub_ml_name "select subsubcategory_name from ec_subsubcategories where subsubcategory_id=:subsubcategory_id"]" - + set mailing_list_name "[db_string get_cat_ml_name " + select category_name + from ec_categories + where category_id=:category_id"]: [db_string get_ml_subcat_name " + select subcategory_name + from ec_subcategories + where subcategory_id=:subcategory_id"]: [db_string get_subsub_ml_name " + select subsubcategory_name + from ec_subsubcategories + where subsubcategory_id=:subsubcategory_id"]" } else { append delete_string " and subsubcategory_id is null" } @@ -74,11 +79,10 @@ db_dml remove_user_from_mailing_list $delete_string -set re_add_link "[ec_insecure_location][ec_url]mailing-list-add?[export_url_vars category_id subcategory_id subsubcategory_id]" - +set re_add_link " + [ec_insecure_location][ec_url]mailing-list-add?[export_url_vars category_id subcategory_id subsubcategory_id]" set back_to_account_link "Your Account" - set continue_shopping_options [ec_continue_shopping_options] -db_release_unused_handles -ec_return_template \ No newline at end of file +db_release_unused_handles +ad_return_template Index: openacs-4/packages/ecommerce/www/mailing-list-remove.xql =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/ecommerce/www/mailing-list-remove.xql,v diff -u -r1.1 -r1.2 --- openacs-4/packages/ecommerce/www/mailing-list-remove.xql 10 Jul 2001 20:42:02 -0000 1.1 +++ openacs-4/packages/ecommerce/www/mailing-list-remove.xql 26 May 2002 04:36:50 -0000 1.2 @@ -1,46 +1,53 @@ + - - - select category_name from ec_categories where category_id=:category_id - - + + + select category_name + from ec_categories + where category_id=:category_id + + - - - - select category_name from ec_categories where category_id=:category_id - - + + + select category_name + from ec_categories + where category_id=:category_id + + - - - - select subcategory_name from ec_subcategories where subcategory_id=:subcategory_id - - + + + select subcategory_name + from ec_subcategories + where subcategory_id=:subcategory_id + + - - - - select category_name from ec_categories where category_id=:category_id - - + + + select category_name + from ec_categories + where category_id=:category_id + + - - - - select subcategory_name from ec_subcategories where subcategory_id=:subcategory_id - - + + + select subcategory_name + from ec_subcategories + where subcategory_id=:subcategory_id + + - - - - select subsubcategory_name from ec_subsubcategories where subsubcategory_id=:subsubcategory_id - - + + + select subsubcategory_name + from ec_subsubcategories + where subsubcategory_id=:subsubcategory_id + + - Index: openacs-4/packages/ecommerce/www/order.tcl =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/ecommerce/www/order.tcl,v diff -u -r1.1 -r1.2 --- openacs-4/packages/ecommerce/www/order.tcl 20 Apr 2001 20:51:13 -0000 1.1 +++ openacs-4/packages/ecommerce/www/order.tcl 26 May 2002 04:36:50 -0000 1.2 @@ -1,49 +1,43 @@ -# www/ecommerce/order.tcl ad_page_contract { + Displays an order for the user + @param order_id:integer @param usca_p:optional - @author - @creation-date - @cvs-id order.tcl,v 3.2.2.6 2000/08/18 21:46:34 stevenp Exp - @author ported by Jerry Asher (jerry@theashergroup.com) + + @author + @creation-date + @author ported by Jerry Asher (jerry@theashergroup.com) + @author revised by Bart Teeuwisse + @revision-date April 2002 + } { order_id:integer usca_p:optional - } - - # we need them to be logged in -set user_id [ad_verify_and_get_user_id] +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]" return } # user session tracking -set user_session_id [ec_get_user_session_id] - - +set user_session_id [ec_get_user_session_id] ec_create_new_session_if_necessary [export_url_vars order_id] - ec_log_user_as_user_id_for_this_session -set order_summary "
    +set order_summary "
    +
     Order #:
     $order_id
     
     Status:
     [ec_order_status $order_id]
     
    -[ec_order_summary_for_customer $order_id $user_id "t"] -" - -ec_return_template +[ec_order_summary_for_customer $order_id $user_id "t"]" Index: openacs-4/packages/ecommerce/www/payment-oracle.xql =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/ecommerce/www/payment-oracle.xql,v diff -u -r1.1 -r1.2 --- openacs-4/packages/ecommerce/www/payment-oracle.xql 10 Jul 2001 20:42:02 -0000 1.1 +++ openacs-4/packages/ecommerce/www/payment-oracle.xql 26 May 2002 04:36:50 -0000 1.2 @@ -1,17 +1,17 @@ - oracle8.1.6 + + oracle + 8.1.6 + - - - - select ec_order_cost(:order_id) as otppgc, - ec_gift_certificate_balance(:user_id) as user_gift_certificate_balance - from dual - - - + + + 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/ecommerce/www/payment-postgresql.xql =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/ecommerce/www/payment-postgresql.xql,v diff -u -r1.1 -r1.2 --- openacs-4/packages/ecommerce/www/payment-postgresql.xql 10 Jul 2001 20:42:02 -0000 1.1 +++ openacs-4/packages/ecommerce/www/payment-postgresql.xql 26 May 2002 04:36:50 -0000 1.2 @@ -1,17 +1,15 @@ - postgresql7.1 + + postgresql + 7.1 + - - - - select ec_order_cost(:order_id) as otppgc, - ec_gift_certificate_balance(:user_id) as user_gift_certificate_balance - - - - + + + select ec_order_cost(:order_id) as otppgc, ec_gift_certificate_balance(:user_id) as user_gift_certificate_balance + + - Index: openacs-4/packages/ecommerce/www/payment.tcl =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/ecommerce/www/payment.tcl,v diff -u -r1.3 -r1.4 --- openacs-4/packages/ecommerce/www/payment.tcl 16 Feb 2002 23:32:06 -0000 1.3 +++ openacs-4/packages/ecommerce/www/payment.tcl 26 May 2002 04:36:50 -0000 1.4 @@ -1,171 +1,231 @@ -# www/ecommerce/payment.tcl ad_page_contract { -This script has to check whether the user has a gift_certificate that can cover the - cost of the order and, if not, present credit card form - @author - @creation-date - @cvs-id payment.tcl,v 3.2.6.7 2000/08/18 21:46:34 stevenp Exp - @author ported by Jerry Asher (jerry@theashergroup.com) + + This script has to check whether the user has a gift_certificate that can cover the + cost of the order and, if not, present credit card form + + @author + @creation-date + @author ported by Jerry Asher (jerry@theashergroup.com) + @author revised by Bart Teeuwisse + @revision-date April 2002 + } { + address_id:integer,optional + address_type: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] +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]" return } -# make sure they have an in_basket order, otherwise they've probably +# Make sure they have an in_basket order, otherwise they've probably # gotten here by pushing Back, so return them to index.tcl -# user session tracking -set user_session_id [ec_get_user_session_id] +# User session tracking +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 success_p [db_0or1row get_order_id_and_order_owner " - select order_id, - shipping_address as address_id, - user_id as order_owner - from ec_orders - where user_session_id=:user_session_id - and order_state='in_basket' - "] +# Store the input address_id as billing_address_id so that the next +# query won't overwrite it. +set billing_address_id $address_id +set success_p [db_0or1row get_order_id_and_order_owner " + select order_id, + shipping_address as address_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 + + # No rows came back, so they probably got here by pushing "Back", + # so just redirect them to index.tcl + ad_returnredirect index.tcl return } -if { $order_owner != $user_id || [empty_string_p $address_id] } { +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) + # 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; + # if they get here, either they managed to skip past checkout.tcl, + # or they messed w/their user_session_id cookie; # address_id should already be in the database for this order - # otherwise they've probably gotten here via url surgery, so redirect them - # to checkout.tcl + # otherwise they've probably gotten here via url surgery, so + # redirect them to checkout.tcl ad_returnredirect checkout.tcl return } -# 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 { [empty_string_p $address_id] } { -if { [db_string get_ec_item_cart_count "select count(*) from ec_items where order_id=:order_id"] == 0 } { + # 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] + return + } +} + +# 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_cart_count " + select count(*) + from ec_items + where order_id=:order_id"] == 0 } { ad_returnredirect shopping-cart.tcl return } -# 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 +# Everything is ok now; the user has a non-empty in_basket order and +# an address associated with it. +if {[info exists address_type] && [string equal $address_type "shipping"]} { + + set saved_user_id $user_id + + # Clone the shipping address and make it a billing address. This + # allows the user to delete the billing address at a later point + # without affecting the shipping address. + + if {[db_0or1row get_shipping_address " + select * + from ec_addresses + where address_id = :address_id"]} { + + set address_id [db_nextval ec_address_id_sequence] + db_dml insert_new_address " + insert into ec_addresses + (address_id, user_id, address_type, attn, line1, line2, city, usps_abbrev, zip_code, full_state_name, country_code, phone, phone_time) + values + (:address_id, :user_id, 'billing', :attn, :line1, :line2, :city, :usps_abbrev, :zip_code, :full_state_name, :country_code, :phone,:phone_time)" + } + set user_id $saved_user_id +} + +# Now get the other necessary information + set form_action [ec_securelink [ec_url]process-payment.tcl] -# 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 +# 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 - " + 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 +# 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 -# I know these variable names look kind of retarded, but I think they'll -# make things clearer for non-programmers editing the ADP templates: +# I know these variable names look kind of retarded, but I think +# they'll make things clearer for non-programmers editing the ADP +# templates: + set gift_certificate_covers_whole_order 0 set gift_certificate_covers_part_of_order 0 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 1 - # see if the administrator lets customers reuse their credit cards + # See if the administrator lets customers reuse their credit cards + if { [ad_parameter -package_id [ec_id] SaveCreditCardDataP ecommerce] } { - # then see if we have any credit cards on file for this user + + # 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 " - " - + + set to_print_before_creditcards " +
    Card TypeLast 4 DigitsExpires
    + + + + + + " 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 and o.shipping_address=$address_id) - order by c.creditcard_id desc" { - + 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 "\n - " + append old_cards_to_choose_from " + > + + + + " 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]" - set zip_code [db_string get_zip_code "select zip_code from ec_addresses where address_id=:address_id"] - # 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. + # 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 "
    Card TypeLast 4 DigitsExpires
    + [ec_pretty_creditcard_type $creditcard_type]$creditcard_last_four$creditcard_expire
    [ec_pretty_creditcard_type $creditcard_type]$creditcard_last_four$creditcard_expire
    " - } db_release_unused_handles - -ec_return_template +ad_return_template Index: openacs-4/packages/ecommerce/www/payment.xql =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/ecommerce/www/payment.xql,v diff -u -r1.1 -r1.2 --- openacs-4/packages/ecommerce/www/payment.xql 10 Jul 2001 20:42:02 -0000 1.1 +++ openacs-4/packages/ecommerce/www/payment.xql 26 May 2002 04:36:50 -0000 1.2 @@ -1,45 +1,34 @@ + - - - - select order_id, - shipping_address as address_id, - user_id as order_owner - from ec_orders - where user_session_id=:user_session_id - and order_state='in_basket' - - - + + + select order_id, shipping_address as address_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_items + where order_id=:order_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 and o.shipping_address=$address_id) - order by c.creditcard_id desc - - + 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 + + - - - - select zip_code from ec_addresses where address_id=:address_id - - - - Index: openacs-4/packages/ecommerce/www/process-order-quantity-shipping-oracle.xql =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/ecommerce/www/process-order-quantity-shipping-oracle.xql,v diff -u -r1.1 -r1.2 --- openacs-4/packages/ecommerce/www/process-order-quantity-shipping-oracle.xql 10 Jul 2001 20:42:02 -0000 1.1 +++ openacs-4/packages/ecommerce/www/process-order-quantity-shipping-oracle.xql 26 May 2002 04:36:50 -0000 1.2 @@ -1,38 +1,40 @@ - oracle8.1.6 + + oracle + 8.1.6 + - - + + 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 - - + 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(base_shipping_cost,0) + from ec_admin_settings + + - - - - select nvl(add_exp_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 - - + + + select ec_tax(0,:order_shipping_cost,:order_id) + from dual + + - Index: openacs-4/packages/ecommerce/www/process-order-quantity-shipping-postgresql.xql =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/ecommerce/www/process-order-quantity-shipping-postgresql.xql,v diff -u -r1.1 -r1.2 --- openacs-4/packages/ecommerce/www/process-order-quantity-shipping-postgresql.xql 10 Jul 2001 20:42:02 -0000 1.1 +++ openacs-4/packages/ecommerce/www/process-order-quantity-shipping-postgresql.xql 26 May 2002 04:36:50 -0000 1.2 @@ -1,13 +1,40 @@ - postgresql7.1 + + postgresql + 7.1 + - - - select ec_tax(0,:order_shipping_cost,:order_id) - - + + + select ec_tax(0,:order_shipping_cost,: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 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 + + + Index: openacs-4/packages/ecommerce/www/process-order-quantity-shipping.tcl =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/ecommerce/www/process-order-quantity-shipping.tcl,v diff -u -r1.3 -r1.4 --- openacs-4/packages/ecommerce/www/process-order-quantity-shipping.tcl 16 Feb 2002 23:32:06 -0000 1.3 +++ openacs-4/packages/ecommerce/www/process-order-quantity-shipping.tcl 26 May 2002 04:36:50 -0000 1.4 @@ -1,147 +1,219 @@ -# www/ecommerce/process-order-quantity-shipping.tcl ad_page_contract { - updates quantities, sets the shipping method, + + Updates quantities, sets the shipping method, and finalizes the prices (inserts them into ec_items) + @author @creation-date - @cvs-id process-order-quantity-shipping.tcl,v 3.3.6.7 2000/08/18 21:46:34 stevenp Exp @author ported by Jerry Asher (jerry@theashergroup.com) + @author revised by Bart Teeuwisse + @revision-date April 2002 + } { shipping_method:optional usca_p:optional tax_exempt_p:optional + shipping_gateway:optional quantity:array,optional } - ec_redirect_to_https_if_possible_and_necessary +if {[info exists shipping_gateway] && [string equal $shipping_gateway "true"]} { + if { ![info exists shipping_method] } { + ad_return_error "A shipping method is required" " +

    You forgot to select a shipping method.

    +

    Please back up your browser and pick a shipping service from the available services.

    +

    Should no shiping options be available for your shipping address then back up your browser + further and pick a different shipping address. Or contact to arrange for special delivery.

    " + } +} else { + if { ![info exists shipping_method] } { + set shipping_method "standard" + } +} + if {[info exists quantity]} { set arraynames [array names quantity] set fullarraynames [list] foreach arrayname $arraynames { set quantity.$arrayname $quantity($arrayname) lappend fullarraynames "quantity.$arrayname" } - set return_url "process-order-quantity-shipping?[export_url_vars creditcard_id creditcard_number creditcard_type creditcard_expire_1 creditcard_expire_2 billing_zip_code shipping_method tax_exempt_p]" + set return_url "process-order-quantity-shipping?[export_url_vars creditcard_id creditcard_number creditcard_type creditcard_expire_1 creditcard_expire_2 address_id shipping_method shipping_gateway tax_exempt_p]" ad_returnredirect "shopping-cart-quantities-change?[export_url_vars return_url]&[eval export_url_vars $fullarraynames]" return } -# we need them to be logged in -set user_id [ad_verify_and_get_user_id] +# We need them to be logged in +set user_id [ad_verify_and_get_user_id] if {$user_id == 0} { - set form [ns_conn form] if { ![empty_string_p $form] } { set return_url "[ad_conn url]?[export_entire_form_as_url_vars]" } else { set return_url "[ad_conn url]" } - ad_returnredirect "/register?[export_url_vars return_url]" return } -# user sessions: +# 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 +# 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 [ec_export_entire_form_as_url_vars_maybe] -# type3 - ec_log_user_as_user_id_for_this_session -# make sure they have an in_basket order, otherwise they've probably +# Make sure they have an in_basket order, otherwise they've probably # gotten here by pushing Back, so return them to index.tcl -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 ""] +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 + + # Then they probably got here by pushing "Back", so just redirect + # them to index.tcl + ad_returnredirect index.tcl return } -# make sure there's something in their shopping cart, otherwise -# redirect them to their shopping cart which will tell them -# that it's empty. +# 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_count_cart "select count(*) from ec_items where order_id=:order_id"] == 0 } { +if { [db_string get_count_cart " + select count(*) + from ec_items + where order_id = :order_id"] == 0 } { ad_returnredirect shopping-cart.tcl db_release_unused_handles return } -# 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"] +# 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 } { ad_returnredirect checkout.tcl return } -# make sure there is an address for this order, otherwise they've probably -# gotten here via url surgery, so redirect them to checkout.tcl +# 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 ""] +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] } { - ad_returnredirect checkout.tcl - return -} -if { ![info exists shipping_method] } { - set shipping_method "standard" + # 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 checkout.tcl + return + } } if { ![info exists tax_exempt_p] } { set tax_exempt_p "f" - ns_log Notice "no tax_exempt_p" } -# everything is ok now; the user has a non-empty in_basket order and an -# address associated with it, so now update shipping method +# Everything is ok now; the user has a non-empty in_basket order and +# an address associated with it, so now update shipping method -# 1. update the shipping method and tax status -db_dml update_shipping_method "update ec_orders -set shipping_method=:shipping_method, - tax_exempt_p=:tax_exempt_p -where order_id=:order_id" +# 1. Update the shipping method and tax status -# 2. put the prices into ec_items +if {[info exists shipping_gateway] && [string equal $shipping_gateway "true"]} { -# set some things to use as arguments when setting prices + # 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) +} + +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"] +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 { $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" - +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 { - 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 + 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"] +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] && $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 } { + 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 } @@ -150,51 +222,66 @@ set shipping_p f } -# set selection [ns_db select $db "select item_id, product_id -# from ec_items -# where order_id=$order_id"] +# These will be updated as we loop through the items -# 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" { +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 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" -} + 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 { $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 -} +if {![info exists shipping_gateway]} { + 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 { $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] + # Add on the extra base cost for express shipping, if appropriate + + if { $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"] +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" -db_release_unused_handles -ad_returnredirect payment.tcl +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" +db_release_unused_handles +ad_returnredirect billing.tcl Index: openacs-4/packages/ecommerce/www/process-order-quantity-shipping.xql =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/ecommerce/www/process-order-quantity-shipping.xql,v diff -u -r1.2 -r1.3 --- openacs-4/packages/ecommerce/www/process-order-quantity-shipping.xql 11 Jul 2001 04:52:05 -0000 1.2 +++ openacs-4/packages/ecommerce/www/process-order-quantity-shipping.xql 26 May 2002 04:36:50 -0000 1.3 @@ -1,119 +1,101 @@ + - - - 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_session_id=:user_session_id + and order_state='in_basket' + + - - - - select count(*) from ec_items where order_id=:order_id - - + + + select count(*) + from ec_items + where order_id=:order_id + + - - - - select user_id from ec_orders 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 shipping_address + from ec_orders + where order_id=:order_id + + - - - + + update ec_orders -set shipping_method=:shipping_method, - tax_exempt_p=:tax_exempt_p -where order_id=:order_id - - + 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 user_class_id + from ec_user_class_user_map + where user_id=:user_id $additional_user_class_restriction + + - - - - select default_shipping_per_item, weight_shipping_cost from ec_admin_settings - - + + + 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 - - + + + select add_exp_amount_per_item, add_exp_amount_by_weight + from ec_admin_settings + + - - - - select usps_abbrev from ec_addresses 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 - - + + + select tax_rate, shipping_p + from ec_sales_tax_by_state + where usps_abbrev=:usps_abbrev + + - - - + + + 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 + + -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 + + + 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 + + - - - - - - - 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 - - - - - - - select coalesce(base_shipping_cost,0) from ec_admin_settings - - - - - - - select coalesce(add_exp_base_shipping_cost,0) 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/ecommerce/www/process-payment-oracle.xql =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/ecommerce/www/process-payment-oracle.xql,v diff -u -r1.2 -r1.3 --- openacs-4/packages/ecommerce/www/process-payment-oracle.xql 31 Jan 2002 06:41:59 -0000 1.2 +++ openacs-4/packages/ecommerce/www/process-payment-oracle.xql 26 May 2002 04:36:50 -0000 1.3 @@ -1,11 +1,15 @@ - oracle8.1.6 + + oracle + 8.1.6 + - select ec_gift_certificate_balance(:user_id) from dual + select ec_gift_certificate_balance(:user_id) + from dual Index: openacs-4/packages/ecommerce/www/process-payment-postgresql.xql =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/ecommerce/www/process-payment-postgresql.xql,v diff -u -r1.2 -r1.3 --- openacs-4/packages/ecommerce/www/process-payment-postgresql.xql 31 Jan 2002 06:41:59 -0000 1.2 +++ openacs-4/packages/ecommerce/www/process-payment-postgresql.xql 26 May 2002 04:36:50 -0000 1.3 @@ -1,12 +1,15 @@ - postgresql7.1 + + postgresql + 7.1 + - select ec_gift_certificate_balance(:user_id) + select ec_gift_certificate_balance(:user_id) - + Index: openacs-4/packages/ecommerce/www/process-payment.tcl =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/ecommerce/www/process-payment.tcl,v diff -u -r1.2 -r1.3 --- openacs-4/packages/ecommerce/www/process-payment.tcl 29 Jan 2002 00:11:46 -0000 1.2 +++ openacs-4/packages/ecommerce/www/process-payment.tcl 26 May 2002 04:36:50 -0000 1.3 @@ -1,4 +1,3 @@ -# www/ecommerce/process-payment.tcl ad_page_contract { Begins processing a payment from a customer, using either a credit @@ -13,123 +12,149 @@ @param creditcard_type @param creditcard_expire_1 @param creditcard_expire_2 - @param billing_zip_code + @param billing_address_id + @author original author unknown (eveander@arsdigita.com?) @author hbrock@arsdigita.com @creation-date - @cvs-id process-payment.tcl,v 3.2.6.9 2000/08/18 21:46:34 stevenp Exp @author ported by Jerry Asher (jerry@theashergroup.com) + @author revised by Bart Teeuwisse + @revision-date April 2002 + } { creditcard_id:optional creditcard_number:optional creditcard_type:optional creditcard_expire_1:optional creditcard_expire_2:optional - billing_zip_code:optional + billing_address_id:optional usca_p:optional } - - - ec_redirect_to_https_if_possible_and_necessary if { [info exists creditcard_number] } { + # get rid of spaces and dashes + regsub -all -- "-" $creditcard_number "" creditcard_number regsub -all " " $creditcard_number "" creditcard_number } +# We need them to be logged in -# 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]" return } -# user sessions: +# 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 [ec_export_entire_form_as_url_vars_maybe] -# type3 - ec_log_user_as_user_id_for_this_session -# make sure they have an in_basket order, otherwise they've probably +# Make sure they have an in_basket order, otherwise they've probably # gotten here by pushing Back, so return them to index.tcl -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 ""] - +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 + + # Then they probably got here by pushing "Back", so just redirect + # them to index.tcl + ad_returnredirect index.tcl return } -# make sure there's something in their shopping cart, otherwise +# 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_shopping_cart_no "select count(*) from ec_items where order_id=:order_id"] == 0 } { +if { [db_string get_shopping_cart_no " + select count(*) + from ec_items + where order_id=:order_id"] == 0 } { ad_returnredirect shopping-cart.tcl return } -# 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"] +# 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 } { ad_returnredirect checkout.tcl return } -# make sure there is an address for this order, otherwise they've probably -# gotten here via url surgery, so redirect them to checkout.tcl +# 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 ""] +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] } { - ad_returnredirect checkout.tcl - return + + # 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] + return + } } -# make sure there is a shipping method for this order, otherwise they've probably -# gotten here via url surgery, so redirect them to checkout-2.tcl +# Make sure there is a shipping method for this order, otherwise +# they've probably gotten here via url surgery, so redirect them to +# checkout-2.tcl -set shipping_method [db_string get_shipping_method "select shipping_method from ec_orders where order_id=:order_id"] +set shipping_method [db_string get_shipping_method " + select shipping_method + from ec_orders + where order_id=:order_id"] if { [empty_string_p $shipping_method] } { ad_returnredirect checkout-2.tcl return } - -## now do error checking; It is required that either +# 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] +# 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"] - - +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 { @@ -140,19 +165,25 @@ 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 + + # Then they haven't selected a previous credit card nor + # have they entered new credit card info + ad_return_complaint 1 "
  • You forgot to specify which credit card you'd like to use." return } else { - # then they are using a new credit card and we just have to check that they - # got it all right + + # 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 + + # I've already removed spaces and dashes, so only + # numbers should remain + incr exception_count append exception_text "
  • Your credit card number contains invalid characters." } @@ -162,10 +193,10 @@ append exception_text "
  • You forgot to enter your credit card type." } - # make sure the credit card type is right & that it has the right number - # of digits + # 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] @@ -178,55 +209,102 @@ ad_return_complaint $exception_count $exception_text return } + + # 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 "
  • You forgot to provide your billing address.
  • " + return + } } - } 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 + + # 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 + + # Probably form surgery + ad_returnredirect checkout-2.tcl return } - set creditcard_owner [db_string get_cc_owner "select user_id from ec_creditcards where creditcard_id=:creditcard_id" -default ""] + + 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 + + # Probably form surgery + ad_returnredirect checkout-2.tcl return } + + # 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 "
  • You forgot to provide your billing address.
  • " + return + } + } } -# 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 +# 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 gift_certificate doesn't cover cost, either insert or update + # credit card -if { $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" + if { $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 { - # 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_zip_code) - values - (:creditcard_id, :user_id, :creditcard_number,:cc_no , :creditcard_type,:expiry,:billing_zip_code) - " - db_dml update_order_set_cc "update ec_orders set creditcard_id=:creditcard_id where order_id=:order_id" + + # 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" } -} 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 - ad_returnredirect checkout-3.tcl Index: openacs-4/packages/ecommerce/www/process-payment.xql =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/ecommerce/www/process-payment.xql,v diff -u -r1.1 -r1.2 --- openacs-4/packages/ecommerce/www/process-payment.xql 10 Jul 2001 20:42:02 -0000 1.1 +++ openacs-4/packages/ecommerce/www/process-payment.xql 26 May 2002 04:36:50 -0000 1.2 @@ -1,78 +1,87 @@ + - - - 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_session_id=:user_session_id + and order_state='in_basket' + + - - - - select count(*) from ec_items where order_id=:order_id - - + + + select count(*) + from ec_items + where order_id=:order_id + + - - - - select user_id from ec_orders 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 shipping_address + from ec_orders + where order_id=:order_id + + - - - - select shipping_method from ec_orders where order_id=:order_id - - + + + select shipping_method + from ec_orders + where order_id=:order_id + + - - - - select user_id from ec_creditcards where creditcard_id=:creditcard_id - - + + + select user_id + from ec_creditcards + where creditcard_id=:creditcard_id + + - - - - update ec_orders set creditcard_id=:creditcard_id where order_id=:order_id - - + + + 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_zip_code) - values - (:creditcard_id, :user_id, :creditcard_number,:cc_no , :creditcard_type,:expiry,:billing_zip_code) - - - + (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_orders set creditcard_id=:creditcard_id where order_id=:order_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_orders + set creditcard_id=null + where order_id=:order_id + + - Index: openacs-4/packages/ecommerce/www/product-oracle.xql =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/ecommerce/www/product-oracle.xql,v diff -u -r1.1 -r1.2 --- openacs-4/packages/ecommerce/www/product-oracle.xql 10 Jul 2001 20:42:02 -0000 1.1 +++ openacs-4/packages/ecommerce/www/product-oracle.xql 26 May 2002 04:36:50 -0000 1.2 @@ -1,38 +1,33 @@ - oracle8.1.6 + + oracle + 8.1.6 + - - - -select * - from ec_products p, ec_custom_product_field_values v - where p.product_id = :product_id - and p.product_id = v.product_id(+) + + + select * + from ec_products p, ec_custom_product_field_values v + where p.product_id = :product_id + and p.product_id = v.product_id(+) + + - - - - - - - - select * from - (select category_id, - (select count(*) - from ec_subcategories s - where s.category_id = m.category_id) subcount, - (select count(*) - from ec_subsubcategories ss - where ss.subcategory_id = m.category_id) subsubcount + + + select * + from (select category_id, (select count(*) + from ec_subcategories s + where s.category_id = m.category_id) subcount, (select count(*) + from ec_subsubcategories ss + where ss.subcategory_id = m.category_id) subsubcount from ec_category_product_map m - where product_id = :product_id - order by subcount, subsubcount, category_id) - where rownum = 1 + where product_id = :product_id + order by subcount, subsubcount, category_id) + where rownum = 1 + + - - - - Index: openacs-4/packages/ecommerce/www/product-postgresql.xql =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/ecommerce/www/product-postgresql.xql,v diff -u -r1.3 -r1.4 --- openacs-4/packages/ecommerce/www/product-postgresql.xql 20 Jul 2001 18:26:42 -0000 1.3 +++ openacs-4/packages/ecommerce/www/product-postgresql.xql 26 May 2002 04:36:50 -0000 1.4 @@ -1,26 +1,24 @@ - postgresql7.1 + + postgresql + 7.1 + - - + + + select * + from (select category_id, (select count(*) + from ec_subcategories s + where s.category_id = m.category_id) as subcount, (select count(*) + from ec_subsubcategories ss + where ss.subcategory_id = m.category_id) as subsubcount + from ec_category_product_map m + where product_id = :product_id + order by subcount, subsubcount, category_id) some_name + limit 1 + + - select * from - (select category_id, - (select count(*) - from ec_subcategories s - where s.category_id = m.category_id) as subcount, - (select count(*) - from ec_subsubcategories ss - where ss.subcategory_id = m.category_id) as subsubcount - from ec_category_product_map m - where product_id = :product_id - order by subcount, subsubcount, category_id) some_name - limit 1 - - - - - Index: openacs-4/packages/ecommerce/www/product-search-oracle.xql =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/ecommerce/www/product-search-oracle.xql,v diff -u -r1.1 -r1.2 --- openacs-4/packages/ecommerce/www/product-search-oracle.xql 16 Feb 2002 23:32:06 -0000 1.1 +++ openacs-4/packages/ecommerce/www/product-search-oracle.xql 26 May 2002 04:36:50 -0000 1.2 @@ -1,10 +1,15 @@ + - oracle8.1.6 + + oracle + 8.1.6 + - select p.product_name, p.product_id, p.dirname, p.one_line_description,pseudo_contains(p.product_name || p.one_line_description || p.detailed_description || p.search_keywords, :search_text) as score + select p.product_name, p.product_id, p.dirname, + p.one_line_description,pseudo_contains(p.product_name || p.one_line_description || p.detailed_description || p.search_keywords, :search_text) as score from ec_products_searchable p, ec_category_product_map c where c.category_id=:category_id and p.product_id=c.product_id @@ -15,7 +20,8 @@ - select p.product_name, p.product_id, p.dirname, p.one_line_description,pseudo_contains(p.product_name || p.one_line_description || p.detailed_description || p.search_keywords, :search_text) as score + select p.product_name, p.product_id, p.dirname, + p.one_line_description,pseudo_contains(p.product_name || p.one_line_description || p.detailed_description || p.search_keywords, :search_text) as score from ec_products_searchable p, ec_subcategory_product_map c where c.subcategory_id=:subcategory_id and p.product_id=c.product_id @@ -26,7 +32,8 @@ - select p.product_name, p.product_id, p.dirname, p.one_line_description,pseudo_contains(p.product_name || p.one_line_description || p.detailed_description || p.search_keywords, :search_text) as score + select p.product_name, p.product_id, p.dirname, + p.one_line_description,pseudo_contains(p.product_name || p.one_line_description || p.detailed_description || p.search_keywords, :search_text) as score from ec_products_searchable p where pseudo_contains(p.product_name || p.one_line_description || p.detailed_description || p.search_keywords, :search_text) > 0 order by score desc Index: openacs-4/packages/ecommerce/www/product-search-postgresql.xql =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/ecommerce/www/product-search-postgresql.xql,v diff -u -r1.1 -r1.2 --- openacs-4/packages/ecommerce/www/product-search-postgresql.xql 16 Feb 2002 23:32:06 -0000 1.1 +++ openacs-4/packages/ecommerce/www/product-search-postgresql.xql 26 May 2002 04:36:50 -0000 1.2 @@ -1,10 +1,15 @@ + - postgresql7.1 + + postgresql + 7.1 + - select p.product_name, p.product_id, p.dirname, p.one_line_description, pseudo_contains(coalesce(p.product_name, '') || coalesce(p.one_line_description, '') || coalesce(p.detailed_description, '') || coalesce(p.search_keywords,''), :search_text) as score + select p.product_name, p.product_id, p.dirname, p.one_line_description, + pseudo_contains(coalesce(p.product_name, '') || coalesce(p.one_line_description, '') || coalesce(p.detailed_description, '') || coalesce(p.search_keywords,''), :search_text) as score from ec_products_searchable p, ec_category_product_map c where c.category_id=:category_id and p.product_id=c.product_id @@ -15,7 +20,8 @@ - select p.product_name, p.product_id, p.dirname, p.one_line_description, pseudo_contains(coalesce(p.product_name, '') || coalesce(p.one_line_description, '') || coalesce(p.detailed_description, '') || coalesce(p.search_keywords,''), :search_text) as score + select p.product_name, p.product_id, p.dirname, p.one_line_description, + pseudo_contains(coalesce(p.product_name, '') || coalesce(p.one_line_description, '') || coalesce(p.detailed_description, '') || coalesce(p.search_keywords,''), :search_text) as score from ec_products_searchable p, ec_subcategory_product_map c where c.subcategory_id=:subcategory_id and p.product_id=c.product_id @@ -26,7 +32,8 @@ - select p.product_name, p.product_id, p.dirname, p.one_line_description, pseudo_contains(coalesce(p.product_name, '') || coalesce(p.one_line_description, '') || coalesce(p.detailed_description, '') || coalesce(p.search_keywords,''), :search_text) as score + select p.product_name, p.product_id, p.dirname, p.one_line_description, + pseudo_contains(coalesce(p.product_name, '') || coalesce(p.one_line_description, '') || coalesce(p.detailed_description, '') || coalesce(p.search_keywords,''), :search_text) as score from ec_products_searchable p where pseudo_contains(coalesce(p.product_name, '') || coalesce(p.one_line_description, '') || coalesce(p.detailed_description, '') || coalesce(p.search_keywords,''), :search_text) > 0 order by score desc Index: openacs-4/packages/ecommerce/www/product-search.tcl =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/ecommerce/www/product-search.tcl,v diff -u -r1.3 -r1.4 --- openacs-4/packages/ecommerce/www/product-search.tcl 21 Feb 2002 21:07:15 -0000 1.3 +++ openacs-4/packages/ecommerce/www/product-search.tcl 26 May 2002 04:36:50 -0000 1.4 @@ -1,4 +1,3 @@ -# www/ecommerce/product-search.tcl ad_page_contract { @param search_text @param combocategory_id:optional @@ -9,9 +8,10 @@ @author Eve Andersson (eveander@arsdigita.com) @creation-date Summer 1999 - @cvs-id product-search.tcl,v 3.3.2.4 2000/07/21 03:59:29 ron Exp @author ported by Jerry Asher (jerry@theashergroup.com) @author Bart Teeuwisse + @revision-date April 2002 + } { search_text {combocategory_id ""} @@ -49,7 +49,7 @@ db_dml insert_search_text_to_session_info "insert into ec_user_session_info (user_session_id, category_id, search_text) values (:user_session_id, :category_id, :search_text)" } -if { ![empty_string_p $subcategory_id] } { +if { ![empty_string_p $subcategory_id] && $subcategory_id > 0} { set category_name "[ec_system_name] > [db_string get_subcategory_name "select category_name || ' > ' || subcategory_name from ec_categories c, ec_subcategories s where s.subcategory_id=:subcategory_id and c.category_id=s.category_id"] search results for '$search_text'" } else { if { ![empty_string_p $category_id] } { @@ -59,7 +59,7 @@ } } -if { ![empty_string_p $subcategory_id] } { +if { ![empty_string_p $subcategory_id] && $subcategory_id > 0} { set query_string [db_map search_subcategory] # select p.product_name, p.product_id, p.dirname, p.one_line_description,pseudo_contains(p.product_name || p.one_line_description || p.detailed_description || p.search_keywords, :search_text) as score # from ec_products_searchable p, ec_subcategory_product_map c @@ -110,4 +110,4 @@ set search_results " $search_count item[ec_decode $search_count "1" "" "s"] found.

    $search_string" } db_release_unused_handles -ec_return_template +ad_return_template Index: openacs-4/packages/ecommerce/www/product-search.xql =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/ecommerce/www/product-search.xql,v diff -u -r1.2 -r1.3 --- openacs-4/packages/ecommerce/www/product-search.xql 16 Feb 2002 23:32:06 -0000 1.2 +++ openacs-4/packages/ecommerce/www/product-search.xql 26 May 2002 04:36:50 -0000 1.3 @@ -1,21 +1,30 @@ + - insert into ec_user_session_info (user_session_id, category_id, search_text) values (:user_session_id, :category_id, :search_text) + insert into ec_user_session_info + (user_session_id, category_id, search_text) + values + (:user_session_id, :category_id, :search_text) - select category_name from ec_categories where category_id=:category_id + select category_name + from ec_categories + where category_id=:category_id - select category_name || ' > ' || subcategory_name from ec_categories c, ec_subcategories s where s.subcategory_id=:subcategory_id and c.category_id=s.category_id + select category_name || ' > ' || subcategory_name + from ec_categories c, ec_subcategories s + where s.subcategory_id=:subcategory_id + and c.category_id=s.category_id Index: openacs-4/packages/ecommerce/www/product.tcl =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/ecommerce/www/product.tcl,v diff -u -r1.2 -r1.3 --- openacs-4/packages/ecommerce/www/product.tcl 31 Jan 2002 22:43:54 -0000 1.2 +++ openacs-4/packages/ecommerce/www/product.tcl 26 May 2002 04:36:50 -0000 1.3 @@ -1,16 +1,19 @@ -# www/ecommerce/product.tcl ad_page_contract { + + Display a single product and possibly comments on that + product or professional reviews + @param product_id:integer @param offer_code:optional @param comments_sort_by:optional @param usca_p:optional - display a single product and possibly comments on that - product or professional reviews - @author Eve Andersson (eveander@arsdigita.com) - @creation-date June 1999 - @cvs-id product.tcl,v 3.1.4.7 2000/09/22 01:37:31 kevin Exp - @author ported by Jerry Asher (jerry@theashergroup.com) + @author Eve Andersson (eveander@arsdigita.com) + @creation-date June 1999 + @author ported by Jerry Asher (jerry@theashergroup.com) + @author revised by Bart Teeuwisse + @revision-date April 2002 + } { product_id:integer offer_code:optional @@ -19,63 +22,105 @@ } -# default to empty string (date) +# Default to empty string (date) + if { ![info exists comments_sort_by] } { set comments_sort_by "" } -# we don't need them to be logged in, but if they are they might get a lower price +# Users don't need to be logged in but if they are the could get a +# lower price + set user_id [ad_verify_and_get_user_id] # 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 + +# 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, # (a) if they have no offer_code, then do nothing -# (b) if they have a offer_code, tell them they need cookies on if they -# want their offer price +# (b) if they have a offer_code, tell them they need cookies on if +# they want their offer price + # 4. Log this product_id into the user session set user_session_id [ec_get_user_session_id] - ec_create_new_session_if_necessary [export_url_vars product_id offer_code] cookies_are_not_required -# valid offer codes must be <= 20 characters, so if it's more than 20 characters, pretend -# it isn't there +# Valid offer codes must be <= 20 characters, so if it's more than 20 +# characters, pretend it isn't there + if { ![info exists user_session_id] } { if { [info exists offer_code] && [string length $offer_code] <= 20 } { ad_return_complaint 1 " +

    You need to have cookies turned on in order to have + special offers take effect (we use cookies to remember that you are a + recipient of this special offer.

    - You need to have cookies turned on in order to have - special offers take effect (we use cookies to remember that you are a - recipient of this special offer. -

    - - Please turn on cookies in your browser, or if you don't wish - to take advantage of this offer, you can still continue shopping at [ec_system_name] - " +

    Please turn on cookies in your browser, or if you don't wish + to take advantage of this offer, you can still continue shopping at [ec_system_name]" return } } -if { [string compare $user_session_id "0"] != 0 } { - db_dml insert_user_session_info "insert into ec_user_session_info (user_session_id, product_id) values (:user_session_id, :product_id)" +set product_id_temp $product_id +if { [db_0or1row get_ec_product_info " + select * + from ec_products p, ec_custom_product_field_values v + where p.product_id = :product_id + and p.product_id = v.product_id(+)"] == 0 } { + + doc_return 200 text/html " + [ad_header "Product Not Found"] +

    The product you have requested was not found in the database.

    +

    Please contact [ec_system_owner] to report the error.

    " + return } +# Finishing up the kludge from a few lines back +set product_id $product_id_temp + +if { [string compare $user_session_id "0"] != 0 } { + db_dml insert_user_session_info " + insert into ec_user_session_info + (user_session_id, product_id) + values + (:user_session_id, :product_id)" +} + if { [info exists offer_code] && [string compare $user_session_id "0"] != 0} { - # insert into or update ec_user_session_offer_codes - if { [db_string get_offer_code_p "select count(*) from ec_user_session_offer_codes where user_session_id=:user_session_id and product_id=:product_id"] == 0 } { - db_dml inert_uc_offer_code "insert into ec_user_session_offer_codes (user_session_id, product_id, offer_code) values (:user_session_id, :product_id, :offer_code)" + + # Insert into or update ec_user_session_offer_codes + + if { [db_string get_offer_code_p " + select count(*) + from ec_user_session_offer_codes + where user_session_id=:user_session_id + and product_id=:product_id"] == 0 } { + db_dml inert_uc_offer_code " + insert into ec_user_session_offer_codes + (user_session_id, product_id, offer_code) + values + (:user_session_id, :product_id, :offer_code)" } else { - db_dml update_ec_us_offers "update ec_user_session_offer_codes set offer_code=:offer_code where user_session_id=:user_session_id and product_id=:product_id" + db_dml update_ec_us_offers " + update ec_user_session_offer_codes + set offer_code = :offer_code + where user_session_id = :user_session_id + and product_id = :product_id" } } if { ![info exists offer_code] && [string compare $user_session_id "0"] != 0} { - set offer_code [db_string get_offer_code "select offer_code from ec_user_session_offer_codes where user_session_id=:user_session_id and product_id=:product_id" -default "" ] + set offer_code [db_string get_offer_code " + select offer_code + from ec_user_session_offer_codes + where user_session_id=:user_session_id + and product_id=:product_id" -default "" ] } if { ![info exists offer_code] } { @@ -85,88 +130,58 @@ set currency [ad_parameter -package_id [ec_id] Currency ecommerce] set allow_pre_orders_p [ad_parameter -package_id [ec_id] AllowPreOrdersP ecommerce] -# get all the information from both the products table -# and any custom product fields added by this publisher +# Get all the information from both the products table and any custom +# product fields added by this publisher -# But first... -# This is a major kludge but it is not as bad as the query that follows. +# But first... This is a major kludge but it is not as bad as the +# query that follows. -set product_id_temp $product_id - -if { [db_0or1row get_ec_product_info " -select * - from ec_products p, ec_custom_product_field_values v - where p.product_id = :product_id - and p.product_id = v.product_id(+) -"]==0} { - - doc_return 200 text/html "[ad_header "Product Not Found"]The product you have requested was not found in the database. Please contact
    [ec_system_owner]
    to report the error." - return -} - - - if { ![empty_string_p $template_id] } { # Template specified by Url set template [db_string get_template " - select template - from ec_templates - where template_id=:template_id - "] + select template + from ec_templates + where template_id=:template_id"] } else { # Template specified by Product category set template_list [db_list get_template_list " -SELECT template - FROM ec_templates t, ec_category_template_map ct, ec_category_product_map cp - WHERE t.template_id = ct.template_id - AND ct.category_id = cp.category_id - AND cp.product_id = :product_id"] - + select template + from ec_templates t, ec_category_template_map ct, ec_category_product_map cp + where t.template_id = ct.template_id + and ct.category_id = cp.category_id + and cp.product_id = :product_id"] set template [lindex $template_list 0] if [empty_string_p $template] { # Template specified by... well, just use the default set template [db_string get_template_finally " - select template - from ec_templates - where template_id=(select default_template - from ec_admin_settings)"] + select template + from ec_templates + where template_id=(select default_template + from ec_admin_settings)"] } } - -# Finishing up the kludge from a few lines back -set product_id $product_id_temp -# set category_id [db_string get_product_category " -# select category_id -# from ec_category_product_map -# where product_id = :product_id -# "] - db_foreach find_a_good_category " - select * from - (select category_id, - (select count(*) - from ec_subcategories s - where s.category_id = m.category_id) subcount, - (select count(*) - from ec_subsubcategories ss - where ss.subcategory_id = m.category_id) subsubcount - from ec_category_product_map m + select * + from (select category_id, (select count(*) + from ec_subcategories s + where s.category_id = m.category_id) subcount, + (select count(*) + from ec_subsubcategories ss + where ss.subcategory_id = m.category_id) subsubcount + from ec_category_product_map m where product_id = :product_id - order by subcount, subsubcount, category_id) - where rownum = 1 -" { + order by subcount, subsubcount, category_id) + where rownum = 1" { } db_release_unused_handles -ns_adp_parse -string $template -set r [ns_adp_parse -string $template] -doc_return 200 text/html $r +set formatted_product [ns_adp_parse -string $template] Index: openacs-4/packages/ecommerce/www/product.xql =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/ecommerce/www/product.xql,v diff -u -r1.2 -r1.3 --- openacs-4/packages/ecommerce/www/product.xql 11 Jul 2001 04:52:05 -0000 1.2 +++ openacs-4/packages/ecommerce/www/product.xql 26 May 2002 04:36:50 -0000 1.3 @@ -1,85 +1,86 @@ + - - - insert into ec_user_session_info (user_session_id, product_id) values (:user_session_id, :product_id) - - + + + insert into ec_user_session_info + (user_session_id, product_id) + values + (:user_session_id, :product_id) + + - - - - select count(*) from ec_user_session_offer_codes where user_session_id=:user_session_id and product_id=:product_id - - + + + select count(*) + from ec_user_session_offer_codes + where user_session_id=:user_session_id + and product_id=:product_id + + - - - - insert into ec_user_session_offer_codes (user_session_id, product_id, offer_code) values (:user_session_id, :product_id, :offer_code) - - + + + insert into ec_user_session_offer_codes + (user_session_id, product_id, offer_code) + values + (:user_session_id, :product_id, :offer_code) + + - - - - update ec_user_session_offer_codes set offer_code=:offer_code where user_session_id=:user_session_id and product_id=:product_id - - + + + update ec_user_session_offer_codes + set offer_code=:offer_code + where user_session_id=:user_session_id + and product_id=:product_id + + - - - - select offer_code from ec_user_session_offer_codes where user_session_id=:user_session_id and product_id=:product_id - - + + + select offer_code + from ec_user_session_offer_codes + where user_session_id=:user_session_id + and product_id=:product_id + + - - - + + + select * + from ec_products p + left join ec_custom_product_field_values v on (p.product_id = v.product_id) + where p.product_id = :product_id + + -select * - from ec_products p - LEFT JOIN ec_custom_product_field_values v on (p.product_id = v.product_id) - where p.product_id = :product_id + + + select template + from ec_templates + where template_id=:template_id + + - - + + + select template + from ec_templates t, ec_category_template_map ct, ec_category_product_map cp + where t.template_id = ct.template_id + and ct.category_id = cp.category_id + and cp.product_id = :product_id + + - - - - - select template + + + select template from ec_templates - where template_id=:template_id - - - + where template_id=(select default_template + from ec_admin_settings) + + - - - - -SELECT template - FROM ec_templates t, ec_category_template_map ct, ec_category_product_map cp - WHERE t.template_id = ct.template_id - AND ct.category_id = cp.category_id - AND cp.product_id = :product_id - - - - - - - - select template - from ec_templates - where template_id=(select default_template - from ec_admin_settings) - - - - Index: openacs-4/packages/ecommerce/www/review-submit-2-oracle.xql =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/ecommerce/www/review-submit-2-oracle.xql,v diff -u -r1.1 -r1.2 --- openacs-4/packages/ecommerce/www/review-submit-2-oracle.xql 10 Jul 2001 20:42:02 -0000 1.1 +++ openacs-4/packages/ecommerce/www/review-submit-2-oracle.xql 26 May 2002 04:36:50 -0000 1.2 @@ -1,23 +1,19 @@ - oracle8.1.6 + + oracle + 8.1.6 + - - - - select product_name, - ec_product_comment_id_sequence.nextval as comment_id, - user_email, - to_char(sysdate,'Day Month DD, YYYY') as current_date - from ec_products, - (select email as user_email - from cc_users - where user_id = :user_id) - where product_id=:product_id + + + select product_name, ec_product_comment_id_sequence.nextval as comment_id, user_email, to_char(sysdate,'Day Month DD, YYYY') as current_date + from ec_products, (select email as user_email + from cc_users + where user_id = :user_id) + where product_id=:product_id + + - - - - Index: openacs-4/packages/ecommerce/www/review-submit-2-postgresql.xql =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/ecommerce/www/review-submit-2-postgresql.xql,v diff -u -r1.2 -r1.3 --- openacs-4/packages/ecommerce/www/review-submit-2-postgresql.xql 6 Jan 2002 07:22:48 -0000 1.2 +++ openacs-4/packages/ecommerce/www/review-submit-2-postgresql.xql 26 May 2002 04:36:50 -0000 1.3 @@ -1,23 +1,19 @@ - postgresql7.1 + + postgresql + 7.1 + - - - - select product_name, - ec_product_comment_id_sequence.nextval as comment_id, - user_email, - to_char(current_timestamp,'Day Month DD, YYYY') as current_date - from ec_products, - (select email as user_email - from cc_users - where user_id = :user_id) as cc_emails - where product_id=:product_id + + + select product_name, ec_product_comment_id_sequence.nextval as comment_id, user_email, to_char(current_timestamp,'Day Month DD, YYYY') as current_date + from ec_products, (select email as user_email + from cc_users + where user_id = :user_id) as cc_emails + where product_id=:product_id + + - - - - Index: openacs-4/packages/ecommerce/www/review-submit-2.tcl =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/ecommerce/www/review-submit-2.tcl,v diff -u -r1.1 -r1.2 --- openacs-4/packages/ecommerce/www/review-submit-2.tcl 20 Apr 2001 20:51:13 -0000 1.1 +++ openacs-4/packages/ecommerce/www/review-submit-2.tcl 26 May 2002 04:36:50 -0000 1.2 @@ -1,14 +1,17 @@ -# www/ecommerce/review-submit-2.tcl ad_page_contract { + @param product_id:integer @param rating @param one_line_summary @param user_comment @param usca_p:optional - @author - @creation-date - @cvs-id review-submit-2.tcl,v 3.3.2.8 2000/08/18 21:46:35 stevenp Exp - @author ported by Jerry Asher (jerry@theashergroup.com) + + @author + @creation-date + @author ported by Jerry Asher (jerry@theashergroup.com) + @author revised by Bart Teeuwisse + @revision-date April 2002 + } { product_id:integer rating:notnull @@ -19,11 +22,8 @@ # 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]?[export_entire_form_as_url_vars]" - ad_returnredirect "/register?[export_url_vars return_url]" return } @@ -42,10 +42,9 @@ } # user session tracking -set user_session_id [ec_get_user_session_id] +set user_session_id [ec_get_user_session_id] ec_create_new_session_if_necessary [export_entire_form_as_url_vars] -# type2 db_1row get_product_and_user_info " select product_name, @@ -56,19 +55,16 @@ (select email as user_email from cc_users where user_id = :user_id) - where product_id=:product_id -" + where product_id=:product_id" set hidden_form_variables [export_form_vars product_id rating one_line_summary user_comment comment_id] - -set review_as_it_will_appear "$user_email +set review_as_it_will_appear " +$user_email rated this product [ec_display_rating $rating] on $current_date and wrote:
    $one_line_summary
    -[ec_display_as_html $user_comment] -" +[ec_display_as_html $user_comment]" set system_name [ad_system_name] db_release_unused_handles -ec_return_template - +ad_return_template Index: openacs-4/packages/ecommerce/www/review-submit-3-oracle.xql =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/ecommerce/www/review-submit-3-oracle.xql,v diff -u -r1.1 -r1.2 --- openacs-4/packages/ecommerce/www/review-submit-3-oracle.xql 10 Jul 2001 20:42:02 -0000 1.1 +++ openacs-4/packages/ecommerce/www/review-submit-3-oracle.xql 26 May 2002 04:36:50 -0000 1.2 @@ -1,20 +1,20 @@ - oracle8.1.6 + + oracle + 8.1.6 + - - - - insert into ec_product_comments - (comment_id, product_id, user_id, user_comment, one_line_summary, - rating, comment_date, last_modified, last_modifying_user, modified_ip_address) - values - (:comment_id, :product_id, :user_id, :user_comment, :one_line_summary, - :rating, sysdate, sysdate, :user_id, :ns_conn_peeraddr) + + + insert into ec_product_comments + (comment_id, product_id, user_id, user_comment, one_line_summary, + rating, comment_date, last_modified, last_modifying_user, modified_ip_address) + values + (:comment_id, :product_id, :user_id, :user_comment, :one_line_summary, + :rating, sysdate, sysdate, :user_id, :ns_conn_peeraddr) + + - - - - Index: openacs-4/packages/ecommerce/www/review-submit-3-postgresql.xql =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/ecommerce/www/review-submit-3-postgresql.xql,v diff -u -r1.1 -r1.2 --- openacs-4/packages/ecommerce/www/review-submit-3-postgresql.xql 10 Jul 2001 20:42:02 -0000 1.1 +++ openacs-4/packages/ecommerce/www/review-submit-3-postgresql.xql 26 May 2002 04:36:50 -0000 1.2 @@ -1,20 +1,20 @@ - postgresql7.1 + + postgresql + 7.1 + - - - - insert into ec_product_comments - (comment_id, product_id, user_id, user_comment, one_line_summary, - rating, comment_date, last_modified, last_modifying_user, modified_ip_address) - values - (:comment_id, :product_id, :user_id, :user_comment, :one_line_summary, - :rating, current_timestamp, current_timestamp, :user_id, :ns_conn_peeraddr) + + + insert into ec_product_comments + (comment_id, product_id, user_id, user_comment, one_line_summary, + rating, comment_date, last_modified, last_modifying_user, modified_ip_address) + values + (:comment_id, :product_id, :user_id, :user_comment, :one_line_summary, + :rating, current_timestamp, current_timestamp, :user_id, :ns_conn_peeraddr) + + - - - - Index: openacs-4/packages/ecommerce/www/review-submit-3.tcl =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/ecommerce/www/review-submit-3.tcl,v diff -u -r1.2 -r1.3 --- openacs-4/packages/ecommerce/www/review-submit-3.tcl 31 Jan 2002 22:43:54 -0000 1.2 +++ openacs-4/packages/ecommerce/www/review-submit-3.tcl 26 May 2002 04:36:50 -0000 1.3 @@ -1,15 +1,17 @@ -# www/ecommerce/review-submit-3.tcl ad_page_contract { @param product_id @param rating @param one_line_summary @param user_comment @param comment_id @param usca_p:optional - @author - @creation-date - @cvs-id review-submit-3.tcl,v 3.2.2.6 2000/08/18 21:46:35 stevenp Exp - @author ported by Jerry Asher (jerry@theashergroup.com) + + @author + @creation-date + @author ported by Jerry Asher (jerry@theashergroup.com) + @author revised by Bart Teeuwisse + @revision-date April 2002 + } { product_id:integer rating @@ -19,62 +21,48 @@ usca_p:optional } - - # we need them to be logged in -set user_id [ad_verify_and_get_user_id] +set user_id [ad_verify_and_get_user_id] if {$user_id == 0} { - - # The following code was here before, but I am commenting it out because I can find no definition of prev_page_url, prev_args_list, et al, in the entire acs code tree. - # set return_url "[ad_conn url]?[export_url_vars product_id prev_page_url prev_args_list altered_prev_args_list rating one_line_summary user_comment comment_id]" - if [info exists usca_p] { set return_url "[ad_conn url]?[export_url_vars product_id rating one_line_summary user_comment comment_id usca_p]" } else { set return_url "[ad_conn url]?[export_url_vars product_id rating one_line_summary user_comment comment_id]" } - ad_returnredirect "/register?[export_url_vars return_url]" return } # user session tracking -set user_session_id [ec_get_user_session_id] +set user_session_id [ec_get_user_session_id] ec_create_new_session_if_necessary [export_entire_form_as_url_vars] -# type2 -# see if the review is already in there, meaning they pushed reload, +# See if the review is already in there, meaning they pushed reload, # in which case, just show the thank you message, otherwise insert the # review db_1row product_name_and_double_click_check " -select product_name, - comment_found_p -from ec_products, - (select count(*) as comment_found_p - from ec_product_comments - where comment_id = :comment_id) -where product_id = :product_id -" + select product_name, comment_found_p + from ec_products, ( + select count(*) as comment_found_p + from ec_product_comments + where comment_id = :comment_id) + where product_id = :product_id" if { !$comment_found_p } { - set ns_conn_peeraddr [ns_conn peeraddr] - db_dml insert_new_comment " - insert into ec_product_comments - (comment_id, product_id, user_id, user_comment, one_line_summary, - rating, comment_date, last_modified, last_modifying_user, modified_ip_address) - values - (:comment_id, :product_id, :user_id, :user_comment, :one_line_summary, - :rating, sysdate, sysdate, :user_id, :ns_conn_peeraddr) -" + insert into ec_product_comments + (comment_id, product_id, user_id, user_comment, one_line_summary, rating, comment_date, last_modified, last_modifying_user, modified_ip_address) + values + (:comment_id, :product_id, :user_id, :user_comment, :one_line_summary, :rating, sysdate, sysdate, :user_id, :ns_conn_peeraddr)" } set comments_need_approval [ad_parameter -package_id [ec_id] ProductCommentsNeedApprovalP] set system_owner_email [ec_system_owner] set product_link "product?[export_url_vars product_id]" + db_release_unused_handles -ec_return_template \ No newline at end of file +ad_return_template Index: openacs-4/packages/ecommerce/www/review-submit-3.xql =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/ecommerce/www/review-submit-3.xql,v diff -u -r1.2 -r1.3 --- openacs-4/packages/ecommerce/www/review-submit-3.xql 6 Jan 2002 07:22:48 -0000 1.2 +++ openacs-4/packages/ecommerce/www/review-submit-3.xql 26 May 2002 04:36:50 -0000 1.3 @@ -1,19 +1,17 @@ + - - - -select product_name, - comment_found_p -from ec_products, - (select count(*) as comment_found_p - from ec_product_comments - where comment_id = :comment_id) ec_comments_count -where product_id = :product_id + + + select product_name, + comment_found_p + from ec_products, + (select count(*) as comment_found_p + from ec_product_comments + where comment_id = :comment_id) ec_comments_count + where product_id = :product_id + + - - - - Index: openacs-4/packages/ecommerce/www/review-submit.tcl =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/ecommerce/www/review-submit.tcl,v diff -u -r1.1 -r1.2 --- openacs-4/packages/ecommerce/www/review-submit.tcl 20 Apr 2001 20:51:13 -0000 1.1 +++ openacs-4/packages/ecommerce/www/review-submit.tcl 26 May 2002 04:36:50 -0000 1.2 @@ -1,51 +1,46 @@ -# www/ecommerce/review-submit.tcl ad_page_contract { @param product_id @param usca_p + @author @creation-date @cvs-id review-submit.tcl,v 3.2.2.6 2000/08/18 21:46:35 stevenp Exp @author ported by Jerry Asher (jerry@theashergroup.com) + @author revised by Bart Teeuwisse + @revision-date April 2002 + } { product_id:integer usca_p:optional } # we need them to be logged in -set user_id [ad_verify_and_get_user_id] +set user_id [ad_verify_and_get_user_id] if {$user_id == 0} { - - # The following line has been commented because only product_id is available. - # set return_url "[ad_conn url]?[export_url_vars product_id prev_page_url prev_args_list]" - - # if [info exists usca_p] { - # set return_url "[ad_conn url]?[export_url_vars product_id usca_p]" - # } else { - # set return_url "[ad_conn url]?[export_url_vars product_id usca_p]" - # } - set return_url "[ad_conn url]?[export_url_vars product_id usca_p]" - ad_returnredirect "/register?[export_url_vars return_url]" return } # user session tracking -set user_session_id [ec_get_user_session_id] +set user_session_id [ec_get_user_session_id] ec_create_new_session_if_necessary [export_entire_form_as_url_vars] -# type2 - ec_log_user_as_user_id_for_this_session -set product_name [db_string get_product_name "select product_name from ec_products where product_id=:product_id"] +set product_name [db_string get_product_name " + select product_name + from ec_products + where product_id=:product_id"] -# not clear where this is used, but I'll leave it in because it's not really clear how this code is put together. -lappend altered_prev_args_list $product_name +# Not clear where this is used, but I'll leave it in because it's not +# really clear how this code is put together. +lappend altered_prev_args_list $product_name set rating_widget [ec_rating_widget] + db_release_unused_handles -ec_return_template +ad_return_template Index: openacs-4/packages/ecommerce/www/review-submit.xql =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/ecommerce/www/review-submit.xql,v diff -u -r1.1 -r1.2 --- openacs-4/packages/ecommerce/www/review-submit.xql 10 Jul 2001 20:42:02 -0000 1.1 +++ openacs-4/packages/ecommerce/www/review-submit.xql 26 May 2002 04:36:50 -0000 1.2 @@ -1,11 +1,13 @@ + - - - select product_name from ec_products where product_id=:product_id - - + + + select product_name + from ec_products + where product_id=:product_id + + - Index: openacs-4/packages/ecommerce/www/select-shipping.tcl =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/ecommerce/www/select-shipping.tcl,v diff -u -r1.1 -r1.2 --- openacs-4/packages/ecommerce/www/select-shipping.tcl 16 Feb 2002 23:32:06 -0000 1.1 +++ openacs-4/packages/ecommerce/www/select-shipping.tcl 26 May 2002 04:36:50 -0000 1.2 @@ -1,21 +1,25 @@ -# /www/ecommerce/checkout-2.tcl ad_page_contract { @param address_id a stored address @param tax_exempt_p a flag to indicate if the customer is tax exempt @param usca_p User session started or not @author @creation-date - @cvs-id checkout-2.tcl,v 3.7.2.13 2000/08/18 21:46:32 stevenp Exp @author ported by Jerry Asher (jerry@theashergroup.com) + @author revised by Bart Teeuwisse + @revision-date April 2002 + } { address_id:optional,naturalnum tax_exempt_p:optional usca_p:optional + quantity:array,optional } -# ec_redirect_to_https_if_possible_and_necessary +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]" @@ -29,100 +33,241 @@ # 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 +# 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' "] + +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 + + # No rows came back, so they probably got here by pushing "Back", + # so just redirect them to index.tcl + ad_returnredirect [ec_url]index.tcl return } 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; + # 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] return } # 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 } { +# 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 } { ad_returnredirect [ec_url]shopping-cart return } -# either address_id should be a form variable, or it should already -# be in the database for this order +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" -# make sure address_id, if it exists, belongs to them, otherwise +# 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 +# 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 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"] + 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] return } - # it checks out ok - db_dml update_ec_order_address "update ec_orders set shipping_address=:address_id where order_id=:order_id" + + # 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 ""] + 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] } { - ad_returnredirect [ec_securelink [ec_url]checkout] - return + + # No shipping address is needed if the order only consists of + # soft goods not requiring shipping. + + if {[info exists no_shipping_avail_p] && [string equal $no_shipping_avail_p "f"]} { + ad_returnredirect [ec_securelink [ec_url]checkout] + return + } } } -# 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 +# 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]process-order-quantity-shipping] -set shipping_avail_p [expr ![db_0or1row shipping_avail "select distinct 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 = 't' and i.order_id = :order_id"]] -set shipping_options "" -set checkout_step {Verify Order} -if { [ad_parameter -package_id [ec_id] ExpressShippingP ecommerce] } { - if { $shipping_avail_p } { - set checkout_step {Select Shipping} - append shipping_options "

    -

  • Shipping method: -

    - Standard Shipping
    - Express
    - Pickup -

    - " + +if {[info exists no_shipping_avail_p] && [string equal $no_shipping_avail_p "f"]} { + + # Check if a shipping gateway has been selected. + + set shipping_gateway [ad_parameter ShippingGateway ecommerce] + if {[acs_sc_binding_exists_p ShippingGateway $shipping_gateway]} { + + # Replace the default ecommerce shipping calculations with the + # charges from the shipping gateway. + + 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 " +

    Available shipping methods:

    + " + + # 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 " + + + + + + " + } + append shipping_options "
    + $service_description + + + [string map {USD $} $value_currency_code] + + $total_charges +
    " + + # 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_method "no shipping" - append shipping_options "

    -

  • No Shipping Available: -

    - [export_form_vars shipping_method] - One or more items in your order are not shippable. -

    - " + set shipping_options " +

    Available shipping methods:

    +

    Standard Shipping
    " + + if { [ad_parameter -package_id [ec_id] ExpressShippingP ecommerce] } { + append shipping_options " + Express
    " + } + if { [ad_parameter -package_id [ec_id] PickupP ecommerce] } { + append shipping_options " + Pickup

    " + } } +} else { + set shipping_options " +

    Your order does not need shipping.

    " } + +# Export the quantity array if one was passed on from checkout-2 + +if {[info exists quantity]} { + foreach name [array names quantity] { + append shipping_options "

    " + } +} + # Export the tax exempt flag if one was passed on from checkout-2 + if {[info exists tax_exempt_p]} { append shipping_options "[export_form_vars tax_exempt_p]" } db_release_unused_handles -ec_return_template Index: openacs-4/packages/ecommerce/www/select-shipping.xql =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/ecommerce/www/select-shipping.xql,v diff -u -r1.1 -r1.2 --- openacs-4/packages/ecommerce/www/select-shipping.xql 16 Feb 2002 23:32:06 -0000 1.1 +++ openacs-4/packages/ecommerce/www/select-shipping.xql 26 May 2002 04:36:50 -0000 1.2 @@ -1,36 +1,49 @@ + - select order_id, user_id as order_owner - 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 count(*) from ec_addresses where address_id=:address_id and user_id=:user_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 + 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 shipping_address + from ec_orders + where order_id = :order_id - + - select distinct 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 = 't' and i.order_id = :order_id + 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 - + Index: openacs-4/packages/ecommerce/www/shopping-cart-add-oracle.xql =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/ecommerce/www/shopping-cart-add-oracle.xql,v diff -u -r1.3 -r1.4 --- openacs-4/packages/ecommerce/www/shopping-cart-add-oracle.xql 16 Feb 2002 23:32:06 -0000 1.3 +++ openacs-4/packages/ecommerce/www/shopping-cart-add-oracle.xql 26 May 2002 04:36:50 -0000 1.4 @@ -1,17 +1,23 @@ - oracle8.1.6 + + 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') + 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 @@ -20,14 +26,22 @@ (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))) + (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/ecommerce/www/shopping-cart-add-postgresql.xql =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/ecommerce/www/shopping-cart-add-postgresql.xql,v diff -u -r1.3 -r1.4 --- openacs-4/packages/ecommerce/www/shopping-cart-add-postgresql.xql 16 Feb 2002 23:32:06 -0000 1.3 +++ openacs-4/packages/ecommerce/www/shopping-cart-add-postgresql.xql 26 May 2002 04:36:50 -0000 1.4 @@ -1,8 +1,11 @@ - postgresql7.1 - + + postgresql + 7.1 + + insert into ec_orders @@ -11,7 +14,7 @@ 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 @@ -20,14 +23,21 @@ (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 - 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))) + 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))) - + Index: openacs-4/packages/ecommerce/www/shopping-cart-add.tcl =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/ecommerce/www/shopping-cart-add.tcl,v diff -u -r1.3 -r1.4 --- openacs-4/packages/ecommerce/www/shopping-cart-add.tcl 16 Feb 2002 23:32:06 -0000 1.3 +++ openacs-4/packages/ecommerce/www/shopping-cart-add.tcl 26 May 2002 04:36:50 -0000 1.4 @@ -1,5 +1,5 @@ -# www/ecommerce/shopping-cart-add.tcl 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 @@ -17,10 +17,13 @@ @param color_choice @param style_choice @param usca_p:optional + @author @creation-date - @cvs-id shopping-cart-add.tcl,v 3.3.2.6 2000/08/17 18:01:28 seb Exp @author ported by Jerry Asher (jerry@theashergroup.com) + @author revised by Bart Teeuwisse + @revision-date April 2002 + } { product_id:integer size_choice @@ -41,56 +44,82 @@ 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'"] +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 "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." + ad_return_complaint 1 " +

    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.

    " return } -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 ""] +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). +# 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 { [empty_string_p $order_id] } { set order_id [db_nextval ec_order_id_sequence] - # create the order (iff 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')" + + # Create the order (if an in_basket order *still* doesn't exist) - # 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 ""] + 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 + + # 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)" + 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]" return } } -# 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. +# 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. +# That should be enough to protect from double clicks yet provides a +# more intuitive user experience. -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, 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"]))" +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, 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"]))" + db_release_unused_handles ad_returnredirect shopping-cart.tcl?[export_url_vars product_id] Index: openacs-4/packages/ecommerce/www/shopping-cart-add.xql =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/ecommerce/www/shopping-cart-add.xql,v diff -u -r1.1 -r1.2 --- openacs-4/packages/ecommerce/www/shopping-cart-add.xql 10 Jul 2001 20:42:02 -0000 1.1 +++ openacs-4/packages/ecommerce/www/shopping-cart-add.xql 26 May 2002 04:36:50 -0000 1.2 @@ -1,25 +1,32 @@ + - - - select count(*) from ec_orders where user_session_id=:user_session_id and order_state='confirmed' - - + + + 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' - - + + + 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_session_id=:user_session_id and order_state='in_basket' - - + + + select order_id + from ec_orders + where user_session_id=:user_session_id + and order_state='in_basket' + + - Index: openacs-4/packages/ecommerce/www/shopping-cart-delete-from.xql =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/ecommerce/www/shopping-cart-delete-from.xql,v diff -u -r1.1 -r1.2 --- openacs-4/packages/ecommerce/www/shopping-cart-delete-from.xql 10 Jul 2001 20:42:02 -0000 1.1 +++ openacs-4/packages/ecommerce/www/shopping-cart-delete-from.xql 26 May 2002 04:36:50 -0000 1.2 @@ -1,18 +1,25 @@ + - - - 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_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"] - - + + + 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/ecommerce/www/shopping-cart-oracle.xql =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/ecommerce/www/shopping-cart-oracle.xql,v diff -u -r1.1 -r1.2 --- openacs-4/packages/ecommerce/www/shopping-cart-oracle.xql 10 Jul 2001 20:42:02 -0000 1.1 +++ openacs-4/packages/ecommerce/www/shopping-cart-oracle.xql 26 May 2002 04:36:50 -0000 1.2 @@ -1,27 +1,34 @@ - oracle8.1.6 + + oracle + 8.1.6 + - - + + select 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 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.product_id, u.offer_code, i.color_choice, i.size_choice, i.style_choice - - + 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.product_id, u.offer_code, i.color_choice, i.size_choice, i.style_choice + + - - - - select 1 from dual where exists (select 1 from ec_orders where user_id=:user_id and order_state='in_basket' and saved_p='t') - - + + + select 1 + from dual + where exists (select 1 + from ec_orders + where user_id=:user_id + and order_state='in_basket' + and saved_p='t') + + - Index: openacs-4/packages/ecommerce/www/shopping-cart-postgresql.xql =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/ecommerce/www/shopping-cart-postgresql.xql,v diff -u -r1.1 -r1.2 --- openacs-4/packages/ecommerce/www/shopping-cart-postgresql.xql 10 Jul 2001 20:42:02 -0000 1.1 +++ openacs-4/packages/ecommerce/www/shopping-cart-postgresql.xql 26 May 2002 04:36:50 -0000 1.2 @@ -1,13 +1,19 @@ - postgresql7.1 + + postgresql + 7.1 + - - - select 1 where exists (select 1 from ec_orders where user_id=:user_id and order_state='in_basket' and saved_p='t') - - + + + select 1 where exists (select 1 + from ec_orders + where user_id=:user_id + and order_state = 'in_basket' + and saved_p='t') + + - Index: openacs-4/packages/ecommerce/www/shopping-cart-quantities-change-oracle.xql =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/ecommerce/www/shopping-cart-quantities-change-oracle.xql,v diff -u -r1.1 -r1.2 --- openacs-4/packages/ecommerce/www/shopping-cart-quantities-change-oracle.xql 10 Jul 2001 20:42:02 -0000 1.1 +++ openacs-4/packages/ecommerce/www/shopping-cart-quantities-change-oracle.xql 26 May 2002 04:36:50 -0000 1.2 @@ -1,17 +1,18 @@ - oracle8.1.6 + + 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) - - - + (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/ecommerce/www/shopping-cart-quantities-change-postgresql.xql =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/ecommerce/www/shopping-cart-quantities-change-postgresql.xql,v diff -u -r1.1 -r1.2 --- openacs-4/packages/ecommerce/www/shopping-cart-quantities-change-postgresql.xql 10 Jul 2001 20:42:02 -0000 1.1 +++ openacs-4/packages/ecommerce/www/shopping-cart-quantities-change-postgresql.xql 26 May 2002 04:36:50 -0000 1.2 @@ -1,17 +1,18 @@ - postgresql7.1 + + 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) - - - + (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) + + - Index: openacs-4/packages/ecommerce/www/shopping-cart-quantities-change.xql =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/ecommerce/www/shopping-cart-quantities-change.xql,v diff -u -r1.1 -r1.2 --- openacs-4/packages/ecommerce/www/shopping-cart-quantities-change.xql 10 Jul 2001 20:42:02 -0000 1.1 +++ openacs-4/packages/ecommerce/www/shopping-cart-quantities-change.xql 26 May 2002 04:36:50 -0000 1.2 @@ -1,55 +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 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 - - - + + + 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 ", "]) - - + + + delete from ec_items + where item_id in ([join $rows_to_delete ", "]) + + - Index: openacs-4/packages/ecommerce/www/shopping-cart-retrieve-2-oracle.xql =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/ecommerce/www/shopping-cart-retrieve-2-oracle.xql,v diff -u -r1.1 -r1.2 --- openacs-4/packages/ecommerce/www/shopping-cart-retrieve-2-oracle.xql 10 Jul 2001 20:42:02 -0000 1.1 +++ openacs-4/packages/ecommerce/www/shopping-cart-retrieve-2-oracle.xql 26 May 2002 04:36:50 -0000 1.2 @@ -1,20 +1,22 @@ - oracle8.1.6 + + oracle + 8.1.6 + - - + + select to_char(o.in_basket_date,'Month DD, YYYY') as formatted_in_basket_date, o.in_basket_date, o.order_id, count(*) as n_products -from ec_orders o, ec_items i -where user_id=:user_id -and order_state='in_basket' -and saved_p='t' -and i.order_id=o.order_id -group by o.order_id, to_char(o.in_basket_date,'Month DD, YYYY'), o.in_basket_date -order by o.in_basket_date - - + from ec_orders o, ec_items i + where user_id=:user_id + and order_state='in_basket' + and saved_p='t' + and i.order_id=o.order_id + group by o.order_id, to_char(o.in_basket_date,'Month DD, YYYY'), o.in_basket_date + order by o.in_basket_date + + - Index: openacs-4/packages/ecommerce/www/shopping-cart-retrieve-2-postgresql.xql =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/ecommerce/www/shopping-cart-retrieve-2-postgresql.xql,v diff -u -r1.1 -r1.2 --- openacs-4/packages/ecommerce/www/shopping-cart-retrieve-2-postgresql.xql 10 Jul 2001 20:42:02 -0000 1.1 +++ openacs-4/packages/ecommerce/www/shopping-cart-retrieve-2-postgresql.xql 26 May 2002 04:36:50 -0000 1.2 @@ -1,20 +1,22 @@ - postgresql7.1 + + postgresql + 7.1 + - - + + select to_char(o.in_basket_date,'Month DD, YYYY') as formatted_in_basket_date, o.in_basket_date, o.order_id, count(*) as n_products -from ec_orders o, ec_items i -where user_id=:user_id -and order_state='in_basket' -and saved_p='t' -and i.order_id=o.order_id -group by o.order_id, to_char(o.in_basket_date,'Month DD, YYYY'), o.in_basket_date -order by o.in_basket_date - - + from ec_orders o, ec_items i + where user_id=:user_id + and order_state='in_basket' + and saved_p='t' + and i.order_id=o.order_id + group by o.order_id, to_char(o.in_basket_date,'Month DD, YYYY'), o.in_basket_date + order by o.in_basket_date + + - Index: openacs-4/packages/ecommerce/www/shopping-cart-retrieve-2.tcl =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/ecommerce/www/shopping-cart-retrieve-2.tcl,v diff -u -r1.1 -r1.2 --- openacs-4/packages/ecommerce/www/shopping-cart-retrieve-2.tcl 20 Apr 2001 20:51:13 -0000 1.1 +++ openacs-4/packages/ecommerce/www/shopping-cart-retrieve-2.tcl 26 May 2002 04:36:50 -0000 1.2 @@ -1,22 +1,23 @@ -# www/ecommerce/shopping-cart-retrieve-2.tcl ad_page_contract { + @param usca_p User session begun or not @author @creation-date @cvs-id shopping-cart-retrieve-2.tcl,v 3.3.6.5 2000/08/18 21:46:36 stevenp Exp @author ported by Jerry Asher (jerry@theashergroup.com) + @author revised by Bart Teeuwisse + @revision-date April 2002 + } { usca_p:optional } -# we need them to be logged in -set user_id [ad_verify_and_get_user_id] +# 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]" return } @@ -29,32 +30,33 @@ set saved_carts "" # user session tracking -set user_session_id [ec_get_user_session_id] +set user_session_id [ec_get_user_session_id] ec_create_new_session_if_necessary "" shopping_cart_required -# typeA -db_foreach get_basket_info "select to_char(o.in_basket_date,'Month DD, YYYY') as formatted_in_basket_date, o.in_basket_date, o.order_id, count(*) as n_products -from ec_orders o, ec_items i -where user_id=:user_id -and order_state='in_basket' -and saved_p='t' -and i.order_id=o.order_id -group by o.order_id, to_char(o.in_basket_date,'Month DD, YYYY'), o.in_basket_date -order by o.in_basket_date" { +db_foreach get_basket_info " + select to_char(o.in_basket_date,'Month DD, YYYY') as formatted_in_basket_date, o.in_basket_date, o.order_id, count(*) as n_products + from ec_orders o, ec_items i + where user_id=:user_id + and order_state='in_basket' + and saved_p='t' + and i.order_id=o.order_id + group by o.order_id, to_char(o.in_basket_date,'Month DD, YYYY'), o.in_basket_date + order by o.in_basket_date" { - append saved_carts "
    - [export_form_vars order_id] -
  • $formatted_in_basket_date, $n_products item(s) - - - -
  • - " + append saved_carts " +
    + [export_form_vars order_id] +
      +
    • $formatted_in_basket_date, $n_products item(s) + + +
    • +
    +
    " } if_no_rows { append saved_carts "No shopping carts were found.\n" } db_release_unused_handles - -ec_return_template \ No newline at end of file +ad_return_template Index: openacs-4/packages/ecommerce/www/shopping-cart-retrieve-3-oracle.xql =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/ecommerce/www/shopping-cart-retrieve-3-oracle.xql,v diff -u -r1.1 -r1.2 --- openacs-4/packages/ecommerce/www/shopping-cart-retrieve-3-oracle.xql 10 Jul 2001 20:42:02 -0000 1.1 +++ openacs-4/packages/ecommerce/www/shopping-cart-retrieve-3-oracle.xql 26 May 2002 04:36:50 -0000 1.2 @@ -1,13 +1,17 @@ - oracle8.1.6 + + oracle + 8.1.6 + - - - select to_char(in_basket_date,'Month DD, YYYY') as formatted_in_basket_date from ec_orders where order_id=:order_id - - + + + select to_char(in_basket_date,'Month DD, YYYY') as formatted_in_basket_date + from ec_orders + where order_id=:order_id + + - Index: openacs-4/packages/ecommerce/www/shopping-cart-retrieve-3-postgresql.xql =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/ecommerce/www/shopping-cart-retrieve-3-postgresql.xql,v diff -u -r1.1 -r1.2 --- openacs-4/packages/ecommerce/www/shopping-cart-retrieve-3-postgresql.xql 10 Jul 2001 20:42:02 -0000 1.1 +++ openacs-4/packages/ecommerce/www/shopping-cart-retrieve-3-postgresql.xql 26 May 2002 04:36:50 -0000 1.2 @@ -1,13 +1,17 @@ - postgresql7.1 + + postgresql + 7.1 + - - - select to_char(in_basket_date,'Month DD, YYYY') as formatted_in_basket_date from ec_orders where order_id=:order_id - - + + + select to_char(in_basket_date,'Month DD, YYYY') as formatted_in_basket_date + from ec_orders + where order_id=:order_id + + - Index: openacs-4/packages/ecommerce/www/shopping-cart-retrieve-3.tcl =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/ecommerce/www/shopping-cart-retrieve-3.tcl,v diff -u -r1.1 -r1.2 --- openacs-4/packages/ecommerce/www/shopping-cart-retrieve-3.tcl 20 Apr 2001 20:51:13 -0000 1.1 +++ openacs-4/packages/ecommerce/www/shopping-cart-retrieve-3.tcl 26 May 2002 04:36:50 -0000 1.2 @@ -1,4 +1,3 @@ -# www/ecommerce/shopping-cart-retrieve-3.tcl ad_page_contract { @param order_id The ID of the order @param submit What action to take @@ -7,90 +6,112 @@ @author @creation-date - @cvs-id shopping-cart-retrieve-3.tcl,v 3.4.2.8 2000/09/22 01:37:31 kevin Exp @author ported by Jerry Asher (jerry@theashergroup.com) + @author revised by Bart Teeuwisse + @revision-date April 2002 + } { order_id:notnull,naturalnum submit:notnull discard_confirmed_p:optional usca_p:optional } -# This script performs five functions, depending on which submit button -# the user pushed. It either displays the contents of a cart, retrieves -# a cart (no current cart to get in the way), merges a saved cart with -# a current cart, replaces a current cart with a saved cart, or discards a -# saved cart. +# This script performs five functions, depending on which submit +# button the user pushed. It either displays the contents of a cart, +# retrieves a cart (no current cart to get in the way), merges a saved +# cart with a current cart, replaces a current cart with a saved cart, +# or discards a saved cart. -# we need them to be logged in -set user_id [ad_verify_and_get_user_id] +# 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]" return } +# Make sure order exists (they might have discarded it then pushed +# back) - -# make sure order exists (they might have discarded it then pushed back) -if { 0 == [db_string get_order_exists_p "select count(*) from ec_orders where order_id=:order_id"] } { +if { 0 == [db_string get_order_exists_p " + select count(*) + from ec_orders + where order_id=:order_id"] } { ad_returnredirect shopping-cart return } -# make sure this order is theirs +# Make sure this order is theirs -set order_theirs_p [db_string get_order_is_theirs "select count(*) from ec_orders where order_id=:order_id and user_id=:user_id"] +set order_theirs_p [db_string get_order_is_theirs " + select count(*) + from ec_orders + where order_id=:order_id + and user_id=:user_id"] if { !$order_theirs_p } { - doc_return 200 text/html "[ad_header "Invalid Order"]

    Invalid Order

    The order you have selected either does not exist or does not belong to you. Please contact [ec_system_owner] if this is incorrect.[ec_footer]" + doc_return 200 text/html " + [ad_header "Invalid Order"] + +

    Invalid Order

    + +

    The order you have selected either does not exist or does not belong to you. + Please contact [ec_system_owner] if this is incorrect.

    + [ec_footer]" return } -# make sure the order is still a "saved shopping basket", otherwise they may have -# have gotten here by pushing "Back" +# Make sure the order is still a "saved shopping basket", otherwise +# they may have have gotten here by pushing "Back" -if { 0 == [db_string confirm_have_basket "select count(*) from ec_orders where order_id=:order_id and order_state='in_basket' and saved_p='t'"] } { +if { 0 == [db_string confirm_have_basket " + select count(*) + from ec_orders + where order_id=:order_id + and order_state='in_basket' + and saved_p='t'"] } { ad_returnredirect "shopping-cart" return } -# end security checks +# End security checks set user_session_id [ec_get_user_session_id] - ec_create_new_session_if_necessary [export_url_vars order_id submit discard_confirmed_p] shopping_cart_required # Possible values of submit: # View, Retrieve, Merge, Replace, Discard if { $submit == "View" } { - set page_title "Your Saved Shopping Cart" set page_function "view" set shopping_cart_items "" set hidden_form_variables [export_form_vars order_id] + set saved_date [db_string get_saved_date " + select to_char(in_basket_date,'Month DD, YYYY') as formatted_in_basket_date + from ec_orders + where order_id=:order_id"] + set product_counter 0 - set saved_date [db_string get_saved_date "select to_char(in_basket_date,'Month DD, YYYY') as formatted_in_basket_date from ec_orders where order_id=:order_id"] - -set product_counter 0 - db_foreach get_saved_shopping_cart "select p.product_name, p.one_line_description, p.product_id, i.color_choice, i.size_choice, i.style_choice, count(*) as quantity - from ec_orders o, ec_items i, ec_products p - where i.product_id=p.product_id - and o.order_id=i.order_id - and o.order_id=:order_id - group by p.product_name, p.one_line_description, p.product_id, i.color_choice, i.size_choice, i.style_choice" { - - - + db_foreach get_saved_shopping_cart " + select p.product_name, p.one_line_description, p.product_id, i.color_choice, i.size_choice, i.style_choice, count(*) as quantity + from ec_orders o, ec_items i, ec_products p + where i.product_id=p.product_id + and o.order_id=i.order_id + and o.order_id=:order_id + group by p.product_name, p.one_line_description, p.product_id, i.color_choice, i.size_choice, i.style_choice" { if { $product_counter == 0 } { - append shopping_cart_items "Shopping Cart ItemsOptionsQty. \n" + append shopping_cart_items " + + Shopping Cart Items + Options + Qty. +   + " } - set option_list [list] if { ![empty_string_p $color_choice] } { lappend option_list "Color: $color_choice" @@ -103,225 +124,271 @@ } set options [join $option_list "
    "] - append shopping_cart_items " - $product_name
    - $one_line_description - $options - $quantity - - " + append shopping_cart_items " + + $product_name
    + $one_line_description + $options + $quantity + " incr product_counter } + db_release_unused_handles - ec_return_template + ad_return_template return - } elseif { $submit == "Retrieve" } { - # first see if they already have a non-empty shopping basket, in which - # case we'll have to find out whether they want us to merge the two - # baskets or replace the current basket with the saved one - - set n_current_baskets [db_string get_n_baskets "select count(*) from ec_orders where order_state='in_basket' and user_session_id=:user_session_id"] + # First see if they already have a non-empty shopping basket, in + # which case we'll have to find out whether they want us to merge + # the two baskets or replace the current basket with the saved one + + set n_current_baskets [db_string get_n_baskets " + select count(*) + from ec_orders + where order_state='in_basket' + and user_session_id=:user_session_id"] if { $n_current_baskets == 0 } { - # the easy case + + # The easy case + db_transaction { - db_dml update_ec_orders "update ec_orders set user_session_id=:user_session_id, saved_p='f' where order_id=:order_id" - # Well, the case *was* easy, but now we have to deal with special offer codes; - # we want to put any special offer codes the user had in a previous session into - # this session so that a retrieved cart doesn't end up having higher prices than - # it had before (it is possible that it will have lower prices). - # If they have more than one offer code for the same product, I'll put the lowest - # priced current offer into ec_user_session_offer_codes. -set offer_and_product_list [list] - db_foreach get_special_offers "select o.offer_code, o.product_id - from ec_user_sessions s, ec_user_session_offer_codes o, ec_sale_prices_current p - where p.offer_code=o.offer_code - and s.user_session_id=o.user_session_id - and s.user_id=:user_id - order by p.sale_price" { + db_dml update_ec_orders " + update ec_orders + set user_session_id=:user_session_id, saved_p='f' + where order_id=:order_id" - - - lappend offer_and_product_list [list $offer_code $product_id] - } + # Well, the case *was* easy, but now we have to deal with + # special offer codes; we want to put any special offer + # codes the user had in a previous session into this + # session so that a retrieved cart doesn't end up having + # higher prices than it had before (it is possible that it + # will have lower prices). If they have more than one + # offer code for the same product, I'll put the lowest + # priced current offer into ec_user_session_offer_codes. - # delete any current offer codes so no unique constraints will be violated - # (they'll be re-added anyway if they're the best offer the user has for the product) + set offer_and_product_list [list] + db_foreach get_special_offers " + select o.offer_code, o.product_id + from ec_user_sessions s, ec_user_session_offer_codes o, ec_sale_prices_current p + where p.offer_code=o.offer_code + and s.user_session_id=o.user_session_id + and s.user_id=:user_id + order by p.sale_price" { - db_dml delete_previous_offer_codes "delete from ec_user_session_offer_codes where user_session_id=:user_session_id" + lappend offer_and_product_list [list $offer_code $product_id] + } - set old_offer_and_product_list [list "" ""] - foreach offer_and_product $offer_and_product_list { - # insert it if the product hasn't been inserted before - if { [string compare [lindex $old_offer_and_product_list 1] [lindex $offer_and_product_list 1]] != 0 } { - set temp_pd [lindex $offer_and_product 1] + # Delete any current offer codes so no unique constraints + # will be violated (they'll be re-added anyway if they're + # the best offer the user has for the product) + + db_dml delete_previous_offer_codes " + delete from ec_user_session_offer_codes + where user_session_id=:user_session_id" + + set old_offer_and_product_list [list "" ""] + foreach offer_and_product $offer_and_product_list { - set offprod [lindex $offer_and_product 0] + # Insert it if the product hasn't been inserted before - db_dml insert_session_offer "insert into ec_user_session_offer_codes - (user_session_id, product_id, offer_code) - values - (:user_session_id, :temp_pd, :offprod) - " + if { [string compare [lindex $old_offer_and_product_list 1] [lindex $offer_and_product_list 1]] != 0 } { + set temp_pd [lindex $offer_and_product 1] + set offprod [lindex $offer_and_product 0] + db_dml insert_session_offer " + insert into ec_user_session_offer_codes + (user_session_id, product_id, offer_code) + values + (:user_session_id, :temp_pd, :offprod)" + } + set old_offer_and_product_list $offer_and_product_list } - set old_offer_and_product_list $offer_and_product_list } - } db_release_unused_handles ad_returnredirect "shopping-cart" return } else { - # the hard case - # either they can merge their saved order with their current basket, or - # they can replace their current basket with the saved order + # The hard case, either they can merge their saved order with + # their current basket, or they can replace their current + # basket with the saved order + set page_title "Merge or Replace Your Current Shopping Cart?" set page_function "retrieve" set hidden_form_variables [export_form_vars order_id] - ec_return_template + ad_return_template return } } elseif { $submit == "Merge" } { - # update all the items in the old order so that they belong to - # the current shopping basket + + # Update all the items in the old order so that they belong to the + # current shopping basket - # determine the current shopping basket - # (I use _or_null) in case they got here by pushing "Back" - set current_basket [db_string get_current_basket "select order_id from ec_orders where user_session_id=:user_session_id and order_state='in_basket'" -default ""] + # Determine the current shopping basket (I use _or_null) in case + # they got here by pushing "Back" + + set current_basket [db_string get_current_basket " + select order_id + from ec_orders + where user_session_id=:user_session_id + and order_state='in_basket'" -default ""] if { [empty_string_p $current_basket] } { ad_returnredirect shopping-cart return } db_transaction { - db_dml update_order_basket_pr "update ec_items set order_id=:current_basket where order_id=:order_id" - + db_dml update_order_basket_pr " + update ec_items + set order_id=:current_basket + where order_id=:order_id" set offer_and_product_list [list] + # The same offer code iterator as above - # the same offer code iterator as above - db_foreach get_product_offer_codes "select o.offer_code, o.product_id - from ec_user_sessions s, ec_user_session_offer_codes o, ec_sale_prices_current p - where p.offer_code=o.offer_code - and s.user_session_id=o.user_session_id - and s.user_id=:user_id - order by p.sale_price" { + db_foreach get_product_offer_codes " + select o.offer_code, o.product_id + from ec_user_sessions s, ec_user_session_offer_codes o, ec_sale_prices_current p + where p.offer_code=o.offer_code + and s.user_session_id=o.user_session_id + and s.user_id=:user_id + order by p.sale_price" { - lappend offer_and_product_list [list $offer_code $product_id] - } - - # delete any current offer codes so no unique constraints will be violated - # (they'll be re-added anyway if they're the best offer the user has for the product) - - db_dml delete_session_offer_codes "delete from ec_user_session_offer_codes where user_session_id=:user_session_id" - - set old_offer_and_product_list [list "" ""] - foreach offer_and_product $offer_and_product_list { - # insert it if the product hasn't been inserted before - if { [string compare [lindex $old_offer_and_product_list 1] [lindex $offer_and_product_list 1]] != 0 } { - - set temp_pd [lindex $offer_and_product 1] - - set offprod [lindex $offer_and_product 0] + lappend offer_and_product_list [list $offer_code $product_id] + } + + # Delete any current offer codes so no unique constraints will + # be violated (they'll be re-added anyway if they're the best + # offer the user has for the product) + + db_dml delete_session_offer_codes " + delete from ec_user_session_offer_codes + where user_session_id=:user_session_id" - db_dml insert_session_offer "insert into ec_user_session_offer_codes - (user_session_id, product_id, offer_code) - values - (:user_session_id, :temp_pd, :offprod) - " + set old_offer_and_product_list [list "" ""] + foreach offer_and_product $offer_and_product_list { + # Insert it if the product hasn't been inserted before + if { [string compare [lindex $old_offer_and_product_list 1] [lindex $offer_and_product_list 1]] != 0 } { + set temp_pd [lindex $offer_and_product 1] + set offprod [lindex $offer_and_product 0] + db_dml insert_session_offer " + insert into ec_user_session_offer_codes + (user_session_id, product_id, offer_code) + values + (:user_session_id, :temp_pd, :offprod)" + } + set old_offer_and_product_list $offer_and_product_list } - set old_offer_and_product_list $offer_and_product_list } - } - db_release_unused_handles + db_release_unused_handles ad_returnredirect shopping-cart return } elseif { $submit == "Replace" } { - # delete the items in the current basket and update the items in the saved order so - # that they're in the current basket - # determine the current shopping basket - # (I use _or_null) in case they got here by pushing "Back" - set current_basket [db_string get_current_baskey "select order_id from ec_orders where user_session_id=:user_session_id and order_state='in_basket'" -default ""] + # Delete the items in the current basket and update the items in + # the saved order so that they're in the current basket + + # Determine the current shopping basket (I use _or_null) in case + # they got here by pushing "Back" + + set current_basket [db_string get_current_baskey " + select order_id + from ec_orders + where user_session_id=:user_session_id + and order_state='in_basket'" -default ""] if { [empty_string_p $current_basket] } { ad_returnredirect shopping-cart return } db_transaction { - db_dml delete_current_items "delete from ec_items where order_id=:current_basket" - db_dml update_items "update ec_items set order_id=:current_basket where order_id=:order_id" -set offer_and_product_list [list] - # the same offer code thing as above - db_foreach get_offer_codes "select o.offer_code, o.product_id - from ec_user_sessions s, ec_user_session_offer_codes o, ec_sale_prices_current p - where p.offer_code=o.offer_code - and s.user_session_id=o.user_session_id - and s.user_id=:user_id - order by p.sale_price" { - - - lappend offer_and_product_list [list $offer_code $product_id] - } - - # delete any current offer codes so no unique constraints will be violated - # (they'll be re-added anyway if they're the best offer the user has for the product) - - db_dml delete_uc_offer_codes "delete from ec_user_session_offer_codes where user_session_id=:user_session_id" - - set old_offer_and_product_list [list "" ""] - foreach offer_and_product $offer_and_product_list { - # insert it if the product hasn't been inserted before - if { [string compare [lindex $old_offer_and_product_list 1] [lindex $offer_and_product_list 1]] != 0 } { - set temp_pd [lindex $offer_and_product 1] - - set offprod [lindex $offer_and_product 0] + db_dml delete_current_items " + delete from ec_items + where order_id=:current_basket" + db_dml update_items " + update ec_items + set order_id=:current_basket + where order_id=:order_id" + set offer_and_product_list [list] - db_dml insert_session_offer "insert into ec_user_session_offer_codes - (user_session_id, product_id, offer_code) - values - (:user_session_id, :temp_pd, :offprod) - " + # The same offer code thing as above + db_foreach get_offer_codes " + select o.offer_code, o.product_id + from ec_user_sessions s, ec_user_session_offer_codes o, ec_sale_prices_current p + where p.offer_code=o.offer_code + and s.user_session_id=o.user_session_id + and s.user_id=:user_id + order by p.sale_price" { + lappend offer_and_product_list [list $offer_code $product_id] + } + + # Delete any current offer codes so no unique constraints will + # be violated (they'll be re-added anyway if they're the best + # offer the user has for the product) + + db_dml delete_uc_offer_codes " + delete from ec_user_session_offer_codes + where user_session_id=:user_session_id" + + set old_offer_and_product_list [list "" ""] + foreach offer_and_product $offer_and_product_list { + + # Insert it if the product hasn't been inserted before + + if { [string compare [lindex $old_offer_and_product_list 1] [lindex $offer_and_product_list 1]] != 0 } { + set temp_pd [lindex $offer_and_product 1] + set offprod [lindex $offer_and_product 0] + db_dml insert_session_offer " + insert into ec_user_session_offer_codes + (user_session_id, product_id, offer_code) + values + (:user_session_id, :temp_pd, :offprod)" + } + set old_offer_and_product_list $offer_and_product_list } - set old_offer_and_product_list $offer_and_product_list } - } + db_release_unused_handles ad_returnredirect shopping-cart return } elseif { $submit == "Discard" } { if { [info exists discard_confirmed_p] && $discard_confirmed_p == "t" } { db_transaction { - db_dml delete_current_cart "delete from ec_items where order_id=:order_id" - db_dml delete_current_cart "delete from ec_orders where order_id=:order_id" + db_dml delete_current_cart " + delete from ec_items + where order_id=:order_id" + db_dml delete_current_cart " + delete from ec_orders + where order_id=:order_id" } + ad_returnredirect "shopping-cart" return } - # otherwise I have to give them a confirmation page + # Otherwise I have to give them a confirmation page + set page_title "Discard Your Saved Shopping Cart?" set page_function "discard" set hidden_form_variables "[export_form_vars order_id] [ec_hidden_input discard_confirmed_p "t"]" - ec_return_template + ad_return_template return } elseif { $submit == "Save it for Later" } { ad_returnredirect "shopping-cart-retrieve-2" return } -# there shouldn't be any other cases, but log it if there are +# There shouldn't be any other cases, but log it if there are + ns_log Notice "Error: [ec_url]shopping-cart-retrieve-3.tcl was called with an unexpected value of submit: $submit" db_release_unused_handles - ad_returnredirect "shopping-cart" Index: openacs-4/packages/ecommerce/www/shopping-cart-retrieve-3.xql =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/ecommerce/www/shopping-cart-retrieve-3.xql,v diff -u -r1.1 -r1.2 --- openacs-4/packages/ecommerce/www/shopping-cart-retrieve-3.xql 10 Jul 2001 20:42:02 -0000 1.1 +++ openacs-4/packages/ecommerce/www/shopping-cart-retrieve-3.xql 26 May 2002 04:36:50 -0000 1.2 @@ -1,190 +1,189 @@ + - - - select count(*) from ec_orders where order_id=:order_id - - + + + select count(*) + from ec_orders + where order_id=:order_id + + - - - - select count(*) from ec_orders where order_id=:order_id and user_id=:user_id - - + + + select count(*) + from ec_orders + where order_id=:order_id + and user_id=:user_id + + - - - - select count(*) from ec_orders where order_id=:order_id and order_state='in_basket' and saved_p='t' - - + + + select count(*) + from ec_orders + where order_id=:order_id + and order_state='in_basket' and saved_p='t' + + - - - + + select p.product_name, p.one_line_description, p.product_id, i.color_choice, i.size_choice, i.style_choice, count(*) as quantity - from ec_orders o, ec_items i, ec_products p - where i.product_id=p.product_id - and o.order_id=i.order_id - and o.order_id=:order_id - group by p.product_name, p.one_line_description, p.product_id, i.color_choice, i.size_choice, i.style_choice - - + from ec_orders o, ec_items i, ec_products p + where i.product_id=p.product_id + and o.order_id=i.order_id + and o.order_id=:order_id + group by p.product_name, p.one_line_description, p.product_id, i.color_choice, i.size_choice, i.style_choice + + - - - - select count(*) from ec_orders where order_state='in_basket' and user_session_id=:user_session_id - - + + + select count(*) + from ec_orders + where order_state='in_basket' + and user_session_id=:user_session_id + + - - - + + update ec_orders set user_session_id=:user_session_id, saved_p='f' where order_id=:order_id - - + + - - - + + select o.offer_code, o.product_id - from ec_user_sessions s, ec_user_session_offer_codes o, ec_sale_prices_current p - where p.offer_code=o.offer_code - and s.user_session_id=o.user_session_id - and s.user_id=:user_id - order by p.sale_price - - + from ec_user_sessions s, ec_user_session_offer_codes o, ec_sale_prices_current p + where p.offer_code=o.offer_code + and s.user_session_id=o.user_session_id + and s.user_id=:user_id + order by p.sale_price + + - - - - delete from ec_user_session_offer_codes where user_session_id=:user_session_id - - + + + delete from ec_user_session_offer_codes + where user_session_id=:user_session_id + + - - - + + insert into ec_user_session_offer_codes - (user_session_id, product_id, offer_code) - values - (:user_session_id, :temp_pd, :offprod) - - - + (user_session_id, product_id, offer_code) + values + (:user_session_id, :temp_pd, :offprod) + + - - - - 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_session_id=:user_session_id + and order_state='in_basket' + + - - - + + update ec_items set order_id=:current_basket where order_id=:order_id - - + + - - - + + select o.offer_code, o.product_id - from ec_user_sessions s, ec_user_session_offer_codes o, ec_sale_prices_current p - where p.offer_code=o.offer_code - and s.user_session_id=o.user_session_id - and s.user_id=:user_id - order by p.sale_price - - + from ec_user_sessions s, ec_user_session_offer_codes o, ec_sale_prices_current p + where p.offer_code=o.offer_code + and s.user_session_id=o.user_session_id + and s.user_id=:user_id + order by p.sale_price + + - - - - delete from ec_user_session_offer_codes where user_session_id=:user_session_id - - + + + delete from ec_user_session_offer_codes + where user_session_id=:user_session_id + + - - - + + insert into ec_user_session_offer_codes - (user_session_id, product_id, offer_code) - values - (:user_session_id, :temp_pd, :offprod) - - - + (user_session_id, product_id, offer_code) + values + (:user_session_id, :temp_pd, :offprod) + + - - - - 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_session_id=:user_session_id + and order_state='in_basket' + + - - - - delete from ec_items where order_id=:current_basket - - + + + delete from ec_items + where order_id=:current_basket + + - - - + + update ec_items set order_id=:current_basket where order_id=:order_id - - + + - - - + + select o.offer_code, o.product_id - from ec_user_sessions s, ec_user_session_offer_codes o, ec_sale_prices_current p - where p.offer_code=o.offer_code - and s.user_session_id=o.user_session_id - and s.user_id=:user_id - order by p.sale_price - - + from ec_user_sessions s, ec_user_session_offer_codes o, ec_sale_prices_current p + where p.offer_code=o.offer_code + and s.user_session_id=o.user_session_id + and s.user_id=:user_id + order by p.sale_price + + - - - - delete from ec_user_session_offer_codes where user_session_id=:user_session_id - - + + + delete from ec_user_session_offer_codes + where user_session_id=:user_session_id + + - - - + + insert into ec_user_session_offer_codes - (user_session_id, product_id, offer_code) - values - (:user_session_id, :temp_pd, :offprod) - - - + (user_session_id, product_id, offer_code) + values + (:user_session_id, :temp_pd, :offprod) + + - - - - delete from ec_items where order_id=:order_id - - + + + delete from ec_items + where order_id=:order_id + + - - - - delete from ec_items where order_id=:order_id - - + + + delete from ec_items + where order_id=:order_id + + - Index: openacs-4/packages/ecommerce/www/shopping-cart-retrieve.tcl =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/ecommerce/www/shopping-cart-retrieve.tcl,v diff -u -r1.1 -r1.2 --- openacs-4/packages/ecommerce/www/shopping-cart-retrieve.tcl 20 Apr 2001 20:51:13 -0000 1.1 +++ openacs-4/packages/ecommerce/www/shopping-cart-retrieve.tcl 26 May 2002 04:36:50 -0000 1.2 @@ -1,40 +1,38 @@ -# www/ecommerce/shopping-cart-retrieve.tcl ad_page_contract { This page either redirects them to log on or asks them to confirm that they are who we think they are. @param usca_p User session begun or not @author @creation-date - @cvs-id shopping-cart-retrieve.tcl,v 3.1.6.4 2000/07/31 18:00:12 ryanlee Exp @author ported by Jerry Asher (jerry@theashergroup.com) + @author revised by Bart Teeuwisse + @revision-date April 2002 + } { usca_p:optional } set user_id [ad_verify_and_get_user_id] - set return_url "[ec_url]shopping-cart-retrieve-2" - if {$user_id == 0} { ad_returnredirect "/register?[export_url_vars return_url]" return } -# user session tracking -set user_session_id [ec_get_user_session_id] +# User session tracking +set user_session_id [ec_get_user_session_id] ec_create_new_session_if_necessary "" shopping_cart_required -# typeA - ec_log_user_as_user_id_for_this_session +set user_name [db_string get_user_name " + select first_names || ' ' || last_name as user_name + from cc_users + where user_id=:user_id"] -set user_name [db_string get_user_name "select first_names || ' ' || last_name as user_name from cc_users where user_id=:user_id"] - set register_link "/register?[export_url_vars return_url]" db_release_unused_handles +ad_return_template -ec_return_template - Index: openacs-4/packages/ecommerce/www/shopping-cart-retrieve.xql =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/ecommerce/www/shopping-cart-retrieve.xql,v diff -u -r1.1 -r1.2 --- openacs-4/packages/ecommerce/www/shopping-cart-retrieve.xql 10 Jul 2001 20:42:02 -0000 1.1 +++ openacs-4/packages/ecommerce/www/shopping-cart-retrieve.xql 26 May 2002 04:36:50 -0000 1.2 @@ -1,11 +1,13 @@ + - - - select first_names || ' ' || last_name as user_name from cc_users where user_id=:user_id - - + + + select first_names || ' ' || last_name as user_name + from cc_users + where user_id=:user_id + + - Index: openacs-4/packages/ecommerce/www/shopping-cart-save-2.tcl =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/ecommerce/www/shopping-cart-save-2.tcl,v diff -u -r1.1 -r1.2 --- openacs-4/packages/ecommerce/www/shopping-cart-save-2.tcl 20 Apr 2001 20:51:13 -0000 1.1 +++ openacs-4/packages/ecommerce/www/shopping-cart-save-2.tcl 26 May 2002 04:36:50 -0000 1.2 @@ -1,55 +1,54 @@ -# www/ecommerce/shopping-cart-save-2.tcl ad_page_contract { @author @creation-date - @cvs-id shopping-cart-save-2.tcl,v 3.1.6.6 2000/09/22 01:37:31 kevin Exp @author ported by Jerry Asher (jerry@theashergroup.com) + @author revised by Bart Teeuwisse + @revision-date April 2002 + } { } 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]" return } set user_session_id [ec_get_user_session_id] - if { $user_session_id == 0 } { - doc_return 200 text/html "[ad_header "No Cart Found"]

    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.
    + doc_return 200 text/html " + [ad_header "No Cart Found"] - In Microsoft Internet Explorer 4.0, you can enable cookies from View -> - Internet Options -> Advanced -> Security.
    +

    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 and later, you can enable cookies from Edit -> Preferences -> Advanced.

    - [ec_continue_shopping_options] - " +

    In Microsoft Internet Explorer 4.0 and later, you can enable cookies from View -> + Internet Options -> Advanced -> Security.

    + [ec_continue_shopping_options]" return } -# set the user_id of the order so that we'll know who it belongs to +# Set the user_id of the order so that we'll know who it belongs to # and remove the user_session_id so that they can't mess with their # saved order (until they retrieve it, of course) -db_dml update_ec_orders "update ec_orders set user_id=:user_id, user_session_id=null, saved_p='t' -where user_session_id=:user_session_id and order_state='in_basket'" +db_dml update_ec_orders " + update ec_orders + set user_id=:user_id, user_session_id=null, saved_p='t' + where user_session_id=:user_session_id + and order_state='in_basket'" -# this should have only updated 1 row, or 0 if they reload, which is fine -db_release_unused_handles +# This should have only updated 1 row, or 0 if they reload, which is +# fine -ec_return_template +set cart_duration [ad_parameter CartDuration default [ad_parameter -package_id [ec_id] CartDuration]] - +db_release_unused_handles +ad_return_template Index: openacs-4/packages/ecommerce/www/shopping-cart-save-2.xql =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/ecommerce/www/shopping-cart-save-2.xql,v diff -u -r1.1 -r1.2 --- openacs-4/packages/ecommerce/www/shopping-cart-save-2.xql 10 Jul 2001 20:42:02 -0000 1.1 +++ openacs-4/packages/ecommerce/www/shopping-cart-save-2.xql 26 May 2002 04:36:50 -0000 1.2 @@ -1,12 +1,14 @@ + - - - update ec_orders set user_id=:user_id, user_session_id=null, saved_p='t' -where user_session_id=:user_session_id and order_state='in_basket' - - + + + update ec_orders + set user_id=:user_id, user_session_id=null, saved_p='t' + where user_session_id=:user_session_id + and order_state='in_basket' + + - Index: openacs-4/packages/ecommerce/www/shopping-cart-save.tcl =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/ecommerce/www/shopping-cart-save.tcl,v diff -u -r1.1 -r1.2 --- openacs-4/packages/ecommerce/www/shopping-cart-save.tcl 20 Apr 2001 20:51:13 -0000 1.1 +++ openacs-4/packages/ecommerce/www/shopping-cart-save.tcl 26 May 2002 04:36:50 -0000 1.2 @@ -1,25 +1,29 @@ -# www/ecommerce/shopping-cart-save.tcl ad_page_contract { - This page either redirects them to log on or asks them to confirm that they are who we think they are. + This page either redirects them to log on or asks them to + confirm that they are who we think they are. + @author @creation-date - @cvs-id shopping-cart-save.tcl,v 3.1.6.4 2000/07/31 17:56:40 ryanlee Exp @author ported by Jerry Asher (jerry@theashergroup.com) + @author revised by Bart Teeuwisse + @revision-date April 2002 + } { } set user_id [ad_verify_and_get_user_id] - set return_url "[ec_url]shopping-cart-save-2" - if {$user_id == 0} { ad_returnredirect "/register?[export_url_vars return_url]" return } -set user_name [db_string get_full_name "select first_names || ' ' || last_name as user_name from cc_users where user_id=:user_id"] +set user_name [db_string get_full_name " + select first_names || ' ' || last_name as user_name + from cc_users + where user_id=:user_id"] set register_link "/register?[export_url_vars return_url]" -db_release_unused_handles -ec_return_template \ No newline at end of file +db_release_unused_handles +ad_return_template Index: openacs-4/packages/ecommerce/www/shopping-cart-save.xql =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/ecommerce/www/shopping-cart-save.xql,v diff -u -r1.1 -r1.2 --- openacs-4/packages/ecommerce/www/shopping-cart-save.xql 10 Jul 2001 20:42:02 -0000 1.1 +++ openacs-4/packages/ecommerce/www/shopping-cart-save.xql 26 May 2002 04:36:50 -0000 1.2 @@ -1,11 +1,13 @@ + - - - select first_names || ' ' || last_name as user_name from cc_users where user_id=:user_id - - + + + select first_names || ' ' || last_name as user_name + from cc_users + where user_id=:user_id + + - Index: openacs-4/packages/ecommerce/www/shopping-cart.tcl =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/ecommerce/www/shopping-cart.tcl,v diff -u -r1.2 -r1.3 --- openacs-4/packages/ecommerce/www/shopping-cart.tcl 16 Feb 2002 23:32:07 -0000 1.2 +++ openacs-4/packages/ecommerce/www/shopping-cart.tcl 26 May 2002 04:36:50 -0000 1.3 @@ -1,11 +1,12 @@ -# www/ecommerce/shopping-cart.tcl ad_page_contract { @param usca_p User session begun or not @author @creation-date - @cvs-id shopping-cart.tcl,v 3.4.2.10 2000/08/18 18:42:42 hbrock Exp @author ported by Jerry Asher (jerry@theashergroup.com) + @author revised by Bart Teeuwisse + @revision-date April 2002 + } { usca_p:optional product_id:optional @@ -15,18 +16,20 @@ # 1) continue shopping (always) # Case 1) Continue shopping -# Create the link now before the product_id gets overwritten when looping through the products -# in the cart. +# Create the link now before the product_id gets overwritten when +# looping through the products in the cart. + if {[info exists product_id]} { - set bottom_links "
  • Continue Shopping\n" + set bottom_links "
  • Continue Shopping
  • " } else { - set bottom_links "
  • Continue Shopping\n" + set bottom_links "
  • Continue Shopping
  • " } - set cart_contents "" -# we don't need them to be logged in, but if they are they might get a lower price +# We don't need them to be logged in, but if they are they might get a +# lower price + set user_id [ad_verify_and_get_user_id] # user sessions: @@ -37,42 +40,43 @@ # without cookies set user_session_id [ec_get_user_session_id] - ec_create_new_session_if_necessary +set n_items_in_cart [db_string get_n_items " + select count(*) + 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'"] -set n_items_in_cart [db_string get_n_items "select count(*) 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'"] - set product_counter 0 set total_price 0 -db_foreach get_products_in_cart "select 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 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.product_id, u.offer_code, i.color_choice, i.size_choice, i.style_choice" { +db_foreach get_products_in_cart " + select 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 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.product_id, u.offer_code, i.color_choice, i.size_choice, i.style_choice" { # No products listed yet, print header. + if { $product_counter == 0 } { append cart_contents " -
    -
    - - - - - - - - - " + +
    +
    Shopping Cart ItemsOptionsQuantityPrice/ItemAction
    + + + + + + + " } # Prepare color, size and style option list + set option_list [list] if { ![empty_string_p $color_choice] } { lappend option_list "Color: $color_choice" @@ -86,70 +90,79 @@ set options [join $option_list "
    "] # Print the product with name, selected options and quantity + append cart_contents " - - - - - " + + + + " - # Deletions are done by product_id, color_choice, size_choice, style_choice, - # not by item_id because we want to delete the entire quantity of that product. - # Also print the price for a product of the selected options and the aforementioned delete option. + # Deletions are done by product_id, color_choice, size_choice, + # style_choice, not by item_id because we want to delete the + # entire quantity of that product. Also print the price for a + # product of the selected options and the aforementioned delete + # option. + append cart_contents " - - - - " + + + " - # Too bad I have to do another call to get the price. That is because ec_price_line returns canned html instead - # of the price. + # Too bad I have to do another call to get the price. That is + # because ec_price_line returns canned html instead of the price. + set lowest_price_and_price_name [ec_lowest_price_and_price_name_for_an_item $product_id $user_id $offer_code] set lowest_price [lindex $lowest_price_and_price_name 0] # Add the price of the item to the total price + set total_price [expr $total_price + ($quantity * $lowest_price)] incr product_counter $quantity } # Add adjust quantities line if there are products in the cart. + if { $product_counter != 0 } { append cart_contents " - - " - # List the states that get charged tax. Although not 100% accurate as shipping might be taxed too - # this better than nothing. - db_foreach tax_states "select tax_rate, initcap(state_name) as state from ec_sales_tax_by_state tax, us_states state where state.abbrev = tax.usps_abbrev" { + " + + # List the states that get charged tax. Although not 100% accurate + # as shipping might be taxed too this better than nothing. + + db_foreach tax_states " + select tax_rate, initcap(state_name) as state + from ec_sales_tax_by_state tax, us_states state + where state.abbrev = tax.usps_abbrev" { append cart_contents " - - " + " } } # Close product listing and add proceed to checkout button. + if { $product_counter != 0 } { append cart_contents " -
    Shopping Cart ItemsOptionsQuantityPrice/ItemAction
    $product_name$options
    $product_name$options[ec_price_line $product_id $user_id $offer_code]delete
    [ec_price_line $product_id $user_id $offer_code]delete
    Total: $product_counter [ec_pretty_price $total_price [ad_parameter -package_id [ec_id] Currency]]
    Residents of $state, please add [format %0.2f [expr $tax_rate * 100]]% tax.
    -
    -
    -
    -
    -
    -
    -
    - " + + + +
    +
    +
    +
    +
    " } else { + # There are no products in the cart. + append cart_contents " -
    Your Shopping Cart is empty.
    - " +
    Your Shopping Cart is empty.
    " } # bottom links: @@ -159,22 +172,34 @@ # 4) save their cart (if their cart is not empty) if { $user_id == 0 } { + # Case 2) the user is not logged in. + append bottom_links " - " +
  • Log In
  • " } else { - if { ![empty_string_p [db_string check_for_saved_carts "select 1 from dual where exists (select 1 from ec_orders where user_id=:user_id and order_state='in_basket' and saved_p='t')" -default ""]] } { + if { ![empty_string_p [db_string check_for_saved_carts " + select 1 + from dual + where exists ( + select 1 + from ec_orders + where user_id=:user_id + and order_state='in_basket' + and saved_p='t')" -default ""]] } { + # Case 3) Retrieve saved carts - append bottom_links "
  • Retrieve a Saved Cart\n" + + append bottom_links "
  • Retrieve a Saved Cart
  • " } } if { $product_counter != 0 } { + # Case 4) Save non empty cart - append bottom_links "
  • Save Your Cart for Later\n" + + append bottom_links "
  • Save Your Cart for Later
  • " } db_release_unused_handles -ec_return_template \ No newline at end of file +ad_return_template Index: openacs-4/packages/ecommerce/www/shopping-cart.xql =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/ecommerce/www/shopping-cart.xql,v diff -u -r1.3 -r1.4 --- openacs-4/packages/ecommerce/www/shopping-cart.xql 16 Feb 2002 23:32:07 -0000 1.3 +++ openacs-4/packages/ecommerce/www/shopping-cart.xql 26 May 2002 04:36:50 -0000 1.4 @@ -1,4 +1,5 @@ + @@ -9,20 +10,22 @@ and o.user_session_id=:user_session_id and o.order_state='in_basket'
    - + select 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 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' + 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.product_id, u.offer_code, i.color_choice, i.size_choice, i.style_choice - + select tax_rate, initcap(state_name) as state Index: openacs-4/packages/ecommerce/www/thank-you.tcl =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/ecommerce/www/thank-you.tcl,v diff -u -r1.1 -r1.2 --- openacs-4/packages/ecommerce/www/thank-you.tcl 20 Apr 2001 20:51:13 -0000 1.1 +++ openacs-4/packages/ecommerce/www/thank-you.tcl 26 May 2002 04:36:50 -0000 1.2 @@ -1,24 +1,24 @@ -# www/ecommerce/thank-you.tcl ad_page_contract { @param usca_p User session begun or not @author @creation-date - @cvs-id thank-you.tcl,v 3.1.6.6 2000/08/18 21:46:36 stevenp Exp @author ported by Jerry Asher (jerry@theashergroup.com) + @author revised by Bart Teeuwisse + @revision-date April 2002 + } { usca_p:optional } -# This is a "thank you for your order" page -# displays order summary for the most recently confirmed order for this user -# we need them to be logged in -set user_id [ad_verify_and_get_user_id] +# This is a "thank you for your order" page displays order summary for +# the most recently confirmed order for this user +# 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 "[ad_conn package_url]register?[export_url_vars return_url]" template::adp_abort } @@ -27,25 +27,32 @@ # it isn't clear to me why we would log the session here # or why you would create a new session at this point -# user session tracking -set user_session_id [ec_get_user_session_id] +# User session tracking - +set user_session_id [ec_get_user_session_id] ec_create_new_session_if_necessary -# type1 - ec_log_user_as_user_id_for_this_session -# their most recently confirmed order (or the empty string if there is none) -set order_id [db_string get_order_id_info "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 ""] +# Their most recently confirmed order (or the empty string if there is +# none) +set order_id [db_string get_order_id_info " + 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 $order_id] } { ad_returnredirect index - # ad_script_abort } set order_summary [ec_order_summary_for_customer $order_id $user_id] + db_release_unused_handles +ad_return_template -ec_return_template - Index: openacs-4/packages/ecommerce/www/thank-you.xql =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/ecommerce/www/thank-you.xql,v diff -u -r1.1 -r1.2 --- openacs-4/packages/ecommerce/www/thank-you.xql 10 Jul 2001 20:42:02 -0000 1.1 +++ openacs-4/packages/ecommerce/www/thank-you.xql 26 May 2002 04:36:50 -0000 1.2 @@ -1,11 +1,17 @@ + - - - 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 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) + + - Index: openacs-4/packages/ecommerce/www/track-oracle.xql =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/ecommerce/www/track-oracle.xql,v diff -u -r1.1 -r1.2 --- openacs-4/packages/ecommerce/www/track-oracle.xql 10 Jul 2001 20:42:02 -0000 1.1 +++ openacs-4/packages/ecommerce/www/track-oracle.xql 26 May 2002 04:36:50 -0000 1.2 @@ -1,15 +1,17 @@ - oracle8.1.6 + + oracle + 8.1.6 + - - + + select to_char(shipment_date, 'MMDDYY') as ship_date_for_fedex, to_char(shipment_date, 'MM/DD/YYYY') as pretty_ship_date, carrier, tracking_number -from ec_shipments -where shipment_id = :shipment_id - - + from ec_shipments + where shipment_id = :shipment_id + + - Index: openacs-4/packages/ecommerce/www/track-postgresql.xql =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/ecommerce/www/track-postgresql.xql,v diff -u -r1.1 -r1.2 --- openacs-4/packages/ecommerce/www/track-postgresql.xql 10 Jul 2001 20:42:02 -0000 1.1 +++ openacs-4/packages/ecommerce/www/track-postgresql.xql 26 May 2002 04:36:50 -0000 1.2 @@ -1,15 +1,17 @@ - postgresql7.1 + + postgresql + 7.1 + - - + + select to_char(shipment_date, 'MMDDYY') as ship_date_for_fedex, to_char(shipment_date, 'MM/DD/YYYY') as pretty_ship_date, carrier, tracking_number -from ec_shipments -where shipment_id = :shipment_id - - + from ec_shipments + where shipment_id = :shipment_id + + - Index: openacs-4/packages/ecommerce/www/track.tcl =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/ecommerce/www/track.tcl,v diff -u -r1.4 -r1.5 --- openacs-4/packages/ecommerce/www/track.tcl 16 Feb 2002 23:32:07 -0000 1.4 +++ openacs-4/packages/ecommerce/www/track.tcl 26 May 2002 04:36:50 -0000 1.5 @@ -1,52 +1,55 @@ -# www/ecommerce/track.tcl ad_page_contract { @param shipment_id The ID of the shipment to track @param ucsa_p User session begun or not @author @creation-date - @cvs-id track.tcl,v 3.2.2.6 2000/08/18 21:46:37 stevenp Exp @author ported by Jerry Asher (jerry@theashergroup.com) + @author revised by Bart Teeuwisse + @revision-date April 2002 + } { shipment_id:notnull,naturalnum ucsa_p:optional } 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]" return } # user session tracking -set user_session_id [ec_get_user_session_id] +set user_session_id [ec_get_user_session_id] ec_create_new_session_if_necessary [export_url_vars shipment_id] - ec_log_user_as_user_id_for_this_session # Make sure this order belongs to the user. -if { [db_string assure_order_is_this_user "select user_id from ec_orders o, ec_shipments s -where o.order_id = s.order_id -and s.shipment_id = :shipment_id"] != $user_id } { + +if { [db_string assure_order_is_this_user " + select user_id from ec_orders o, ec_shipments s + where o.order_id = s.order_id + and s.shipment_id = :shipment_id"] != $user_id } { ad_return_error "Invalid Order ID" "Invalid Order ID" return } -db_1row get_order_info "select to_char(shipment_date, 'MMDDYY') as ship_date_for_fedex, to_char(shipment_date, 'MM/DD/YYYY') as pretty_ship_date, carrier, tracking_number -from ec_shipments -where shipment_id = :shipment_id" - +db_1row get_order_info " + select to_char(shipment_date, 'MMDDYY') as ship_date_for_fedex, to_char(shipment_date, 'MM/DD/YYYY') as pretty_ship_date, carrier, tracking_number + from ec_shipments + where shipment_id = :shipment_id" set carrier_info "" - if { $carrier == "FedEx" } { set fedex_url "http://www.fedex.com/cgi-bin/tracking?tracknumbers=$tracking_number&action=track&language=english&cntry_code=us" with_catch errmsg { set page_from_fedex [ns_httpget $fedex_url] - regexp {().*?(
    .*?
    )} $page_from_fedex match detailed_info scan_activity + regexp {().*?(
    .*?
    )} $page_from_fedex \ + match detailed_info scan_activity + # Remove links + regsub -all -nocase {} $scan_activity "" scan_activity set carrier_info "$detailed_info $scan_activity" } { @@ -59,15 +62,16 @@ if { ![regexp {(]*>Tracking Number:.*).*Tracking results provided by UPS} $ups_page match ups_info] } { set carrier_info "Unable to parse detail data from UPS." } else { + # Remove spacer images + regsub -all -nocase {} $ups_info "" ups_info set carrier_info "$ups_info" } } { set carrier_info "Unable to retrieve data from UPS." } - } -db_release_unused_handles -ec_return_template +db_release_unused_handles +ad_return_template Index: openacs-4/packages/ecommerce/www/track.xql =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/ecommerce/www/track.xql,v diff -u -r1.1 -r1.2 --- openacs-4/packages/ecommerce/www/track.xql 10 Jul 2001 20:42:02 -0000 1.1 +++ openacs-4/packages/ecommerce/www/track.xql 26 May 2002 04:36:50 -0000 1.2 @@ -1,13 +1,13 @@ + - - + + select user_id from ec_orders o, ec_shipments s -where o.order_id = s.order_id -and s.shipment_id = :shipment_id - - + where o.order_id = s.order_id + and s.shipment_id = :shipment_id + + - Index: openacs-4/packages/ecommerce/www/update-user-classes-2.tcl =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/ecommerce/www/update-user-classes-2.tcl,v diff -u -r1.1 -r1.2 --- openacs-4/packages/ecommerce/www/update-user-classes-2.tcl 20 Apr 2001 20:51:13 -0000 1.1 +++ openacs-4/packages/ecommerce/www/update-user-classes-2.tcl 26 May 2002 04:36:50 -0000 1.2 @@ -1,61 +1,55 @@ -# www/ecommerce/update-user-classes-2.tcl ad_page_contract { @param user_class_id ID of the user class @param usca_p User session begun or not + @author @creation-date - @cvs-id update-user-classes-2.tcl,v 3.2.2.7 2000/08/18 21:46:37 stevenp Exp @author ported by Jerry Asher (jerry@theashergroup.com) + @author revised by Bart Teeuwisse + @revision-date April 2002 + } { user_class_id:multiple usca_p:optional } set user_class_id_list $user_class_id - set user_id [ad_verify_and_get_user_id] - set ip_address [ns_conn peeraddr] - if {$user_id == 0} { - set return_url "[ad_conn url]" - ad_returnredirect "/register?[export_url_vars return_url]" return } set user_session_id [ec_get_user_session_id] - ec_create_new_session_if_necessary -# type1 - ec_log_user_as_user_id_for_this_session # update User Class db_transaction { # Get old user_class_ids - set old_user_class_id_list [db_list get_old_class_ids "select user_class_id - from ec_user_class_user_map - where user_id = :user_id"] + set old_user_class_id_list [db_list get_old_class_ids " + select user_class_id + from ec_user_class_user_map + where user_id = :user_id"] + # Add the user_class if it is not already there + foreach user_class_id $user_class_id_list { if { [lsearch -exact $old_user_class_id_list $user_class_id] == -1 && ![empty_string_p $user_class_id] } { - set sql "insert into - ec_user_class_user_map ( - user_id, user_class_id, user_class_approved_p, last_modified, last_modifying_user, modified_ip_address - ) values ( - :user_id, :user_class_id, NULL, sysdate, :user_id, :ip_address)" - - if [catch { db_dml insert_into_user_class_map $sql } errmsg] { + if [catch { db_dml insert_user_class " + insert into ec_user_class_user_map + (user_id, user_class_id, user_class_approved_p, last_modified, last_modifying_user, modified_ip_address) + values + (:user_id, :user_class_id, null, sysdate, :user_id, :ip_address)" } errmsg] { ad_return_error "Ouch!" "The database choked on our update:
    - $errmsg -
    - " + $errmsg + " } } } @@ -66,7 +60,7 @@ set sql "delete from ec_user_class_user_map where user_id = :user_id and user_class_id = :old_user_class_id" - + if [catch { db_dml delete_from_user_class_map $sql } errmsg] { ad_return_error "Ouch!" "The database choked on our update:
    Index: openacs-4/packages/ecommerce/www/update-user-classes-2.xql =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/ecommerce/www/update-user-classes-2.xql,v diff -u -r1.1 -r1.2 --- openacs-4/packages/ecommerce/www/update-user-classes-2.xql 10 Jul 2001 20:42:02 -0000 1.1 +++ openacs-4/packages/ecommerce/www/update-user-classes-2.xql 26 May 2002 04:36:50 -0000 1.2 @@ -1,13 +1,13 @@ + - - + + select user_class_id - from ec_user_class_user_map - where user_id = :user_id - - + from ec_user_class_user_map + where user_id = :user_id + + - Index: openacs-4/packages/ecommerce/www/update-user-classes.tcl =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/ecommerce/www/update-user-classes.tcl,v diff -u -r1.2 -r1.3 --- openacs-4/packages/ecommerce/www/update-user-classes.tcl 31 Jan 2002 22:43:54 -0000 1.2 +++ openacs-4/packages/ecommerce/www/update-user-classes.tcl 26 May 2002 04:36:50 -0000 1.3 @@ -1,39 +1,34 @@ -# www/ecommerce/update-user-classes.tcl ad_page_contract { @param usca_p User session begun or not + @author @creation-date - @cvs-id update-user-classes.tcl,v 3.1.6.7 2000/08/18 21:46:37 stevenp Exp @author ported by Jerry Asher (jerry@theashergroup.com) + @author revised by Bart Teeuwisse + @revision-date April 2002 + } { usca_p:optional } - 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]" return } set user_session_id [ec_get_user_session_id] - - ec_create_new_session_if_necessary -# type1 - ec_log_user_as_user_id_for_this_session -# two variables for the ADP page -set user_classes_need_approval [ad_parameter -package_id [ec_id] UserClassApproveP ecommerce] +# Two variables for the ADP page -set user_class_select_list [ec_user_class_select_widget [db_list get_user_class_list_for_uid "select user_class_id -from ec_user_class_user_map -where user_id = :user_id"]] +set user_classes_need_approval [ad_parameter -package_id [ec_id] UserClassApproveP ecommerce] +set user_class_select_list [ec_user_class_select_widget [db_list get_user_class_list_for_uid " + select user_class_id + from ec_user_class_user_map + where user_id = :user_id"]] db_release_unused_handles -ec_return_template +ad_return_template Index: openacs-4/packages/ecommerce/www/update-user-classes.xql =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/ecommerce/www/update-user-classes.xql,v diff -u -r1.1 -r1.2 --- openacs-4/packages/ecommerce/www/update-user-classes.xql 10 Jul 2001 20:42:02 -0000 1.1 +++ openacs-4/packages/ecommerce/www/update-user-classes.xql 26 May 2002 04:36:50 -0000 1.2 @@ -1,13 +1,13 @@ + - - + + select user_class_id -from ec_user_class_user_map -where user_id = :user_id - - + from ec_user_class_user_map + where user_id = :user_id + + - Index: openacs-4/packages/ecommerce/www/admin/audit-table-oracle.xql =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/ecommerce/www/admin/audit-table-oracle.xql,v diff -u -r1.1 -r1.2 --- openacs-4/packages/ecommerce/www/admin/audit-table-oracle.xql 10 Jul 2001 20:33:53 -0000 1.1 +++ openacs-4/packages/ecommerce/www/admin/audit-table-oracle.xql 26 May 2002 04:36:50 -0000 1.2 @@ -1,17 +1,17 @@ - oracle8.1.6 + + oracle + 8.1.6 + - - - - select 1 + + + select 1 from dual - where to_date('$start_date(date)','YYYY-MM-DD HH24:MI:SS') > to_date('$end_date(date)', 'YYYY-MM-DD HH24:MI:SS') - - - + where to_date('$start_date(date)','YYYY-MM-DD HH24:MI:SS') > to_date('$end_date(date)', 'YYYY-MM-DD HH24:MI:SS') + + - Index: openacs-4/packages/ecommerce/www/admin/audit-table-postgresql.xql =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/ecommerce/www/admin/audit-table-postgresql.xql,v diff -u -r1.1 -r1.2 --- openacs-4/packages/ecommerce/www/admin/audit-table-postgresql.xql 10 Jul 2001 20:33:53 -0000 1.1 +++ openacs-4/packages/ecommerce/www/admin/audit-table-postgresql.xql 26 May 2002 04:36:50 -0000 1.2 @@ -1,17 +1,15 @@ - postgresql7.1 + + postgresql + 7.1 + - - - - select 1 - - where to_date('$start_date(date)','YYYY-MM-DD HH24:MI:SS') > to_date('$end_date(date)', 'YYYY-MM-DD HH24:MI:SS') - - - + + + select 1 where to_date('$start_date(date)','YYYY-MM-DD HH24:MI:SS') > to_date('$end_date(date)', 'YYYY-MM-DD HH24:MI:SS') + + - Index: openacs-4/packages/ecommerce/www/admin/index.tcl =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/ecommerce/www/admin/index.tcl,v diff -u -r1.2 -r1.3 --- openacs-4/packages/ecommerce/www/admin/index.tcl 31 Jan 2002 22:43:54 -0000 1.2 +++ openacs-4/packages/ecommerce/www/admin/index.tcl 26 May 2002 04:36:50 -0000 1.3 @@ -14,9 +14,13 @@ doc_body_append "[ad_admin_header "[ec_system_name] Administration"]

    [ec_system_name] Administration

    +
    + + + + +
    [ad_admin_context_bar Ecommerce([ec_system_name])]\[ help \]
    -[ad_admin_context_bar Ecommerce([ec_system_name])] -
    Documentation: /doc/ecommerce or [ec_url]doc/ Index: openacs-4/packages/ecommerce/www/admin/index.xql =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/ecommerce/www/admin/index.xql,v diff -u -r1.1 -r1.2 --- openacs-4/packages/ecommerce/www/admin/index.xql 10 Jul 2001 20:33:53 -0000 1.1 +++ openacs-4/packages/ecommerce/www/admin/index.xql 26 May 2002 04:36:50 -0000 1.2 @@ -1,50 +1,52 @@ + - - - select count(*) from ec_problems_log where resolved_date is null - - + + + select count(*) + from ec_problems_log + where resolved_date is null + + - - - - -select - sum(one_if_within_n_days(confirmed_date,1)) as n_in_last_24_hours, - sum(one_if_within_n_days(confirmed_date,7)) as n_in_last_7_days -from ec_orders_reportable - - + + + select sum(one_if_within_n_days(confirmed_date,1)) as n_in_last_24_hours, sum(one_if_within_n_days(confirmed_date,7)) as n_in_last_7_days + from ec_orders_reportable + + - - - - select count(*) as n_products, round(avg(price),2) as avg_price from ec_products_displayable - - + + + select count(*) as n_products, round(avg(price),2) as avg_price + from ec_products_displayable + + - - - - select count(*) from ec_customer_service_issues where close_date is null - - + + + select count(*) + from ec_customer_service_issues + where close_date is null + + - - - - select count(*) from ec_product_comments where approved_p is null - - + + + select count(*) + from ec_product_comments + where approved_p is null + + - - - - select count(*) from ec_user_class_user_map where user_class_approved_p is null or user_class_approved_p='f' - - + + + select count(*) + from ec_user_class_user_map + where user_class_approved_p is null + or user_class_approved_p='f' + + - Index: openacs-4/packages/ecommerce/www/admin/restore-one-id-oracle.xql =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/ecommerce/www/admin/restore-one-id-oracle.xql,v diff -u -r1.1 -r1.2 --- openacs-4/packages/ecommerce/www/admin/restore-one-id-oracle.xql 10 Jul 2001 20:33:53 -0000 1.1 +++ openacs-4/packages/ecommerce/www/admin/restore-one-id-oracle.xql 26 May 2002 04:36:50 -0000 1.2 @@ -1,13 +1,17 @@ - oracle8.1.6 + + oracle + 8.1.6 + - - - select * from $audit_table_name where rowid = :rowid - - + + + select * + from $audit_table_name + where rowid = :rowid + + - Index: openacs-4/packages/ecommerce/www/admin/restore-one-id-postgresql.xql =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/ecommerce/www/admin/restore-one-id-postgresql.xql,v diff -u -r1.1 -r1.2 --- openacs-4/packages/ecommerce/www/admin/restore-one-id-postgresql.xql 10 Jul 2001 20:33:53 -0000 1.1 +++ openacs-4/packages/ecommerce/www/admin/restore-one-id-postgresql.xql 26 May 2002 04:36:50 -0000 1.2 @@ -1,13 +1,17 @@ - postgresql7.1 + + postgresql + 7.1 + - - - select * from $audit_table_name where oid as rowid = :rowid - - + + + select * + from $audit_table_name + where oid as rowid = :rowid + + - Index: openacs-4/packages/ecommerce/www/admin/customer-service/spam-3-oracle.xql =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/ecommerce/www/admin/customer-service/spam-3-oracle.xql,v diff -u -r1.2 -r1.3 --- openacs-4/packages/ecommerce/www/admin/customer-service/spam-3-oracle.xql 29 Jan 2002 00:11:46 -0000 1.2 +++ openacs-4/packages/ecommerce/www/admin/customer-service/spam-3-oracle.xql 26 May 2002 04:36:50 -0000 1.3 @@ -6,8 +6,11 @@ select unique u.user_id as user_id, first_names, last_name, email - from cc_users u, ec_items 1, ec_orders o, ec_products p - where i.order_id=o.order_id and o.user_id=u.user_id and i_items.product_id=p.product_id and p.sku=:product_sku + from cc_users u, ec_items i, ec_orders o, ec_products p + where i.order_id = o.order_id + and o.user_id = u.user_id + and i.product_id = p.product_id + and p.sku = :product_sku Index: openacs-4/packages/ecommerce/www/admin/customer-service/spam-3-postgresql.xql =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/ecommerce/www/admin/customer-service/spam-3-postgresql.xql,v diff -u -r1.2 -r1.3 --- openacs-4/packages/ecommerce/www/admin/customer-service/spam-3-postgresql.xql 29 Jan 2002 00:11:46 -0000 1.2 +++ openacs-4/packages/ecommerce/www/admin/customer-service/spam-3-postgresql.xql 26 May 2002 04:36:50 -0000 1.3 @@ -6,8 +6,11 @@ select distinct u.user_id as user_id, first_names, last_name, email - from cc_users u, ec_items 1, ec_orders o, ec_products p - where i.order_id=o.order_id and o.user_id=u.user_id and i_items.product_id=p.product_id and p.sku=:product_sku + from cc_users u, ec_items i, ec_orders o, ec_products p + where i.order_id = o.order_id + and o.user_id = u.user_id + and i.product_id = p.product_id + and p.sku = :product_sku Index: openacs-4/packages/ecommerce/www/admin/customer-service/spam-3.tcl =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/ecommerce/www/admin/customer-service/spam-3.tcl,v diff -u -r1.3 -r1.4 --- openacs-4/packages/ecommerce/www/admin/customer-service/spam-3.tcl 31 Jan 2002 22:43:54 -0000 1.3 +++ openacs-4/packages/ecommerce/www/admin/customer-service/spam-3.tcl 26 May 2002 04:36:50 -0000 1.4 @@ -1,5 +1,3 @@ -# spam-3.tcl - ad_page_contract { @param spam_id @param subject @@ -19,8 +17,9 @@ @author @creation-date - @cvs-id spam-3.tcl,v 3.2.2.9 2000/09/22 01:34:54 kevin Exp @author ported by Jerry Asher (jerry@theashergroup.com) + @author revised by Bart Teeuwisse + } { spam_id:notnull subject:trim,notnull @@ -42,34 +41,36 @@ ad_require_permission [ad_conn package_id] admin set issue_type_list $issue_type -# no confirm page because they were just sent through the spell + +# No confirm page because they were just sent through the spell # checker (that's enough submits to push) set expires_to_insert [ec_decode $expires "" "null" $expires] -# get rid of stupid ^Ms +# Get rid of stupid ^Ms + regsub -all "\r" $message "" message +# Doubleclick protection -# doubleclick protection -if { [db_string get_log_entries_cnt "select count(*) from ec_spam_log where spam_id=:spam_id"] > 0 } { +if { [db_string get_log_entries_cnt " + select count(*) + from ec_spam_log + where spam_id = :spam_id"] > 0 } { - append doc_body "[ad_admin_header "Spam Sent"] -

    Spam Sent

    - [ad_admin_context_bar [list "../index.tcl" "Ecommerce([ec_system_name])"] [list "index.tcl" "Customer Service Administration"] "Spam Sent"] -
    - You are seeing this page because you probably either hit reload or pushed the Submit button twice. -

    - If you wonder whether the users got the spam, just check the customer service issues for one of the users (all mail sent to a user is recorded as a customer service issue). - [ad_admin_footer] - " + append doc_body " + [ad_admin_header "Spam Sent"] +

    Spam Sent

    + [ad_admin_context_bar [list "../index.tcl" "Ecommerce([ec_system_name])"] [list "index.tcl" "Customer Service Administration"] "Spam Sent"] +
    +

    You are seeing this page because you probably either hit reload or pushed the Submit button twice.

    +

    If you wonder whether the users got the spam, just check the customer service issues for one of the users (all mail sent to a user is recorded as a customer service issue).

    + [ad_admin_footer]" return } set return_url "[ad_conn url]?[export_entire_form_as_url_vars]" - set customer_service_rep [ad_get_user_id] - if {$customer_service_rep == 0} { ad_returnredirect "/register.tcl?[export_url_vars return_url]" return @@ -90,54 +91,42 @@ if { [info exists user_id_list] } { set users_query [db_map users_list] - # select user_id, email from cc_users where user_id in ([join $user_id_list ", "]) } elseif { [info exists mailing_list] } { if { [llength $mailing_list] == 0 } { set search_criteria [db_map null_categories] - # (category_id is null and subcategory_id is null and subsubcategory_id is null) } elseif { [llength $mailing_list] == 1 } { set search_criteria [db_map null_subcategory] - # (category_id=:mailing_list and subcategory_id is null) set mailing_list_category_id $mailing_list } elseif { [llength $mailing_list] == 2 } { set search_criteria [db_map null_subsubcategory] - # (subcategory_id=[lindex $mailing_list 1] and subsubcategory_id is null) set mailing_list_category_id [lindex $mailing_list 0] set mailing_list_subcategory_id [lindex $mailing_list 1] } else { set search_criteria [db_map null_subsubcategory] - # subsubcategory_id=[lindex $mailing_list 2] set mailing_list_category_id [lindex $mailing_list 0] set mailing_list_subcategory_id [lindex $mailing_list 1] set mailing_list_subsubcategory_id [lindex $mailing_list 2] } - set users_query "[db_map users_email] and $search_criteria" - # select users.user_id as user_id, email from cc_users, ec_cat_mailing_lists where users.user_id=ec_cat_mailing_lists.user_id - } elseif { [info exists user_class_id] } { if { ![empty_string_p $user_class_id]} { set users_query [db_map user_class] - # select u.user_id as user_id, first_names, last_name, email from cc_users u, ec_user_class_user_map m where m.user_class_id=:user_class_id and m.user_id=u.user_id } else { set users_query [db_map all_users] - # select user_id, first_names, last_name, email from cc_users } } elseif { [info exists product_sku] } { set users_query [db_map bought_product] - # select unique u.user_id as user_id, first_names, last_name, email from cc_users u, ec_items 1, ec_orders o, ec_products p where i.order_id=o.order_id and o.user_id=u.user_id and i_items.product_id=p.product_id and p.sku=:product_sku } elseif { [info exists viewed_product_sku] } { set users_query - # select unique u.user_id as user_id, first_names, last_name, email from cc_users u, ec_user_session_info ui, ec_user_sessions us, ec_products p where us.user_session_id=ui.user_session_id and us.user_id=u.user_id and ui.product_id=p.product_ud and p.sku=:viewed_product_sku } elseif { [info exists category_id] } { set users_query [db_map viewed_category] - # select unique u.user_id as user_id, first_names, last_name, email from cc_users u, ec_user_session_info ui, ec_user_sessions us where us.user_session_id=ui.user_session_id and us.user_id=u.user_id and ui.category_id=:category_id } elseif { [info exists start] } { set users_query [db_map last_visit] - # select user_id, first_names, last_name, email from cc_users where last_visit >= to_date(:start,'YYYY-MM-DD HH24:MI:SS') and last_visit <= to_date(:end,'YYYY-MM-DD HH24:MI:SS') } -# have to make all variables exist that will be inserted into ec_spam_log +# Have to make all variables exist that will be inserted into +# ec_spam_log + if { ![info exists mailing_list_category_id] } { set mailing_list_category_id "" } @@ -173,62 +162,52 @@ :mailing_list_subcategory_id, :mailing_list_subsubcategory_id, :user_class_id, :product_id, to_date(:start,'YYYY-MM-DD HH24:MI:SS'), - to_date(:end,'YYYY-MM-DD HH24:MI:SS')) - " + to_date(:end,'YYYY-MM-DD HH24:MI:SS'))" set sql $users_query - append doc_body "[ad_admin_header "Spamming Users..."] -

    Spamming Users...

    + append doc_body " + [ad_admin_header "Spamming Users..."] +

    Spamming Users...

    -[ad_admin_context_bar [list "../index.tcl" "Ecommerce([ec_system_name])"] [list "index.tcl" "Customer Service Administration"] "Spamming Users..."] + [ad_admin_context_bar [list "../index.tcl" "Ecommerce([ec_system_name])"] [list "index.tcl" "Customer Service Administration"] "Spamming Users..."] -
    -
      -" +
      +
        " -db_foreach get_users_for_spam $sql { - - # create a customer service issue/interaction/action - set user_identification_and_issue_id [ec_customer_service_simple_issue "" "automatic" "email" "To: $email\nFrom: [ad_parameter -package_id [ec_id] CustomerServiceEmailAddress ecommerce]\nSubject: $subject" "" $issue_type_list $message $user_id "" "f"] - - set user_identification_id [lindex $user_identification_and_issue_id 0] - set issue_id [lindex $user_identification_and_issue_id 1] - - set email_from [ec_customer_service_email_address $user_identification_id $issue_id] - - ec_sendmail_from_service "$email" "$email_from" "$subject" "$message" + db_foreach get_users_for_spam $sql { + + # Create a customer service issue/interaction/action - if { ![empty_string_p $amount] && $amount > 0 } { - # put a record into ec_gift_certificates - # and add the amount to the user's gift certificate account + set user_identification_and_issue_id [ec_customer_service_simple_issue "" "automatic" "email" "To: $email\nFrom: [ad_parameter -package_id [ec_id] CustomerServiceEmailAddress ecommerce]\nSubject: $subject" "" $issue_type_list $message $user_id "" "f"] + + set user_identification_id [lindex $user_identification_and_issue_id 0] + set issue_id [lindex $user_identification_and_issue_id 1] + set email_from [ec_customer_service_email_address $user_identification_id $issue_id] + + ec_sendmail_from_service "$email" "$email_from" "$subject" "$message" - db_dml insert_record_for_gift_certificates " - insert into ec_gift_certificates - (gift_certificate_id, user_id, amount, - expires, - issue_date, issued_by, gift_certificate_state, - last_modified, last_modifying_user, modified_ip_address) - values - (ec_gift_cert_id_sequence.nextval, :user_id, :amount, - $expires_to_insert, - sysdate, :customer_service_rep, 'authorized', - sysdate, :customer_service_rep, '[ns_conn peeraddr]') - " + if { ![empty_string_p $amount] && $amount > 0 } { + + # Put a record into ec_gift_certificates and add the amount to + # the user's gift certificate account + + db_dml insert_record_for_gift_certificates " + insert into ec_gift_certificates + (gift_certificate_id, user_id, amount, expires, issue_date, issued_by, gift_certificate_state, last_modified, last_modifying_user, modified_ip_address) + values + (ec_gift_cert_id_sequence.nextval, :user_id, :amount, $expires_to_insert, sysdate, :customer_service_rep, 'authorized', sysdate, :customer_service_rep, '[ns_conn peeraddr]') " + } + + append doc_body "
      • Email has been sent to $email
      • " } - - append doc_body "
      • Email has been sent to $email\n" -} } -append doc_body "
      +append doc_body " +
    + [ad_admin_footer]" -[ad_admin_footer]" - - - - doc_return 200 text/html $doc_body Index: openacs-4/packages/ecommerce/www/admin/orders/address-add-2.tcl =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/ecommerce/www/admin/orders/address-add-2.tcl,v diff -u -r1.1 -r1.2 --- openacs-4/packages/ecommerce/www/admin/orders/address-add-2.tcl 20 Apr 2001 20:51:14 -0000 1.1 +++ openacs-4/packages/ecommerce/www/admin/orders/address-add-2.tcl 26 May 2002 04:36:50 -0000 1.2 @@ -1,47 +1,48 @@ -# /www/[ec_url_concat [ec_url] /admin]/orders/address-add-2.tcl ad_page_contract { - Confirm shipping address. - @author Eve Andersson (eveander@arsdigita.com) - @creation-date Summer 1999 - @cvs-id address-add-2.tcl,v 3.1.6.3 2000/08/16 16:28:51 seb Exp - @author ported by Jerry Asher (jerry@theashergroup.com) + Confirm shipping address. + + @author Eve Andersson (eveander@arsdigita.com) + @creation-date Summer 1999 + @author ported by Jerry Asher (jerry@theashergroup.com) + @author revised by Bart Teeuwisse + @revision-date April 2002 + } { - order_id:integer,notnull - attn - line1 - line2 - city - {usps_abbrev ""} - {full_state_name ""} - zip_code - {country_code "us"} - phone - phone_time + order_id:integer,notnull + creditcard_id:integer,optional + attn + line1 + line2 + city + {usps_abbrev ""} + {full_state_name ""} + zip_code + {country_code "us"} + phone + phone_time } ad_require_permission [ad_conn package_id] admin -doc_body_append "[ad_admin_header "Confirm Shipping Address"] +doc_body_append " + [ad_admin_header "Confirm Shipping Address"] -

    Confirm Shipping Address

    +

    Confirm Shipping Address

    -[ad_admin_context_bar [list "../" "Ecommerce([ec_system_name])"] [list "index" "Orders"] [list "one?[export_url_vars order_id]" "One Order"] "Confirm Shipping Address"] + [ad_admin_context_bar [list "../" "Ecommerce([ec_system_name])"] [list "index" "Orders"] [list "one?[export_url_vars order_id]" "One Order"] "Confirm Shipping Address"] -
    -Please confirm new address: -
    -" +
    +

    Please confirm new address:

    +
    " doc_body_append " - -[ec_display_as_html [ec_pretty_mailing_address_from_args $line1 $line2 $city $usps_abbrev $zip_code $country_code $full_state_name $attn $phone $phone_time]] - -
    -
    -[export_entire_form] -
    - -
    -[ad_admin_footer] -" + [ec_display_as_html [ec_pretty_mailing_address_from_args $line1 $line2 $city $usps_abbrev $zip_code $country_code $full_state_name $attn $phone $phone_time]] +
    + + [export_entire_form] +
    + +
    + + [ad_admin_footer]" Index: openacs-4/packages/ecommerce/www/admin/orders/address-add-3.tcl =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/ecommerce/www/admin/orders/address-add-3.tcl,v diff -u -r1.2 -r1.3 --- openacs-4/packages/ecommerce/www/admin/orders/address-add-3.tcl 29 Jan 2002 00:11:46 -0000 1.2 +++ openacs-4/packages/ecommerce/www/admin/orders/address-add-3.tcl 26 May 2002 04:36:50 -0000 1.3 @@ -1,40 +1,76 @@ -# /www/[ec_url_concat [ec_url] /admin]/orders/address-add-3.tcl ad_page_contract { - Insert the address. - @author Eve Andersson (eveander@arsdigita.com) - @creation-date Summer 1999 - @cvs-id address-add-3.tcl,v 3.2.2.4 2000/08/16 16:28:51 seb Exp - @author ported by Jerry Asher (jerry@theashergroup.com) + Insert the address. + + @author Eve Andersson (eveander@arsdigita.com) + @creation-date Summer 1999 + @author ported by Jerry Asher (jerry@theashergroup.com) + @author revised by Bart Teeuwisse + @revision-date April 2002 + } { - order_id:integer,notnull - attn - line1 - line2 - city - {usps_abbrev ""} - {full_state_name ""} - zip_code - {country_code "us"} - phone - phone_time + order_id:integer,notnull + creditcard_id:integer,optional + attn + line1 + line2 + city + {usps_abbrev ""} + {full_state_name ""} + zip_code + {country_code "us"} + phone + phone_time } ad_require_permission [ad_conn package_id] admin -# insert the address into ec_addresses, update the address in ec_orders +if {![info exists creditcard_id] || ([info exists creditcard_id] && [empty_string_p creditcard_id])} { -db_transaction { - set address_id [db_nextval ec_address_id_sequence] - set user_id [db_string user_id_select "select user_id from ec_orders where order_id=:order_id"] + # Insert the address into ec_addresses, update the address in + # ec_orders - db_dml address_insert "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, 'shipping', :attn, :line1, :line2, :city, :usps_abbrev, :full_state_name, :zip_code, :country_code, :phone, :phone_time) - " + db_transaction { + set address_id [db_nextval ec_address_id_sequence] + set user_id [db_string user_id_select " + select user_id + from ec_orders + where order_id = :order_id"] - db_dml ec_orders_update "update ec_orders set shipping_address=:address_id where order_id=:order_id" + db_dml address_insert " + 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, 'shipping', :attn, :line1, :line2, :city, :usps_abbrev, :full_state_name, :zip_code, :country_code, :phone, :phone_time)" + + db_dml ec_orders_update " + update ec_orders + set shipping_address = :address_id + where order_id = :order_id" + } +} else { + + # Insert the address into ec_addresses, update the address in + # ec_creditcards + + db_transaction { + set address_id [db_nextval ec_address_id_sequence] + set user_id [db_string user_id_select " + select user_id + from ec_orders + where order_id = :order_id"] + + db_dml address_insert " + 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, 'shipping', :attn, :line1, :line2, :city, :usps_abbrev, :full_state_name, :zip_code, :country_code, :phone, :phone_time)" + + db_dml ec_creditcards_update " + update ec_creditcards + set billing_address = :address_id + where creditcard_id = :creditcard_id" + } } ad_returnredirect "one?[export_url_vars order_id]" Index: openacs-4/packages/ecommerce/www/admin/orders/address-add-3.xql =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/ecommerce/www/admin/orders/address-add-3.xql,v diff -u -r1.1 -r1.2 --- openacs-4/packages/ecommerce/www/admin/orders/address-add-3.xql 10 Jul 2001 20:33:53 -0000 1.1 +++ openacs-4/packages/ecommerce/www/admin/orders/address-add-3.xql 26 May 2002 04:36:50 -0000 1.2 @@ -1,29 +1,37 @@ - - - select user_id from ec_orders where order_id=:order_id - - - - - - + + + select user_id + from ec_orders + 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, 'shipping', :attn, :line1, :line2, :city, :usps_abbrev, :full_state_name, :zip_code, :country_code, :phone, :phone_time) + (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, 'shipping', :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 + + + + + + update ec_creditcards + set billing_address = :address_id + where creditcard_id = :creditcard_id + + - - - - update ec_orders set shipping_address=:address_id where order_id=:order_id - - - - Index: openacs-4/packages/ecommerce/www/admin/orders/address-add.tcl =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/ecommerce/www/admin/orders/address-add.tcl,v diff -u -r1.3 -r1.4 --- openacs-4/packages/ecommerce/www/admin/orders/address-add.tcl 23 Oct 2001 05:07:14 -0000 1.3 +++ openacs-4/packages/ecommerce/www/admin/orders/address-add.tcl 26 May 2002 04:36:50 -0000 1.4 @@ -1,118 +1,120 @@ -# www/[ec_url_concat [ec_url] /admin]/orders/address-add.tcl ad_page_contract { - New shipping address. + New shipping address. - @author Eve Andersson (eveander@arsdigita.com) - @creation-date Summer 1999 - @cvs-id address-add.tcl,v 3.1.6.4 2000/08/16 16:28:51 seb Exp - @author ported by Jerry Asher (jerry@theashergroup.com) + @author Eve Andersson (eveander@arsdigita.com) + @creation-date Summer 1999 + @author ported by Jerry Asher (jerry@theashergroup.com) + @author revised by Bart Teeuwisse + @revision-date April 2002 + } { - order_id:integer,notnull + order_id:integer,notnull + creditcard_id:integer,optional } ad_require_permission [ad_conn package_id] admin -doc_body_append "[ad_admin_header "New Shipping Address"] +doc_body_append " + [ad_admin_header "New Shipping Address"] -

    New Shipping Address

    +

    New Shipping Address

    -[ad_admin_context_bar [list "../" "Ecommerce([ec_system_name])"] [list "index" "Orders"] [list "one?[export_url_vars order_id]" "One Order"] "New Shipping Address"] + [ad_admin_context_bar [list "../" "Ecommerce([ec_system_name])"] [list "index" "Orders"] [list "one?[export_url_vars order_id]" "One Order"] "New Shipping Address"] -
    -Please enter a new domestic address or a new international address. All future shipments for this order will go to this address. +
    +

    Please enter a new domestic address or a new international address. All future shipments for this order will go to this address.

    -

    -New domestic address: -" +

    New domestic address:

    " +set user_name [db_string user_name_select " + select first_names || ' ' || last_name + from cc_users, ec_orders + where ec_orders.user_id=cc_users.user_id + and order_id=:order_id" -default ""] -set user_name [db_string user_name_select "select first_names || ' ' || last_name from cc_users, ec_orders where ec_orders.user_id=cc_users.user_id and order_id=:order_id"] - doc_body_append " -
    -
    -[export_form_vars order_id] - - - - - - - - - - - - - - - - - - - - - - - - - -
    Name
    Address
    2nd line (optional)
    City  State [state_widget]
    Zip
    Phone day     evening
    -

    -

    - -
    -
    -
    +
    +
    + [export_form_vars order_id creditcard_id] + + + + + + + + + + + + + + + + + + + + + + + + + +
    Name
    Address
    2nd line (optional)
    City  State [state_widget]
    Zip
    Phone day     + evening
    +
    + +
    +
    +
    + +

    New international address:

    -

    -New international address: -

    -

    -[export_form_vars order_id] -
    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    Name
    Address
    2nd line (optional)
    City
    Province or Region
    Postal Code
    Country[ec_country_widget]
    Phone day     evening
    -
    -

    -

    - -
    -
    +
    +
    + [export_form_vars order_id creditcard_id] + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Name
    Address
    2nd line (optional)
    City
    Province or Region
    Postal Code
    Country[ec_country_widget]
    Phone day     + evening
    +
    + +
    +
    +
    -[ad_admin_footer] -" + [ad_admin_footer]" Index: openacs-4/packages/ecommerce/www/admin/orders/by-order-state-and-time-oracle.xql =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/ecommerce/www/admin/orders/by-order-state-and-time-oracle.xql,v diff -u -r1.2 -r1.3 --- openacs-4/packages/ecommerce/www/admin/orders/by-order-state-and-time-oracle.xql 23 Jul 2001 05:40:41 -0000 1.2 +++ openacs-4/packages/ecommerce/www/admin/orders/by-order-state-and-time-oracle.xql 26 May 2002 04:36:50 -0000 1.3 @@ -1,41 +1,24 @@ - oracle8.1.6 + oracle8.1.6 - - + + and sysdate-o.confirmed_date <= 1 - - + + - - - + + and sysdate-o.confirmed_date <= 7 - - + + - - - + + and months_between(sysdate,o.confirmed_date) <= 1 - - + + - - - - select o.order_id, o.confirmed_date, o.order_state, ec_total_price(o.order_id) as price_to_display, o.user_id, u.first_names, u.last_name, count(*) as n_items -from ec_orders o, cc_users u, ec_items i -where o.user_id=u.user_id(+) -and o.order_id=i.order_id -$confirmed_query_bit $order_state_query_bit -group by o.order_id, o.confirmed_date, o.order_state, ec_total_price(o.order_id), o.user_id, u.first_names, u.last_name -order by $order_by_clause - - - - - Index: openacs-4/packages/ecommerce/www/admin/orders/by-order-state-and-time-postgresql.xql =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/ecommerce/www/admin/orders/by-order-state-and-time-postgresql.xql,v diff -u -r1.1 -r1.2 --- openacs-4/packages/ecommerce/www/admin/orders/by-order-state-and-time-postgresql.xql 23 Jul 2001 05:40:41 -0000 1.1 +++ openacs-4/packages/ecommerce/www/admin/orders/by-order-state-and-time-postgresql.xql 26 May 2002 04:36:50 -0000 1.2 @@ -1,27 +1,24 @@ - postgresql7.1 + postgresql7.1 - - - and now()-o.confirmed_date <= timespan_days(1) - - + + + where now()-o.confirmed_date <= timespan_days(1) + + + + + where now()-o.confirmed_date <= timespan_days(7) + + - - - and now()-o.confirmed_date <= timespan_days(7) - - - - - - - and now()-o.confirmed_date <= '1 month'::interval - - - - + + + where now()-o.confirmed_date <= '1 month'::interval + + + Index: openacs-4/packages/ecommerce/www/admin/orders/by-order-state-and-time.tcl =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/ecommerce/www/admin/orders/by-order-state-and-time.tcl,v diff -u -r1.3 -r1.4 --- openacs-4/packages/ecommerce/www/admin/orders/by-order-state-and-time.tcl 6 Jan 2002 06:09:13 -0000 1.3 +++ openacs-4/packages/ecommerce/www/admin/orders/by-order-state-and-time.tcl 26 May 2002 04:36:50 -0000 1.4 @@ -1,42 +1,51 @@ -# /www/[ec_url_concat [ec_url] /admin]/orders/by-order-state-and-time.tcl ad_page_contract { - View orders by order state and order time. + View orders by order state and order time. - @author Eve Anderson (eveander@arsdigita.com) - @author Bart Teeuwisse (bart.teeuwisse@7-sisters.com) - @creation-date Summer 1999 - @cvs-id by-order-state-and-time.tcl,v 3.2.2.3 2000/08/16 16:28:51 seb Exp - @author ported by Jerry Asher (jerry@theashergroup.com) + @author Eve Anderson (eveander@arsdigita.com) + @author Bart Teeuwisse (bart.teeuwisse@7-sisters.com) + @creation-date Summer 1999 + @author ported by Jerry Asher (jerry@theashergroup.com) + @author revised by Bart Teeuwisse + @revision-date April 2002 + } { - {view_order_state "reportable"} - {view_confirmed "all"} - {order_by "order_id"} + {view_order_state "reportable"} + {view_confirmed "last_24"} + {order_by "order_id"} } ad_require_permission [ad_conn package_id] admin -doc_body_append "[ad_admin_header "Order History"] +doc_body_append " + [ad_admin_header "Order History"] -

    Order History

    +

    Order History

    -[ad_admin_context_bar [list "../" "Ecommerce([ec_system_name])"] [list "index" "Orders"] "History"] + [ad_admin_context_bar [list "../" "Ecommerce([ec_system_name])"] [list "index" "Orders"] "History"] +
    -
    +
    + [export_form_vars view_confirmed order_by] + + + + + + +
    Order StateConfirmed Date
    - - - - - - - + + +
    Order StateConfirmed Date
    - - -" +doc_body_append " + + + " set confirmed_list [list [list last_24 "last 24 hrs"] [list last_week "last week"] [list last_month "last month"] [list all all]] @@ -63,97 +72,100 @@ } } -doc_body_append "\[ [join $linked_confirmed_list " | "] \] +doc_body_append " + \[ [join $linked_confirmed_list " | "] \] +
    + +
    " -
    - - -
    -" - if { $view_order_state == "reportable" } { - set order_state_query_bit "and o.order_state in ('authorized_plus_avs','authorized_minus_avs','partially_fulfilled','fulfilled')" + set order_state_query_bit "and o.order_state in ('authorized', 'partially_fulfilled', 'fulfilled')" } else { set order_state_query_bit "and o.order_state=:view_order_state" } if { $view_confirmed == "last_24" } { - #set confirmed_query_bit "where sysdate-o.confirmed_date <= 1" set confirmed_query_bit [db_map last_24] } elseif { $view_confirmed == "last_week" } { - #set confirmed_query_bit "where sysdate-o.confirmed_date <= 7" set confirmed_query_bit [db_map last_week] } elseif { $view_confirmed == "last_month" } { - #set confirmed_query_bit "where months_between(sysdate,o.confirmed_date) <= 1" set confirmed_query_bit [db_map last_month] } else { set confirmed_query_bit "where true" } set link_beginning "by-order-state-and-time?[export_url_vars view_order_state view_confirmed]" -set order_by_clause [util_decode $order_by \ - "order_id" "order_id" \ - "confirmed_date" "confirmed_date" \ - "order_state" "order_state" \ - "name" "last_name, first_names" \ - "price" "ec_total_price(o.order_id)" \ - "n_items" "n_items"] +set order_by_clause [ec_decode $order_by \ + "order_id" "order_id" \ + "confirmed_date" "confirmed_date" \ + "order_state" "order_state" \ + "name" "last_name, first_names" \ + "price" "ec_total_price(o.order_id)" \ + "n_items" "n_items"] -set table_header " - - - - - - - -" +set table_header " +
    Order IDDate ConfirmedOrder StateCustomerAmount# of Items
    + + + + + + + + " - - set row_counter 0 -db_foreach orders_select "select o.order_id, o.confirmed_date, o.order_state, ec_total_price(o.order_id) as price_to_display, o.user_id, u.first_names, u.last_name, count(*) as n_items -from ec_orders o, cc_users u, ec_items i -where o.user_id=u.user_id(+) -and o.order_id=i.order_id -$confirmed_query_bit $order_state_query_bit -group by o.order_id, o.confirmed_date, o.order_state, ec_total_price(o.order_id), o.user_id, u.first_names, u.last_name -order by $order_by_clause -" { - if { $row_counter == 0 } { - doc_body_append $table_header - } elseif { $row_counter == 20 } { - doc_body_append "
    Order IDDate ConfirmedOrder StateCustomerAmount# of Items
    +db_foreach orders_select " + select o.order_id, o.confirmed_date, o.order_state, ec_total_price(o.order_id) as price_to_display, o.user_id, u.first_names, u.last_name, count(*) as n_items + from ec_orders o, cc_users u, ec_items i + where o.user_id=u.user_id(+) + and o.order_id=i.order_id + $confirmed_query_bit $order_state_query_bit + group by o.order_id, o.confirmed_date, o.order_state, ec_total_price(o.order_id), o.user_id, u.first_names, u.last_name + order by $order_by_clause" { + + if { $row_counter == 0 } { + doc_body_append $table_header + } elseif { $row_counter == 20 } { + doc_body_append "

    $table_header " - set row_counter 1 - } - # even rows are white, odd are grey - if { [expr floor($row_counter/2.)] == [expr $row_counter/2.] } { - set bgcolor "white" - } else { - set bgcolor "ececec" - } - doc_body_append " -$order_id -[ec_nbsp_if_null [util_AnsiDatetoPrettyDate $confirmed_date]] -$order_state -[ec_decode $last_name "" " " "$last_name, $first_names"] -[ec_nbsp_if_null [ec_pretty_price $price_to_display]] -$n_items - " + set row_counter 1 + } + + # Even rows are white, odd are grey + + if { [expr floor($row_counter/2.)] == [expr $row_counter/2.] } { + set bgcolor "white" + } else { + set bgcolor "ececec" + } + + doc_body_append " + + $order_id + [ec_nbsp_if_null [util_AnsiDatetoPrettyDate $confirmed_date]] + $order_state + [ec_decode $last_name "" " " "$last_name, $first_names"] + [ec_nbsp_if_null [ec_pretty_price $price_to_display]] + $n_items + " incr row_counter } if { $row_counter != 0 } { - doc_body_append "" + doc_body_append " + " } else { - doc_body_append "

    None Found
    " + doc_body_append " +
    None Found
    " } -doc_body_append "
    +doc_body_append " + -[ad_admin_footer] -" + [ad_admin_footer]" Index: openacs-4/packages/ecommerce/www/admin/orders/by-order-state-and-time.xql =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/ecommerce/www/admin/orders/Attic/by-order-state-and-time.xql,v diff -u -r1.3 -r1.4 --- openacs-4/packages/ecommerce/www/admin/orders/by-order-state-and-time.xql 22 Jul 2001 05:08:55 -0000 1.3 +++ openacs-4/packages/ecommerce/www/admin/orders/by-order-state-and-time.xql 26 May 2002 04:36:50 -0000 1.4 @@ -2,19 +2,17 @@ - - - -select o.order_id, o.confirmed_date, o.order_state, ec_total_price(o.order_id) as price_to_display, o.user_id, u.first_names, u.last_name, count(*) as n_items -from ec_orders o - JOIN ec_items i using (order_id) - LEFT JOIN cc_users u on (o.user_id=u.user_id) -$confirmed_query_bit $order_state_query_bit -group by o.order_id, o.confirmed_date, o.order_state, ec_total_price(o.order_id), o.user_id, u.first_names, u.last_name -order by $order_by_clause - - - - - + + + select o.order_id, o.confirmed_date, o.order_state, ec_total_price(o.order_id) as price_to_display, o.user_id, u.first_names, u.last_name, count(*) as n_items + from ec_orders o + join ec_items i using (order_id) + left join cc_users u on (o.user_id=u.user_id) + $confirmed_query_bit + $order_state_query_bit + group by o.order_id, o.confirmed_date, o.order_state, ec_total_price(o.order_id), o.user_id, u.first_names, u.last_name + order by $order_by_clause + + + Index: openacs-4/packages/ecommerce/www/admin/orders/creditcard-add-2.tcl =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/ecommerce/www/admin/orders/creditcard-add-2.tcl,v diff -u -r1.1 -r1.2 --- openacs-4/packages/ecommerce/www/admin/orders/creditcard-add-2.tcl 20 Apr 2001 20:51:14 -0000 1.1 +++ openacs-4/packages/ecommerce/www/admin/orders/creditcard-add-2.tcl 26 May 2002 04:36:50 -0000 1.2 @@ -1,82 +1,89 @@ -# www/[ec_url_concat [ec_url] /admin]/orders/creditcard-add-2.tcl ad_page_contract { - Credit card confirm. - @author Eve Andersson (eveander@arsdigita.com) - @creation-date Summer 1999 - @cvs-id creditcard-add-2.tcl,v 3.1.6.2 2000/08/16 18:49:04 seb Exp - @author ported by Jerry Asher (jerry@theashergroup.com) + Credit card confirm. + + @author Eve Andersson (eveander@arsdigita.com) + @creation-date Summer 1999 + @author ported by Jerry Asher (jerry@theashergroup.com) + @author revised by Bart Teeuwisse + @revision-date April 2002 + } { - order_id:integer,notnull - creditcard_number - creditcard_type - creditcard_expire_1 - creditcard_expire_2 - billing_zip_code + + address_id:notnull + order_id:integer,notnull + creditcard_number + creditcard_type + creditcard_expire_1 + creditcard_expire_2 } ad_require_permission [ad_conn package_id] admin -# get rid of spaces and dashes +# Get rid of spaces and dashes + regsub -all -- "-" $creditcard_number "" creditcard_number -regsub -all " " $creditcard_number "" creditcard_number +regsub -all -- " " $creditcard_number "" creditcard_number -# error checking +# Error checking + 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 + + # I've already removed spaces and dashes, so only numbers should + # remain + incr exception_count - append exception_text "
  • Your credit card number contains invalid characters." + append exception_text "
  • Your credit card number contains invalid characters.
  • " } if { ![info exists creditcard_type] || [empty_string_p $creditcard_type] } { incr exception_count - append exception_text "
  • You forgot to enter your credit card type." + append exception_text "
  • You forgot to enter your credit card type.
  • " } -# 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] +# 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 "
  • Please enter your full credit card expiration date (month and year)" + append exception_text "
  • Please enter your full credit card expiration date (month and year).
  • " } if { $exception_count > 0 } { ad_return_complaint $exception_count $exception_text return } -doc_body_append "[ad_admin_header "Confirm Credit Card"] +doc_body_append " + [ad_admin_header "Confirm Credit Card"] -

    Confirm Credit Card

    +

    Confirm Credit Card

    -[ad_admin_context_bar [list "../" "Ecommerce([ec_system_name])"] [list "index" "Orders"] [list "one?[export_url_vars order_id]" "One Order"] "Confirm Credit Card"] + [ad_admin_context_bar [list "../" "Ecommerce([ec_system_name])"] [list "index" "Orders"] [list "one?[export_url_vars order_id]" "One Order"] "Confirm Credit Card"] -
    -Please confirm that this is correct: +
    -
    -
    +    

    Please confirm that this is correct:

    + +
    +
     [ec_pretty_creditcard_type $creditcard_type]
     $creditcard_number
     exp: $creditcard_expire_1/$creditcard_expire_2
    -zip: $billing_zip_code
    -
    -
    +
    +
    -
    -[export_entire_form] - -
    - -
    - -[ad_admin_footer] -" + + [export_entire_form] +
    + +
    +
    + [ad_admin_footer]" Index: openacs-4/packages/ecommerce/www/admin/orders/creditcard-add-3.tcl =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/ecommerce/www/admin/orders/creditcard-add-3.tcl,v diff -u -r1.2 -r1.3 --- openacs-4/packages/ecommerce/www/admin/orders/creditcard-add-3.tcl 29 Jan 2002 00:11:46 -0000 1.2 +++ openacs-4/packages/ecommerce/www/admin/orders/creditcard-add-3.tcl 26 May 2002 04:36:50 -0000 1.3 @@ -1,37 +1,38 @@ -# www/[ec_url_concat [ec_url] /admin]/orders/creditcard-add-3.tcl ad_page_contract { - @author Eve Andersson (eveander@arsdigita.com) - @creation-date Summer 1999 - @cvs-id creditcard-add-3.tcl,v 3.1.6.3 2000/08/16 18:49:04 seb Exp - @author ported by Jerry Asher (jerry@theashergroup.com) + @author Eve Andersson (eveander@arsdigita.com) + @creation-date Summer 1999 + @author ported by Jerry Asher (jerry@theashergroup.com) + @author revised by Bart Teeuwisse + @revision-date April 2002 + } { - order_id:insert,notnull - creditcard_number:notnull - creditcard_type:notnull - creditcard_expire_1 - creditcard_expire_2 - billing_zip_code + address_id + order_id:notnull + creditcard_number:notnull + creditcard_type:notnull + creditcard_expire_1 + creditcard_expire_2 } ad_require_permission [ad_conn package_id] admin db_transaction { - - set user_id [db_string user_id_select "select user_id from ec_orders where order_id=:order_id"] - - set creditcard_id [db_nextval ec_creditcard_id_sequence] - - set creditcard_last_four [string range $creditcard_number [expr [string length $creditcard_number] -4] [expr [string length $creditcard_number] -1]] - set creditcard_expire "$creditcard_expire_1/$creditcard_expire_2" - - db_dml creditcard_insert_select "insert into ec_creditcards - (creditcard_id, user_id, creditcard_number, creditcard_last_four, creditcard_type, creditcard_expire, billing_zip_code) - values - (:creditcard_id, :user_id, :creditcard_number, :creditcard_last_four, :creditcard_type, :creditcard_expire, :billing_zip_code) - " - - db_dml ec_orders_update "update ec_orders set creditcard_id=:creditcard_id where order_id=:order_id" + set user_id [db_string user_id_select " + select user_id + from ec_orders + where order_id = :order_id"] + set creditcard_id [db_nextval ec_creditcard_id_sequence] + set creditcard_last_four [string range $creditcard_number [expr [string length $creditcard_number] -4] [expr [string length $creditcard_number] -1]] + set creditcard_expire "$creditcard_expire_1/$creditcard_expire_2" + db_dml creditcard_insert_select " + 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, :creditcard_last_four, :creditcard_type, :creditcard_expire, :address_id)" + db_dml ec_orders_update " + update ec_orders + set creditcard_id = :creditcard_id + where order_id = :order_id" } - ad_returnredirect "one?[export_url_vars order_id]" Index: openacs-4/packages/ecommerce/www/admin/orders/creditcard-add-3.xql =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/ecommerce/www/admin/orders/creditcard-add-3.xql,v diff -u -r1.1 -r1.2 --- openacs-4/packages/ecommerce/www/admin/orders/creditcard-add-3.xql 10 Jul 2001 20:33:53 -0000 1.1 +++ openacs-4/packages/ecommerce/www/admin/orders/creditcard-add-3.xql 26 May 2002 04:36:50 -0000 1.2 @@ -1,29 +1,29 @@ - - - select user_id from ec_orders where order_id=:order_id - - - - - - - insert into ec_creditcards - (creditcard_id, user_id, creditcard_number, creditcard_last_four, creditcard_type, creditcard_expire, billing_zip_code) - values - (:creditcard_id, :user_id, :creditcard_number, :creditcard_last_four, :creditcard_type, :creditcard_expire, :billing_zip_code) + + + select user_id + from ec_orders + 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, :creditcard_last_four, :creditcard_type, :creditcard_expire, :address_id) + + - - - - update ec_orders set creditcard_id=:creditcard_id where order_id=:order_id - - - - + + + update ec_orders + set creditcard_id = :creditcard_id + where order_id = :order_id + + + Index: openacs-4/packages/ecommerce/www/admin/orders/creditcard-add.tcl =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/ecommerce/www/admin/orders/creditcard-add.tcl,v diff -u -r1.1 -r1.2 --- openacs-4/packages/ecommerce/www/admin/orders/creditcard-add.tcl 20 Apr 2001 20:51:14 -0000 1.1 +++ openacs-4/packages/ecommerce/www/admin/orders/creditcard-add.tcl 26 May 2002 04:36:50 -0000 1.2 @@ -1,60 +1,78 @@ -# /www/[ec_url_concat [ec_url] /admin]/orders/creditcard-add.tcl ad_page_contract { - Add a creditcard. - @author Eve Andersson (eveander@arsdigita.com) - @creation-date Summer 1999 - @cvs-id creditcard-add.tcl,v 3.1.6.3 2000/08/16 18:49:04 seb Exp - @author ported by Jerry Asher (jerry@theashergroup.com) + Add a creditcard. + + @author Eve Andersson (eveander@arsdigita.com) + @creation-date Summer 1999 + @author ported by Jerry Asher (jerry@theashergroup.com) + @author revised by Bart Teeuwisse + @revision-date April 2002 + } { - order_id:integer,notnull + order_id:integer,notnull } ad_require_permission [ad_conn package_id] admin -doc_body_append "[ad_admin_header "New Credit Card"] +doc_body_append " + [ad_admin_header "New Credit Card"] -

    New Credit Card

    +

    New Credit Card

    -[ad_admin_context_bar [list "../" "Ecommerce([ec_system_name])"] [list "index" "Orders"] [list "one?[export_url_vars order_id]" "One Order"] "New Credit Card"] + [ad_admin_context_bar [list "../" "Ecommerce([ec_system_name])"] [list "index" "Orders"] [list "one?[export_url_vars order_id]" "One Order"] "New Credit Card"] -
    -Entering a new credit card will cause all future transactions involving this order -to use this credit card. However, it will not have any effect on transactions that -are currently underway (e.g., if a transaction has already been authorized with a -different credit card, that credit card will be used to complete the transaction). -" +
    +

    Entering a new credit card will cause all future transactions + involving this order to use this credit card. However, it will + not have any effect on transactions that are currently + underway (e.g., if a transaction has already been authorized + with a different credit card, that credit card will be used to + complete the transaction).

    " +db_0or1row select_billing_address " + select c.billing_address, a.country_code + from ec_creditcards c, ec_orders o, ec_addresses a + where o.creditcard_id = c.creditcard_id + and a.address_id = c.billing_address + and o.order_id = :order_id + limit 1" -set zip_code [db_string zip_code_select "select zip_code from ec_addresses a, ec_orders o where a.address_id=o.shipping_address and order_id=:order_id"] - -doc_body_append "
    -[export_form_vars order_id] -
    - - - - - - - - - - - - - - - - -
    Credit card number:
    Type:[ec_creditcard_widget]
    Expires:[ec_creditcard_expire_1_widget] [ec_creditcard_expire_2_widget]
    Billing zip code:
    -
    - -
    - -
    - -
    - -[ad_admin_footer] -" +doc_body_append " + + + + + + + +
    + [ec_display_as_html [ec_pretty_mailing_address_from_ec_addresses $billing_address]] + " +doc_body_append " + + +
    + + [export_form_vars order_id] + + + + + + + + + + + + + + +
    Credit card number:
    Type:[ec_creditcard_widget] +
    + +
    +
    Expires:[ec_creditcard_expire_1_widget] [ec_creditcard_expire_2_widget]
    +
    +
    + [ad_admin_footer]" Index: openacs-4/packages/ecommerce/www/admin/orders/creditcard-add.xql =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/ecommerce/www/admin/orders/creditcard-add.xql,v diff -u -r1.1 -r1.2 --- openacs-4/packages/ecommerce/www/admin/orders/creditcard-add.xql 10 Jul 2001 20:33:53 -0000 1.1 +++ openacs-4/packages/ecommerce/www/admin/orders/creditcard-add.xql 26 May 2002 04:36:50 -0000 1.2 @@ -1,11 +1,15 @@ - - - select zip_code from ec_addresses a, ec_orders o where a.address_id=o.shipping_address and order_id=:order_id - - - - + + + select c.billing_address, a.country_code + from ec_creditcards c, ec_orders o, ec_addresses a + where o.creditcard_id = c.creditcard_id + and a.address_id = c.billing_address + and o.order_id = :order_id + limit 1 + + + Index: openacs-4/packages/ecommerce/www/admin/orders/fulfill-2.tcl =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/ecommerce/www/admin/orders/fulfill-2.tcl,v diff -u -r1.4 -r1.5 --- openacs-4/packages/ecommerce/www/admin/orders/fulfill-2.tcl 29 Jan 2002 00:11:46 -0000 1.4 +++ openacs-4/packages/ecommerce/www/admin/orders/fulfill-2.tcl 26 May 2002 04:36:50 -0000 1.5 @@ -1,19 +1,20 @@ -# /www/[ec_url_concat [ec_url] /admin]/orders/fulfill-2.tcl ad_page_contract { - This script shows confirmation page & shipping address. + This script shows confirmation page & shipping address. - @author Eve Andersson (eveander@arsdigita.com) - @creation-date Summer 1999 - @cvs-id fulfill-2.tcl,v 3.5.2.6 2000/09/22 01:34:57 kevin Exp - @author ported by Jerry Asher (jerry@theashergroup.com) + @author Eve Andersson (eveander@arsdigita.com) + @creation-date Summer 1999 + @author ported by Jerry Asher (jerry@theashergroup.com) + @author revised by Bart Teeuwisse + @revision-date April 2002 + } { - order_id:integer,notnull - all_items_p:optional - item_id:multiple,optional,integer - shipment_date:array,date - shipment_time:array,time - expected_arrival_date:optional,array,date - expected_arrival_time:optional,array,time + order_id:integer,notnull + all_items_p:optional + item_id:multiple,optional,integer + shipment_date:array,date + shipment_time:array,time + expected_arrival_date:optional,array,date + expected_arrival_time:optional,array,time {carrier ""} {carrier_other ""} {tracking_number ""} @@ -23,14 +24,8 @@ ad_require_permission [ad_conn package_id] admin -# order_id, shipment_date (in pieces), -# either all_items_p or a series of item_ids +# The customer service rep must be logged on. -# if it's a shippable order: expected_arrival_date (in pieces), -# carrier, carrier_other, tracking_number, - -# the customer service rep must be logged on - ad_maybe_redirect_for_registration set customer_service_rep [ad_get_user_id] @@ -57,15 +52,11 @@ } } - set shippable_p [ec_decode [db_string shipping_method_select " -select shipping_method - from ec_orders - where order_id=:order_id -"] "no shipping" 0 1] - + select shipping_method + from ec_orders + where order_id=:order_id"] "no shipping" 0 1] if { $shippable_p } { - if { ![empty_string_p $carrier_other] } { set carrier $carrier_other } @@ -74,9 +65,9 @@ set exception_count 0 set exception_text "" -# they must have either checked "All items" and none of the rest, or -# at least one of the rest and not "All items" -# they also need to have shipment_date filled in +# Customer rep must have either checked "All items" and none of the +# rest, or at least one of the rest and not "All items". Shipment_date +# must be filled in too. if { [info exists all_items_p] && [info exists item_id] } { incr exception_count @@ -92,35 +83,28 @@ return } - append page_html "[ad_admin_header "Confirm that these item(s) have been [ec_decode $shippable_p 1 "shipped" "fulfilled"]"] -

    Confirm that these item(s) have been [ec_decode $shippable_p 1 "shipped" "fulfilled"]

    +

    Confirm that these item(s) have been [ec_decode $shippable_p 1 "shipped" "fulfilled"]

    -[ad_admin_context_bar [list "../" "Ecommerce([ec_system_name])"] [list "index" "Orders"] [list "fulfillment" "Fulfillment"] "One Order"] + [ad_admin_context_bar [list "../" "Ecommerce([ec_system_name])"] [list "index" "Orders"] [list "fulfillment" "Fulfillment"] "One Order"] +
    " -
    -" - set shipment_id [db_nextval ec_shipment_id_sequence] if { [info exists item_id] && ![empty_string_p item_id] } { - set sql "select i.item_id, p.product_name, p.one_line_description, p.product_id, i.price_charged, i.price_name, i.color_choice, i.size_choice, i.style_choice - from ec_items i, ec_products p - where i.product_id=p.product_id - and i.item_id in ([join $item_id ", "])" + set selected_items [join $item_id ", "] + set sql [db_map selected_items_select] } else { - set sql "select i.item_id, p.product_name, p.one_line_description, p.product_id, i.price_charged, i.price_name, i.color_choice, i.size_choice, i.style_choice - from ec_items i, ec_products p - where i.product_id=p.product_id - and i.order_id=:order_id - and i.item_state='to_be_shipped'" + set sql [db_map all_items_select] } -# If they select "All items", I want to generate a list of the items because, regardless -# of what happens elsewhere on the site (e.g. an item is added to the order, thereby causing -# the query for all items to return one more item), I want only the items that they confirm -# here to be recorded as part of this shipment. +# Generate a list of the items even if "All items" has been selected +# because, regardless of what happens elsewhere on the site (e.g. an +# item is added to the order, thereby causing the query for all items +# to return one more item), only the items that they confirm here to +# be recorded should become part of this shipment. + if { [info exists all_items_p] } { set item_id_list [list] } @@ -144,68 +128,57 @@ } set options [join $option_list ", "] - append items_to_print "
  • $product_name; [ec_decode $options "" "" "$options; "]$price_name: [ec_pretty_price $price_charged]" + append items_to_print "
  • $product_name; [ec_decode $options "" "" "$options; "]$price_name: [ec_pretty_price $price_charged]" } if { [info exists all_items_p] } { set item_id $item_id_list } -append page_html "
    -[export_form_vars shipment_id order_id item_id carrier tracking_number] - - +append page_html " + + [export_form_vars shipment_id order_id item_id carrier tracking_number] + + -
    - -
    -
    -Item(s): -
      -$items_to_print -
    -" +
    + +
    +
    + Item(s): +
      + $items_to_print +
    " if { !$shippable_p } { append page_html "Pickup date: [ec_formatted_date $temp_shipment_date]" } else { append page_html "Shipment information: +
      +
    • Shipment date: [ec_formatted_date $temp_shipment_date] + [ec_decode $temp_expected_arrival_date "" "" "
    • Expected arrival date: [ec_formatted_date $temp_expected_arrival_date]"] + [ec_decode $carrier "" "" "
    • Carrier: $carrier"] + [ec_decode $tracking_number "" "" "
    • Tracking Number: $tracking_number"] +
    • +
    -
      +

      Ship to:

      -
    • Shipment date: [ec_formatted_date $temp_shipment_date] - -[ec_decode $temp_expected_arrival_date "" "" "
    • Expected arrival date: [ec_formatted_date $temp_expected_arrival_date]"] - -[ec_decode $carrier "" "" "
    • Carrier: $carrier"] - -[ec_decode $tracking_number "" "" "
    • Tracking Number: $tracking_number"] - -
    - -Ship to: -
    - -
    - -[ec_display_as_html [ec_pretty_mailing_address_from_ec_addresses [db_string get_pretty_mailing_address "select shipping_address from ec_orders where order_id=:order_id"]]] - -
    -" +
    + [ec_display_as_html [ec_pretty_mailing_address_from_ec_addresses \ + [db_string get_pretty_mailing_address "select shipping_address from ec_orders where order_id=:order_id"]]] +
    " } append page_html " -
    +
    -
    - -
    -
    +
    + +
    + -[ad_admin_footer] -" -db_release_unused_handles + [ad_admin_footer]" +db_release_unused_handles doc_return 200 text/html $page_html - - Index: openacs-4/packages/ecommerce/www/admin/orders/fulfill-2.xql =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/ecommerce/www/admin/orders/fulfill-2.xql,v diff -u -r1.1 -r1.2 --- openacs-4/packages/ecommerce/www/admin/orders/fulfill-2.xql 10 Jul 2001 20:33:53 -0000 1.1 +++ openacs-4/packages/ecommerce/www/admin/orders/fulfill-2.xql 26 May 2002 04:36:50 -0000 1.2 @@ -1,22 +1,40 @@ - - - -select shipping_method - from ec_orders - where order_id=:order_id + + + select shipping_method + from ec_orders + where order_id=:order_id + + + + + + select i.item_id, p.product_name, p.one_line_description, p.product_id, i.price_charged, i.price_name, i.color_choice, i.size_choice, i.style_choice + from ec_items i, ec_products p + where i.product_id=p.product_id + and i.order_id=:order_id + and i.item_id in (:selected_items) + + - - + + + select i.item_id, p.product_name, p.one_line_description, p.product_id, i.price_charged, i.price_name, i.color_choice, i.size_choice, i.style_choice + from ec_items i, ec_products p + where i.product_id=p.product_id + and i.order_id=:order_id + and i.item_state='to_be_shipped' + + - - - - select shipping_address from ec_orders where order_id=:order_id - - - - + + + select shipping_address + from ec_orders + where order_id=:order_id + + + Index: openacs-4/packages/ecommerce/www/admin/orders/fulfill-3-oracle.xql =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/ecommerce/www/admin/orders/fulfill-3-oracle.xql,v diff -u -r1.2 -r1.3 --- openacs-4/packages/ecommerce/www/admin/orders/fulfill-3-oracle.xql 29 Jan 2002 00:11:46 -0000 1.2 +++ openacs-4/packages/ecommerce/www/admin/orders/fulfill-3-oracle.xql 26 May 2002 04:36:50 -0000 1.3 @@ -1,23 +1,31 @@ - oracle8.1.6 + + oracle + 8.1.6 + - select nvl(sum(price_charged),0) from ec_items where item_id in ([join $item_id_vars ", "]) + select nvl(sum(price_charged),0) + from ec_items + where item_id in ([join $item_id_list ", "]) - select nvl(sum(shipping_charged),0) from ec_items where item_id in ([join $item_id_vars ", "]) + select nvl(sum(shipping_charged),0) + from ec_items + where item_id in ([join $item_id_list ", "]) - select ec_tax(:total_price_of_items, :total_shipping_of_items, :order_id) from dual + select ec_tax(:total_price_of_items, :total_shipping_of_items, :order_id) + from dual @@ -32,19 +40,27 @@ - select ec_shipment_cost(:shipment_id) from dual + select ec_shipment_cost(:shipment_id) + from dual - + - select ec_order_cost(:order_id) from dual + select nvl(sum(i.price_charged),0) - nvl(sum(i.price_refunded),0) + 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' - update ec_financial_transactions set shipment_id=:shipment_id, to_be_captured_p='t', to_be_captured_date=sysdate where transaction_id=:transaction_id + update ec_financial_transactions + set shipment_id=:shipment_id, to_be_captured_p='t', to_be_captured_date=sysdate + where transaction_id=:transaction_id @@ -68,7 +84,9 @@ - update ec_financial_transactions set marked_date=sysdate where transaction_id=:transaction_id + update ec_financial_transactions + set marked_date=sysdate + where transaction_id=:pgw_transaction_id @@ -83,7 +101,9 @@ - update ec_financial_transactions set authorized_date=sysdate where transaction_id=:transaction_id + update ec_financial_transactions + set authorized_date=sysdate + where transaction_id=:pgw_transaction_id @@ -96,10 +116,4 @@ - - - update ec_financial_transactions set marked_date=sysdate where transaction_id=:transaction_id - - - Index: openacs-4/packages/ecommerce/www/admin/orders/fulfill-3-postgresql.xql =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/ecommerce/www/admin/orders/fulfill-3-postgresql.xql,v diff -u -r1.2 -r1.3 --- openacs-4/packages/ecommerce/www/admin/orders/fulfill-3-postgresql.xql 29 Jan 2002 00:11:46 -0000 1.2 +++ openacs-4/packages/ecommerce/www/admin/orders/fulfill-3-postgresql.xql 26 May 2002 04:36:50 -0000 1.3 @@ -1,8 +1,27 @@ - postgresql7.1 + + postgresql + 7.1 + + + + select coalesce(sum(price_charged),0) + from ec_items + where item_id in ([join $item_id_list ", "]) + + + + + + select coalesce(sum(shipping_charged),0) + from ec_items + where item_id in ([join $item_id_list ", "]) + + + select ec_tax(:total_price_of_items, :total_shipping_of_items, :order_id) @@ -14,7 +33,8 @@ insert into ec_shipments (shipment_id, order_id, shipment_date, expected_arrival_date, carrier, tracking_number, shippable_p, last_modified, last_modifying_user, modified_ip_address) values - (:shipment_id, :order_id, to_date(:shipment_date, 'YYYY-MM-DD HH12:MI:SSAM'), to_date(:expected_arrival_date, 'YYYY-MM-DD HH12:MI:SSAM'), :carrier, :tracking_number, :shippable_p_tf, current_timestamp, :customer_service_rep, :peeraddr) + (:shipment_id, :order_id, to_date(:shipment_date, 'YYYY-MM-DD HH12:MI:SSAM'), to_date(:expected_arrival_date, 'YYYY-MM-DD HH12:MI:SSAM'), + :carrier, :tracking_number, :shippable_p_tf, current_timestamp, :customer_service_rep, :peeraddr) @@ -26,13 +46,20 @@ - select ec_order_cost(:order_id) + select coalesce(sum(i.price_charged),0) - coalesce(sum(i.price_refunded),0) + 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' - update ec_financial_transactions set shipment_id=:shipment_id, to_be_captured_p='t', to_be_captured_date=current_timestamp where transaction_id=:transaction_id + update ec_financial_transactions + set shipment_id=:shipment_id, to_be_captured_p='t', to_be_captured_date=current_timestamp + where transaction_id=:transaction_id @@ -51,19 +78,22 @@ (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=:transaction_id + update ec_financial_transactions + set marked_date = current_timestamp + where transaction_id=:pgw_transaction_id - + - update ec_financial_transactions set authorized_date=current_timestamp where transaction_id=:transaction_id + update ec_financial_transactions + set authorized_date=current_timestamp + where transaction_id=:pgw_transaction_id @@ -76,10 +106,4 @@ - - - update ec_financial_transactions set marked_date=current_timestamp where transaction_id=:transaction_id - - - Index: openacs-4/packages/ecommerce/www/admin/orders/fulfill-3.tcl =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/ecommerce/www/admin/orders/fulfill-3.tcl,v diff -u -r1.3 -r1.4 --- openacs-4/packages/ecommerce/www/admin/orders/fulfill-3.tcl 31 Jan 2002 22:43:54 -0000 1.3 +++ openacs-4/packages/ecommerce/www/admin/orders/fulfill-3.tcl 26 May 2002 04:36:50 -0000 1.4 @@ -1,10 +1,12 @@ -# /www/[ec_url_concat [ec_url] /admin]/orders/fulfill-3.tcl ad_page_contract { @author Eve Andersson (eveander@arsdigita.com) @creation-date Summer 1999 - @cvs-id fulfill-3.tcl,v 3.4.2.6 2000/08/18 21:46:57 stevenp Exp @author ported by Jerry Asher (jerry@theashergroup.com) + + @author revised by Bart Teeuwisse + @revision-date April 2002 + } { shipment_id:integer,notnull order_id:integer,notnull @@ -20,54 +22,52 @@ set item_id_list $item_id - -# We have to: # 1. Add a row to ec_shipments. + # 2. Update item_state and shipment_id in ec_items. -# 3. Compute how much we need to charge the customer -# (a) If the total amount is the same as the amount previously calculated -# for the entire order, then update to_be_captured_p and to_be_captured_date -# in ec_financial_transactions and try to mark the transaction* + +# 3. Compute how much to charge the customer. The shipment can be a +# pratial shipment, products can have been added to or removed from +# the order after the original order was approved + +# (a) If the total amount is the same as the amount previously +# calculated for the entire order, then update to_be_captured_p +# and to_be_captured_date in ec_financial_transactions and try +# to mark the transaction* + # (b) If the total amount is different and greater than 0: -# I. add a row to ec_financial_transactions with -# to_be_captured_p and to_be_captured_date set -# II. do a new authorization* +# I. add a row to ec_financial_transactions with +# to_be_captured_p and to_be_captured_date set +# II. do a new authorization* # III. mark transaction* -# * I was debating with myself whether it really makes sense to do the CyberCash -# transactions on this page since, by updating to_be_captured_* in -# ec_financial_transactions, a cron job can easily come around later and -# see what needs to be done. -# Pros: (1) instant feedback, if desired, if the transaction fails, which means the -# shipment can possibly be aborted -# (2) if it were done via a cron job, the cron job would need to query CyberCash -# first to see if CyberCash had a record for the transaction before it could -# try to auth/mark it (in case we had attempted the transaction before an got -# an inconclusive result), whereas on this page there's no need to query first -# (you know CyberCash doesn't have a record for it). CyberCash charges 20 -# cents per transaction, although I don't actually know if a query is considered -# a transaction. -# Cons: it slows things down for the person recording shipments +# The customer service rep must be logged on -# I guess I'll just do the transactions on this page, for now, and if they prove too -# slow they can be taken out without terrible consequences (the cron job has to run -# anyway in case the results here are inconclusive). - -# the customer service rep must be logged on ad_maybe_redirect_for_registration set customer_service_rep [ad_verify_and_get_user_id] -# doubleclick protection -if { [db_string doubleclick_select "select count(*) from ec_shipments where shipment_id=:shipment_id"] > 0 } { +# Doubleclick protection + +if { [db_string doubleclick_select " + select count(*) + from ec_shipments + where shipment_id=:shipment_id"] > 0 } { ad_returnredirect "fulfillment" return } -set shipping_method [db_string shipping_method_select "select shipping_method from ec_orders where order_id=:order_id"] +set shipping_method [db_string shipping_method_select " + select shipping_method + from ec_orders + where order_id=:order_id"] -set shippable_p [ec_decode [db_string shippable_p_select "select shipping_method from ec_orders where order_id=:order_id"] "no shipping" 0 1] +set shippable_p [ec_decode [db_string shippable_p_select " + select shipping_method + from ec_orders + where order_id=:order_id"] "no shipping" 0 1] -# 0. Calculate shipment tax charged. +# 0. Calculate shipment tax charged. Start by calculating the shipping +# cost. set item_id_vars [list] foreach item_id $item_id_list { @@ -76,152 +76,256 @@ lappend item_id_vars ":$var_name" } -set total_price_of_items [db_string total_price_of_items_select "select nvl(sum(price_charged),0) from ec_items where item_id in ([join $item_id_vars ", "])"] +set total_price_of_items [db_string total_price_of_items_select " + select nvl(sum(price_charged),0) + from ec_items + where item_id in ([join $item_id_list ", "])"] +# Calculate the total shipping cost of the shipment. + if { $shippable_p } { - # see if base shipping cost should be included in total_shipping_of_items - set n_shipments_already [db_string n_shipments_already_select "select count(*) from ec_shipments where order_id=:order_id"] + + # See if base shipping cost should be included in + # total_shipping_of_items + + set n_shipments_already [db_string n_shipments_already_select " + select count(*) + from ec_shipments + where order_id=:order_id"] - set shipping_of_items [db_string shipping_of_items_select "select nvl(sum(shipping_charged),0) from ec_items where item_id in ([join $item_id_vars ", "])"] - + set shipping_of_items [db_string shipping_of_items_select " + select nvl(sum(shipping_charged),0) + from ec_items + where item_id in ([join $item_id_list ", "])"] + if { $n_shipments_already == 0 } { - set total_shipping_of_items [db_string total_shipping_of_items_select "select $shipping_of_items + shipping_charged from ec_orders where order_id=:order_id"] + set total_shipping_of_items [db_string total_shipping_of_items_select " + select $shipping_of_items + shipping_charged + from ec_orders + where order_id=:order_id"] } else { set total_shipping_of_items $shipping_of_items } } else { - # it's a pickup order + + # It's a pickup order + set total_shipping_of_items 0 set expected_arrival_date "" set carrier "" set tracking_number "" } -set total_tax_of_items [db_string total_tax_of_items_select "select ec_tax(:total_price_of_items, :total_shipping_of_items, :order_id) from dual"] +set total_tax_of_items [db_string total_tax_of_items_select " + select ec_tax(:total_price_of_items, :total_shipping_of_items, :order_id) + from dual"] set peeraddr [ns_conn peeraddr] set shippable_p_tf [ec_decode $shippable_p 0 f t] -db_transaction { - db_dml insert_shipment_info "insert into ec_shipments - (shipment_id, order_id, shipment_date, expected_arrival_date, carrier, tracking_number, shippable_p, last_modified, last_modifying_user, modified_ip_address) - values - (:shipment_id, :order_id, to_date(:shipment_date, 'YYYY-MM-DD HH12:MI:SSAM'), to_date(:expected_arrival_date, 'YYYY-MM-DD HH12:MI:SSAM'), :carrier, :tracking_number, :shippable_p_tf, sysdate, :customer_service_rep, :peeraddr) - " +db_dml insert_shipment_info " + insert into ec_shipments + (shipment_id, order_id, shipment_date, expected_arrival_date, carrier, tracking_number, shippable_p, last_modified, last_modifying_user, modified_ip_address) + values + (:shipment_id, :order_id, to_date(:shipment_date, 'YYYY-MM-DD HH12:MI:SSAM'), + to_date(:expected_arrival_date, 'YYYY-MM-DD HH12:MI:SSAM'), :carrier, :tracking_number, :shippable_p_tf, sysdate, :customer_service_rep, :peeraddr)" - db_dml item_state_update " - update ec_items - set item_state='shipped', shipment_id=:shipment_id - where item_id in ([join $item_id_vars ", "]) - " +db_dml item_state_update " + update ec_items + set item_state='shipped', shipment_id=:shipment_id + where item_id in ([join $item_id_list ", "])" - # calculate the total shipment cost (price + shipping + tax - gift certificate) of the shipment - set shipment_cost [db_string shipment_cost_select "select ec_shipment_cost(:shipment_id) from dual"] +# Calculate the total shipment cost (price + shipping + tax - gift +# certificate) of the shipment - # calculate the total order cost (price + shipping + tax - gift_certificate) so we'll - # know if we can use the original transaction - set order_cost [db_string order_cost_select "select ec_order_cost(:order_id) from dual"] +set shipment_cost [db_string shipment_cost_select " + select ec_shipment_cost(:shipment_id) + from dual"] - # It is conceivable, albeit unlikely, that a partial shipment, - # return, and an addition of more items to the order by the site - # administrator can make the order_cost equal the shipment_cost - # even if it isn't the first shipment, which is fine. But if - # this happens twice, this would have caused the system (which is - # trying to minimize financial transactions) to try to reuse an old - # transaction, which will fail, so I've added the 2nd half of the - # "if statement" below to make sure that transaction doesn't get reused: +# No financial transactions need to be update when the shipment is +# for free. - if { $shipment_cost == $order_cost && [db_string to_be_captured_p_select "select count(*) from ec_financial_transactions where order_id=:order_id and to_be_captured_p='t'"] == 0} { - set transaction_id [db_string transaction_id_select "select max(transaction_id) from ec_financial_transactions where order_id=:order_id"] - # 1999-08-11: added shipment_id to the update - - # 1999-08-29: put the update inside an if statement in case there is - # no transaction to update - if { ![empty_string_p $transaction_id] } { - db_dml transaction_update "update ec_financial_transactions set shipment_id=:shipment_id, to_be_captured_p='t', to_be_captured_date=sysdate where transaction_id=:transaction_id" - } +if { $shipment_cost >= 0 } { - # try to mark the transaction - # 1999-08-29: put the marking inside an if statement in case there is - # no transaction to update - if { ![empty_string_p $transaction_id] } { + # Calculate the total order cost (price + shipping + tax - + # gift_certificate) so we'll know if we can use the original + # transaction - set cc_mark_result [ec_creditcard_marking $transaction_id] - if { $cc_mark_result == "invalid_input" } { - set problem_details "When trying to mark shipment $shipment_id (transaction $transaction_id) at [ad_conn url], the following result occurred: $cc_mark_result" - db_dml problems_log_insert "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 { $cc_mark_result == "success" } { - db_dml transaction_success_update "update ec_financial_transactions set marked_date=sysdate where transaction_id=:transaction_id" + set hard_goods_total_cost [db_string hard_goods_cost_select " + select coalesce(sum(i.price_charged),0) - coalesce(sum(i.price_refunded),0) + + coalesce(sum(i.price_tax_charged),0) - coalesce(sum(i.shipping_refunded),0) + + coalesce(sum(i.shipping_charged),0) - coalesce(sum(i.shipping_refunded),0) + + coalesce(sum(i.shipping_tax_charged),0) - coalesce(sum(i.shipping_tax_refunded),0) + 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)"] + set order_cost [expr $hard_goods_total_cost + $order_shipping + $order_shipping_tax] + + # Verify that the shipment is for the entire order. + + if {$shipment_cost == $order_cost} { + + # The shipment could be for the entire order but it could also + # be that a partial shipment, return, and an addition of more + # items to the order by the site administrator maked the + # order_cost equal the shipment_cost. + + # Get the amount that was authorized when the user placed the + # order. It could be that the customer instructed the + # administrator to add items to or remove items from the + # order. The transaction can only be marked for settlement if + # the shipment cost equals the authorized amount. + + # Bart Teeuwisse: Many (all?) credit card gateways can settle + # a lower amount than the amount authorized but the ecommerce + # package is designed to always settle the authorized + # amount. ec_financial_transactions only stores 1 transaction + # amount and can thus not differentiate between the amount + # authorized and the amount to capture. + + if {[string equal $shipment_cost [db_string authorized_amount_select " + select transaction_amount + from ec_financial_transactions + where order_id = :order_id + and to_be_captured_p is null + and transaction_type = 'charge'" -default ""]]} { + + set transaction_id [db_string transaction_id_select " + select transaction_id + from ec_financial_transactions + where order_id = :order_id + and to_be_captured_p is null + and transaction_type = 'charge'" -default ""] + + if { ![empty_string_p $transaction_id] } { + db_dml transaction_update " + update ec_financial_transactions + set shipment_id=:shipment_id, to_be_captured_p='t', to_be_captured_date=sysdate + where transaction_id=:transaction_id" + + # 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 shipment $shipment_id (transaction $transaction_id) at [ad_conn url], the following result occurred: $mark_result" + db_dml problems_log_insert " + 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 transaction_success_update " + update ec_financial_transactions + set marked_date=sysdate + where transaction_id = :pgw_transaction_id" + } + + # Flag that no new transactions need to be + # created for this shipment. + + set create_new_transaction false } + } else { + + # The shipment is a partial shipment but the + # shipment cost equals the order cost. + + set create_new_transaction false } } else { - if { $shipment_cost >= 0 } { - # 1. add a row to ec_financial_transactions with to_be_captured_p and to_be_captured_date set - # 2. do a new authorization - # 3. mark transaction - - # Note: 1 is the only one we want to do inside the transaction; if 2 & 3 fail, they will be - # tried later with a cron job (they involve talking to CyberCash, so you never know what will - # happen with them) - - # Get id for the new transaction. - set transaction_id [db_nextval ec_transaction_id_sequence] - # 1999-08-11: added shipment_id to the insert - - db_dml transaction_insert "insert into ec_financial_transactions - (transaction_id, order_id, shipment_id, transaction_amount, transaction_type, to_be_captured_p, inserted_date, to_be_captured_date) - values - (:transaction_id, :order_id, :shipment_id, :shipment_cost, 'charge','t',sysdate, sysdate) - " + set create_new_transaction true + } - # CyberCash stuff - # this attempts an auth and returns failed_authorization, authorized_plus_avs, authorized_minus_avs, no_recommendation, or invalid_input - set cc_result [ec_creditcard_authorization $order_id $transaction_id] - if { $cc_result == "failed_authorization" || $cc_result == "invalid_input" } { - set problem_details "When trying to authorize shipment $shipment_id (transaction $transaction_id) at [ad_conn url], the following result occurred: $cc_result" - db_dml problems_insert " - insert into ec_problems_log - (problem_id, problem_date, problem_details, order_id) - values - (ec_problem_id_sequence.nextval, sysdate, :problem_details, :order_id) - " + # Create new financial transactions as needed and process them. - if { [ad_parameter -package_id [ec_id] DisplayTransactionMessagesDuringFulfillmentP ecommerce] } { - ad_return_warning "Credit Card Failure" "Warning: the credit card authorization for this shipment (shipment_id $shipment_id) of order_id $order_id failed. You may wish to abort the shipment (if possible) until this is issue is resolved. A note has been made in the problems log.

    Continue with order fulfillment." - return - } - if { $cc_result == "failed_p" } { - db_dml transaction_failed_update "update ec_financial_transactions set failed_p='t' where transaction_id=:transaction_id" - } - } elseif { $cc_result == "authorized_plus_avs" || $cc_result == "authorized_minus_avs" } { - # put authorized_date into ec_financial_transacions - db_dml transaction_authorized_udpate "update ec_financial_transactions set authorized_date=sysdate where transaction_id=:transaction_id" - # try to mark the transaction - set cc_mark_result [ec_creditcard_marking $transaction_id] - ns_log Notice "fulfill-3.tcl: cc_mark_result is $cc_mark_result" - if { $cc_mark_result == "invalid_input" } { - set problem_details "When trying to mark shipment $shipment_id (transaction $transaction_id) at [ad_conn url], the following result occurred: $cc_mark_result" - db_dml problems_insert "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 { $cc_mark_result == "success" } { - db_dml transaction_success_update "update ec_financial_transactions set marked_date=sysdate where transaction_id=:transaction_id" - } + if { $create_new_transaction } { + + # 1. add a row to ec_financial_transactions with + # to_be_captured_p and to_be_captured_date set + # 2. do a new authorization + # 3. mark transaction + + # Get id for the new transaction. + + set transaction_id [db_nextval ec_transaction_id_sequence] + db_dml transaction_insert " + insert into ec_financial_transactions + (transaction_id, order_id, shipment_id, transaction_amount, transaction_type, to_be_captured_p, inserted_date, to_be_captured_date) + values + (:transaction_id, :order_id, :shipment_id, :shipment_cost, 'charge', 't', sysdate, sysdate)" + + # Authorize the transaction, ec_creditcard_authorization + # returns failed_authorization, authorized, + # no_recommendation, or invalid_input. + + array set response [ec_creditcard_authorization $order_id $transaction_id] + set result $response(response_code) + set pgw_transaction_id $response(transaction_id) + if {[string equal $result "failed_authorization"] || [string equal $result "invalid_input"]} { + set problem_details "When trying to authorize shipment $shipment_id (transaction $transaction_id) at [ad_conn url], the following result occurred: $result" + db_dml problems_insert " + insert into ec_problems_log + (problem_id, problem_date, problem_details, order_id) + values + (ec_problem_id_sequence.nextval, sysdate, :problem_details, :order_id)" + + if { [ad_parameter -package_id [ec_id] DisplayTransactionMessagesDuringFulfillmentP ecommerce] } { + ad_return_warning "Credit Card Failure" " +

    Warning: the credit card authorization for this shipment (shipment_id $shipment_id) of order_id $order_id failed.

    +

    You may wish to abort the shipment (if possible) until this is issue is resolved. A note has been made in the problems log.

    +

    Continue with order fulfillment.

    " + return } + if {[string equal $result "failed_p"]} { + db_dml transaction_failed_update " + update ec_financial_transactions + set failed_p='t' + where transaction_id=:transaction_id" + } + } elseif {[string equal $result "authorized"]} { + + # Put authorized_date into ec_financial_transacions. + + db_dml transaction_authorized_update " + update ec_financial_transactions + set authorized_date=sysdate + where transaction_id=:pgw_transaction_id" + + # Mark the transaction. + + array set response [ec_creditcard_marking $pgw_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 shipment $shipment_id (transaction $transaction_id) at [ad_conn url], the following result occurred: $mark_result" + db_dml problems_insert " + 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 transaction_success_update " + update ec_financial_transactions + set marked_date = sysdate + where transaction_id=:pgw_transaction_id" + } } } } -# send the "Order Shipped" email iff it was a shippable order +# Send the "Order Shipped" email if it was a shippable order if { $shippable_p } { ec_email_order_shipped $shipment_id } - ad_returnredirect "fulfillment" Index: openacs-4/packages/ecommerce/www/admin/orders/fulfill-3.xql =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/ecommerce/www/admin/orders/fulfill-3.xql,v diff -u -r1.2 -r1.3 --- openacs-4/packages/ecommerce/www/admin/orders/fulfill-3.xql 22 Jul 2001 07:04:48 -0000 1.2 +++ openacs-4/packages/ecommerce/www/admin/orders/fulfill-3.xql 26 May 2002 04:36:50 -0000 1.3 @@ -1,92 +1,96 @@ - - - select count(*) from ec_shipments where shipment_id=:shipment_id - - + + + select count(*) + from ec_shipments + where shipment_id=:shipment_id + + - - - - select shipping_method from ec_orders where order_id=:order_id - - + + + select shipping_method + from ec_orders + where order_id=:order_id + + - - - - select shipping_method from ec_orders where order_id=:order_id - - - - - - - select coalesce(sum(price_charged),0) from ec_items where item_id in ([join $item_id_vars ", "]) - - - - - - - select count(*) from ec_shipments where order_id=:order_id - - - - - - - select coalesce(sum(shipping_charged),0) from ec_items where item_id in ([join $item_id_vars ", "]) - - - - - - - select ${shipping_of_items}::numeric + shipping_charged from ec_orders where order_id=:order_id - - - - - - - - update ec_items - set item_state='shipped', shipment_id=:shipment_id - where item_id in ([join $item_id_vars ", "]) + + + select shipping_method + from ec_orders + where order_id=:order_id + + - - + + + select coalesce(sum(price_charged),0) + from ec_items + where item_id in ([join $item_id_list ", "]) + + + + + + select count(*) + from ec_shipments + where order_id=:order_id + + + + + + select coalesce(sum(shipping_charged),0) + from ec_items + where item_id in ([join $item_id_list ", "]) + + + + + + select ${shipping_of_items}::numeric + shipping_charged + from ec_orders + where order_id=:order_id + + + + + + update ec_items + set item_state='shipped', shipment_id=:shipment_id + where item_id in ([join $item_id_list ", "]) + + - - - - select count(*) from ec_financial_transactions where order_id=:order_id and to_be_captured_p='t' - - - - - - - select max(transaction_id) from ec_financial_transactions where order_id=:order_id - - - - - - - select max(transaction_id) from ec_financial_transactions where order_id=:order_id - - - - - - - update ec_financial_transactions set failed_p='t' where transaction_id=:transaction_id - - - - + + + select transaction_amount + from ec_financial_transactions + where order_id = :order_id + and to_be_captured_p is null + and transaction_type = 'charge' + + + + + + select transaction_id + from ec_financial_transactions + where order_id=:order_id + and to_be_captured_p is null + and transaction_type = 'charge' + + + + + + update ec_financial_transactions + set failed_p='t' + where transaction_id=:transaction_id + + + Index: openacs-4/packages/ecommerce/www/admin/orders/gift-certificates-issued.tcl =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/ecommerce/www/admin/orders/gift-certificates-issued.tcl,v diff -u -r1.2 -r1.3 --- openacs-4/packages/ecommerce/www/admin/orders/gift-certificates-issued.tcl 23 Jul 2001 05:56:22 -0000 1.2 +++ openacs-4/packages/ecommerce/www/admin/orders/gift-certificates-issued.tcl 26 May 2002 04:36:50 -0000 1.3 @@ -1,58 +1,60 @@ -# /www/[ec_url_concat [ec_url] /admin]/orders/gift-certificates-issued.tcl ad_page_contract { - View gift certificates issued. + View gift certificates issued. - @author Eve Andersson (eveander@arsdigita.com) - @creation-date Summer 1999 - @cvs-id gift-certificates-issued.tcl,v 3.2.2.3 2000/08/16 21:07:10 seb Exp - @author ported by Jerry Asher (jerry@theashergroup.com) + @author Eve Andersson (eveander@arsdigita.com) + @creation-date Summer 1999 + @author ported by Jerry Asher (jerry@theashergroup.com) + @author revised by Bart Teeuwisse + @revision-date April 2002 + } { - {view_rep "all"} - {view_issue_date "all"} - {order_by "gift_certificate_id"} + {view_rep "all"} + {view_issue_date "last_24"} + {order_by "gift_certificate_id"} } ad_require_permission [ad_conn package_id] admin -doc_body_append "[ad_admin_header "Gift Certificate Issue History"] +doc_body_append " + [ad_admin_header "Gift Certificate Issue History"] -

    Gift Certificate Issue History

    +

    Gift Certificate Issue History

    -[ad_admin_context_bar [list "../" "Ecommerce([ec_system_name])"] [list "index" "Orders"] "Gift Certificate Issue History"] + [ad_admin_context_bar [list "../" "Ecommerce([ec_system_name])"] [list "index" "Orders"] "Gift Certificate Issue History"] -
    +
    -
    -[export_form_vars view_issue_date order_by] + + [export_form_vars view_issue_date order_by] - - - - - - -
    RepIssue Date
    + + + + + + - + + +
    RepIssue Date
    + - - -" +doc_body_append " + + + " set issue_date_list [list [list last_24 "last 24 hrs"] [list last_week "last week"] [list last_month "last month"] [list all all]] @@ -66,22 +68,19 @@ } } -doc_body_append "\[ [join $linked_issue_date_list " | "] \] +doc_body_append " + \[ [join $linked_issue_date_list " | "] \] +
    + +
    " -
    - - -
    -" - if { $view_issue_date == "last_24" } { - #set issue_date_query_bit "and sysdate-g.issue_date <= 1" set issue_date_query_bit [db_map last_24] } elseif { $view_issue_date == "last_week" } { - #set issue_date_query_bit "and sysdate-g.issue_date <= 7" set issue_date_query_bit [db_map last_week] } elseif { $view_issue_date == "last_month" } { - #set issue_date_query_bit "and months_between(sysdate,g.issue_date) <= 1" set issue_date_query_bit [db_map last_month] } else { set issue_date_query_bit "" @@ -95,33 +94,34 @@ set link_beginning "gift-certificates-issued?[export_url_vars view_rep view_issue_date]" -set order_by_clause [util_decode $order_by \ - "gift_certificate_id" "g.gift_certificate_id" \ - "issue_date" "g.issue_date" \ - "issued_by" "u.last_name, u.first_names" \ - "recipient" "r.last_name, r.first_names" \ - "amount" "g.amount"] +set order_by_clause [ec_decode $order_by \ + "gift_certificate_id" "g.gift_certificate_id" \ + "issue_date" "g.issue_date" \ + "issued_by" "u.last_name, u.first_names" \ + "recipient" "r.last_name, r.first_names" \ + "amount" "g.amount"] -set table_header " - - - - - - -" +set table_header " +
    IDDate IssuedIssued ByRecipientAmount
    + + + + + + + " set row_counter 0 db_foreach gift_certificates_select " -SELECT g.gift_certificate_id, g.issue_date, g.amount, + select g.gift_certificate_id, g.issue_date, g.amount, g.issued_by, u.first_names, u.last_name, g.user_id as issued_to, r.first_names as issued_to_first_names, r.last_name as issued_to_last_name -from ec_gift_certificates_issued g, cc_users u, cc_users r -where g.issued_by=u.user_id and g.user_id=r.user_id -$issue_date_query_bit $rep_query_bit -order by $order_by_clause -" { + from ec_gift_certificates_issued g, cc_users u, cc_users r + where g.issued_by=u.user_id and g.user_id=r.user_id + $issue_date_query_bit $rep_query_bit + order by $order_by_clause" { + if { $row_counter == 0 } { doc_body_append $table_header } @@ -131,13 +131,13 @@ } else { set bgcolor "ececec" } - doc_body_append " - - - - - - " + doc_body_append " + + + + + + " incr row_counter } @@ -147,7 +147,7 @@ doc_body_append "
    None Found
    " } -doc_body_append " +doc_body_append " + -[ad_admin_footer] -" + [ad_admin_footer]" Index: openacs-4/packages/ecommerce/www/admin/orders/gift-certificates.tcl =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/ecommerce/www/admin/orders/gift-certificates.tcl,v diff -u -r1.2 -r1.3 --- openacs-4/packages/ecommerce/www/admin/orders/gift-certificates.tcl 23 Jul 2001 05:50:06 -0000 1.2 +++ openacs-4/packages/ecommerce/www/admin/orders/gift-certificates.tcl 26 May 2002 04:36:50 -0000 1.3 @@ -1,41 +1,45 @@ -# /www/[ec_url_concat [ec_url] /admin]/orders/gift-certificates.tcl ad_page_contract { - View gift certificates. + View gift certificates. - @author Eve Andersson (eveander@arsdigita.com) - @creation-date Summer 1999 - @cvs-id gift-certificates.tcl,v 3.2.2.3 2000/08/16 21:07:10 seb Exp - @author ported by Jerry Asher (jerry@theashergroup.com) + @author Eve Andersson (eveander@arsdigita.com) + @creation-date Summer 1999 + @author ported by Jerry Asher (jerry@theashergroup.com) + @author revised by Bart Teeuwisse + @revision-date March 2002 + } { - {view_gift_certificate_state "reportable"} - {view_issue_date "all"} - {order_by "gift_certificate_id"} + {view_gift_certificate_state "reportable"} + {view_issue_date "last_24"} + {order_by "gift_certificate_id"} } ad_require_permission [ad_conn package_id] admin -doc_body_append "[ad_admin_header "Gift Certificate Purchase History"] +doc_body_append " + [ad_admin_header "Gift Certificate Purchase History"] -

    Gift Certificate Purchase History

    +

    Gift Certificate Purchase History

    -[ad_admin_context_bar [list "../" "Ecommerce([ec_system_name])"] [list "index" "Orders"] "Gift Certificate Purchase History"] + [ad_admin_context_bar [list "../" "Ecommerce([ec_system_name])"] [list "index" "Orders"] "Gift Certificate Purchase History"] -
    +
    -
    -[export_form_vars view_issue_date order_by] + + [export_form_vars view_issue_date order_by] -
    IDDate IssuedIssued ByRecipientAmount
    $gift_certificate_id[ec_nbsp_if_null [util_AnsiDatetoPrettyDate $issue_date]][ec_decode $last_name "" " " "$last_name, $first_names"][ec_decode $last_name "" " " "$issued_to_last_name, $issued_to_first_names"][ec_pretty_price $amount]
    $gift_certificate_id[ec_nbsp_if_null [util_AnsiDatetoPrettyDate $issue_date]][ec_decode $last_name "" " " "$last_name, $first_names"][ec_decode $last_name "" " " "$issued_to_last_name, $issued_to_first_names"][ec_pretty_price $amount]
    - - - - - -
    Gift Certificate StateIssue Date
    + + + + + + - + + +
    Gift Certificate StateIssue Date
    - - -" +doc_body_append " + + + " set issue_date_list [list [list last_24 "last 24 hrs"] [list last_week "last week"] [list last_month "last month"] [list all all]] @@ -63,79 +67,74 @@ } } -doc_body_append "\[ [join $linked_issue_date_list " | "] \] +doc_body_append " + \[ [join $linked_issue_date_list " | "] \] +
    + +
    " -
    +set gift_certificate_state_query_bit "and g.gift_certificate_state=:view_gift_certificate_state" - -
    -" - -if { $view_gift_certificate_state == "reportable" } { - set gift_certificate_state_query_bit "and g.gift_certificate_state in ('authorized_plus_avs','authorized_minus_avs')" -} else { - set gift_certificate_state_query_bit "and g.gift_certificate_state=:view_gift_certificate_state" -} - if { $view_issue_date == "last_24" } { - #set issue_date_query_bit "and sysdate-g.issue_date <= 1" set issue_date_query_bit [db_map last_24] } elseif { $view_issue_date == "last_week" } { - #set issue_date_query_bit "and sysdate-g.issue_date <= 7" set issue_date_query_bit [db_map last_week] } elseif { $view_issue_date == "last_month" } { - #set issue_date_query_bit "and months_between(sysdate,g.issue_date) <= 1" set issue_date_query_bit [db_map last_month] } else { set issue_date_query_bit "" } set link_beginning "gift-certificates?[export_url_vars view_gift_certificate_state view_issue_date]" -set order_by_clause [util_decode $order_by \ - "gift_certificate_id" "g.gift_certificate_id" \ - "issue_date" "g.issue_date" \ - "gift_certificate_state" "g.gift_certificate_state" \ - "name" "u.last_name, u.first_names" \ - "recipient_email" "g.recipient_email" \ - "amount" "g.amount"] +set order_by_clause [ec_decode $order_by \ + "gift_certificate_id" "g.gift_certificate_id" \ + "issue_date" "g.issue_date" \ + "gift_certificate_state" "g.gift_certificate_state" \ + "name" "u.last_name, u.first_names" \ + "recipient_email" "g.recipient_email" \ + "amount" "g.amount"] -set table_header " - - - - - - - -" +set table_header " +
    IDDate IssuedGift Certificate StatePurchased ByRecipientAmount
    + + + + + + + + " - - set row_counter 0 -db_foreach gift_certificates_select "select g.gift_certificate_id, g.issue_date, g.gift_certificate_state, g.recipient_email, g.purchased_by, g.amount, u.first_names, u.last_name -from ec_gift_certificates g, cc_users u -where g.purchased_by=u.user_id -$issue_date_query_bit $gift_certificate_state_query_bit -order by $order_by_clause -" { +db_foreach gift_certificates_select " + select g.gift_certificate_id, g.issue_date, g.gift_certificate_state, g.recipient_email, g.purchased_by, g.amount, u.first_names, u.last_name + from ec_gift_certificates g, cc_users u + where g.purchased_by=u.user_id + $issue_date_query_bit $gift_certificate_state_query_bit + order by $order_by_clause" { + if { $row_counter == 0 } { - doc_body_append $table_header + doc_body_append $table_header } - # even rows are white, odd are grey + + # Even rows are white, odd are grey + if { [expr floor($row_counter/2.)] == [expr $row_counter/2.] } { set bgcolor "white" } else { set bgcolor "ececec" } - doc_body_append " - - - - - - - " + doc_body_append " + + + + + + + " incr row_counter } @@ -145,7 +144,7 @@ doc_body_append "
    None Found
    " } -doc_body_append " +doc_body_append " + -[ad_admin_footer] -" + [ad_admin_footer]" Index: openacs-4/packages/ecommerce/www/admin/orders/index.tcl =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/ecommerce/www/admin/orders/index.tcl,v diff -u -r1.2 -r1.3 --- openacs-4/packages/ecommerce/www/admin/orders/index.tcl 29 Jan 2002 00:11:46 -0000 1.2 +++ openacs-4/packages/ecommerce/www/admin/orders/index.tcl 26 May 2002 04:36:50 -0000 1.3 @@ -1,103 +1,99 @@ -# /www/[ec_url_concat [ec_url] /admin]/orders/index.tcl ad_page_contract { - The main page for the orders section of the ecommerce admin pages. + The main page for the orders section of the ecommerce admin pages. - @author Eve Andersson (eveander@arsdigita.com) - @creation-date Summer 1999 - @cvs-id index.tcl,v 3.2.2.3 2000/08/16 21:19:21 seb Exp - @author ported by Jerry Asher (jerry@theashergroup.com) + @author Eve Andersson (eveander@arsdigita.com) + @creation-date Summer 1999 + @author ported by Jerry Asher (jerry@theashergroup.com) + @author revised by Bart Teeuwisse + @revision-date April 2002 + } { } ad_require_permission [ad_conn package_id] admin -doc_body_append "[ad_admin_header "Orders / Shipments / Refunds"] +doc_body_append " + [ad_admin_header "Orders / Shipments / Refunds"] + +

    Orders / Shipments / Refunds

    -

    Orders / Shipments / Refunds

    + [ad_admin_context_bar [list "../" "Ecommerce([ec_system_name])"] "Orders / Shipments / Refunds"] -[ad_admin_context_bar [list "../" "Ecommerce([ec_system_name])"] "Orders / Shipments / Refunds"] +
    " -
    -" - - - -doc_body_append "
      " - db_1row recent_orders_select " -select - sum(one_if_within_n_days(confirmed_date,1)) as n_o_in_last_24_hours, - sum(one_if_within_n_days(confirmed_date,7)) as n_o_in_last_7_days -from ec_orders_reportable -" + select sum(one_if_within_n_days(confirmed_date,1)) as n_o_in_last_24_hours, sum(one_if_within_n_days(confirmed_date,7)) as n_o_in_last_7_days + from ec_orders_reportable" db_1row recent_gift_certificates_purchased_select " -select - sum(one_if_within_n_days(issue_date,1)) as n_g_in_last_24_hours, - sum(one_if_within_n_days(issue_date,7)) as n_g_in_last_7_days -from ec_gift_certificates_purchased -" + select sum(one_if_within_n_days(issue_date,1)) as n_g_in_last_24_hours, sum(one_if_within_n_days(issue_date,7)) as n_g_in_last_7_days + from ec_gift_certificates_purchased" db_1row recent_gift_certificates_issued_select " -select - sum(one_if_within_n_days(issue_date,1)) as n_gi_in_last_24_hours, - sum(one_if_within_n_days(issue_date,7)) as n_gi_in_last_7_days -from ec_gift_certificates_issued -" + select sum(one_if_within_n_days(issue_date,1)) as n_gi_in_last_24_hours, sum(one_if_within_n_days(issue_date,7)) as n_gi_in_last_7_days + from ec_gift_certificates_issued" db_1row recent_shipments_select " -select - sum(one_if_within_n_days(shipment_date,1)) as n_s_in_last_24_hours, - sum(one_if_within_n_days(shipment_date,7)) as n_s_in_last_7_days -from ec_shipments -" + select sum(one_if_within_n_days(shipment_date,1)) as n_s_in_last_24_hours, sum(one_if_within_n_days(shipment_date,7)) as n_s_in_last_7_days + from ec_shipments" db_1row recent_refunds_select " -select - sum(one_if_within_n_days(refund_date,1)) as n_r_in_last_24_hours, - sum(one_if_within_n_days(refund_date,7)) as n_r_in_last_7_days -from ec_refunds -" + select sum(one_if_within_n_days(refund_date,1)) as n_r_in_last_24_hours, sum(one_if_within_n_days(refund_date,7)) as n_r_in_last_7_days + from ec_refunds" -set n_standard_to_ship [db_string standard_shipping "select count(*) from ec_orders_shippable where shipping_method='standard'"] -set n_express_to_ship [db_string express_shipping "select count(*) from ec_orders_shippable where shipping_method='express'"] - doc_body_append " -
    • Orders ($n_o_in_last_24_hours in last 24 hours; $n_o_in_last_7_days in last 7 days) -

      -

    • Order Fulfillment ($n_standard_to_ship order[ec_decode $n_standard_to_ship 1 "" "s"] to be shipped via standard shipping[ec_decode $n_express_to_ship "0" "" ", $n_express_to_ship via express shipping"]) -

      -

    • Gift Certificate Purchases ($n_g_in_last_24_hours in last 24 hours; $n_g_in_last_7_days in last 7 days) -

      -

    • Gift Certificates Issued ($n_gi_in_last_24_hours in last 24 hours; $n_gi_in_last_7_days in last 7 days) -

      -

    • Shipments ($n_s_in_last_24_hours in last 24 hours; $n_s_in_last_7_days in last 7 days) -

      -

    • Refunds ($n_r_in_last_24_hours in last 24 hours; $n_r_in_last_7_days in last 7 days) -

      -

    • Financial Reports -

      -

    • Search for an order: -
      +
        +
      • Orders + ($n_o_in_last_24_hours in last 24 hours; $n_o_in_last_7_days in last 7 days)

      • +
      • Order Fulfillment + " -
        -By Order ID: - +set count 0 +db_foreach shipping_method_counts " + select shipping_method, coalesce(count(*), 0) as shipping_method_count + from ec_orders_shippable + where shipping_method not in ('no_shipping', 'pickup') + and shipping_method is not null + group by shipping_method" { -
        -By Product SKU: - + incr count + if {$count == 1} { + doc_body_append "(" + } + doc_body_append "$shipping_method_count to be shipped via $shipping_method" + if {$count < [db_resultrows]} { + doc_body_append ", " + } else { + doc_body_append ")" + } +} -
        -By Product Name: - - -
        -By Customer Last Name: - - -

      -
    -[ad_admin_footer] -" +doc_body_append "

    +
  • Gift Certificate Purchases + ($n_g_in_last_24_hours in last 24 hours; $n_g_in_last_7_days in last 7 days)

  • +
  • Gift Certificates Issued + ($n_gi_in_last_24_hours in last 24 hours; $n_gi_in_last_7_days in last 7 days)

  • +
  • Shipments + ($n_s_in_last_24_hours in last 24 hours; $n_s_in_last_7_days in last 7 days)

  • +
  • Refunds + ($n_r_in_last_24_hours in last 24 hours; $n_r_in_last_7_days in last 7 days)

  • +
  • Financial Reports +

  • Search for an order:

    +
    +
    +

    By Order ID:

    + +
    +

    By Product SKU:

    + +
    +

    By Product Name:

    + +
    +

    By Customer Last Name:

    + +
    +
  • + + [ad_admin_footer]" Index: openacs-4/packages/ecommerce/www/admin/orders/index.xql =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/ecommerce/www/admin/orders/index.xql,v diff -u -r1.2 -r1.3 --- openacs-4/packages/ecommerce/www/admin/orders/index.xql 29 Jan 2002 00:11:46 -0000 1.2 +++ openacs-4/packages/ecommerce/www/admin/orders/index.xql 26 May 2002 04:36:50 -0000 1.3 @@ -48,18 +48,7 @@ - select count(*) - from ec_orders_shippable - where shipping_method='standard' - - - select count(*) - from ec_orders_shippable - where shipping_method='express' - - - Index: openacs-4/packages/ecommerce/www/admin/orders/items-add-2.tcl =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/ecommerce/www/admin/orders/items-add-2.tcl,v diff -u -r1.2 -r1.3 --- openacs-4/packages/ecommerce/www/admin/orders/items-add-2.tcl 29 Jan 2002 00:11:46 -0000 1.2 +++ openacs-4/packages/ecommerce/www/admin/orders/items-add-2.tcl 26 May 2002 04:36:50 -0000 1.3 @@ -1,56 +1,60 @@ -# /www/[ec_url_concat [ec_url] /admin]/orders/items-add-2.tcl ad_page_contract { - @author Eve Andersson (eveander@arsdigita.com) - @creation-date Summer 1999 - @cvs-id items-add-2.tcl,v 3.2.6.3 2000/08/16 21:19:21 seb Exp - @author ported by Jerry Asher (jerry@theashergroup.com) + @author Eve Andersson (eveander@arsdigita.com) + @creation-date Summer 1999 + @author ported by Jerry Asher (jerry@theashergroup.com) + @author revised by Bart Teeuwisse + @revision-date April 2002 + } { - order_id:integer,notnull - sku:optional - product_name:optional + order_id:integer,notnull + sku:optional + product_name:optional } ad_require_permission [ad_conn package_id] admin -doc_body_append "[ad_admin_header "Add Items, Cont."] +doc_body_append " + [ad_admin_header "Add Items, Cont."] -

    Add Items, Cont.

    +

    Add Items, Cont.

    -[ad_admin_context_bar [list "../" "Ecommerce([ec_system_name])"] [list "index" "Orders"] [list "one?order_id=$order_id" "One Order"] "Add Items, Cont."] + [ad_admin_context_bar [list "../" "Ecommerce([ec_system_name])"] [list "index" "Orders"] [list "one?order_id=$order_id" "One Order"] "Add Items, Cont."] + +
    " -
    -" - if { [exists_and_not_null sku] } { set additional_query_part "sku=:sku" } else { set additional_query_part "upper(product_name) like '%' || upper(:product_name) || '%'" } set product_counter 0 -db_foreach products_select "select product_id, product_name from ec_products where $additional_query_part" { +db_foreach products_select " + select product_id, product_name + from ec_products + where $additional_query_part" { if { $product_counter == 0 } { - doc_body_append "Here are the product(s) that match your search. -

    - Note: the customer's credit card is not going to be reauthorized when you add this item to the order (their card was already found to be valid when they placed the intial order). They will, as usual, be automatically billed for this item when it ships. If the customer's credit limit is in question, just make a test authorization offline. -

      - " + doc_body_append " +

      Here are the product(s) that match your search.

      +

      Note: the customer's credit card is not going to be reauthorized when you add this item to the order + (their card was already found to be valid when they placed the intial order). + They will, as usual, be automatically billed for this item when it ships. + If the customer's credit limit is in question, just make a test authorization offline.

      +
        " } incr product_counter - doc_body_append "
      • $product_name -
        - [ec_add_to_cart_link $product_id "Add to Order" "Add to Order" "items-add-3" $order_id] -

        - " + doc_body_append " +

      • $product_name

        + [ec_add_to_cart_link $product_id "Add to Order" "Add to Order" "items-add-3" $order_id]" } if { $product_counter == 0 } { - doc_body_append "No matching products were found.\n" + doc_body_append " +

        No matching products were found.

        " } else { doc_body_append "
      " } doc_body_append " -[ad_admin_footer] -" + [ad_admin_footer]" Index: openacs-4/packages/ecommerce/www/admin/orders/items-add-3.tcl =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/ecommerce/www/admin/orders/items-add-3.tcl,v diff -u -r1.3 -r1.4 --- openacs-4/packages/ecommerce/www/admin/orders/items-add-3.tcl 31 Jan 2002 22:43:54 -0000 1.3 +++ openacs-4/packages/ecommerce/www/admin/orders/items-add-3.tcl 26 May 2002 04:36:50 -0000 1.4 @@ -1,53 +1,51 @@ -# /www/[ec_url_concat [ec_url] /admin]/orders/items-add-3.tcl ad_page_contract { - Add items, Cont. + Add items, Cont. - @author Eve Andersson (eveander@arsdigita.com) - @creation-date Summer 1999 - @cvs-id items-add-3.tcl,v 3.2.6.3 2000/08/16 21:19:21 seb Exp - @author ported by Jerry Asher (jerry@theashergroup.com) + @author Eve Andersson (eveander@arsdigita.com) + @creation-date Summer 1999 + @author ported by Jerry Asher (jerry@theashergroup.com) + @author revised by Bart Teeuwisse + @revision-date April 2002 + } { - order_id:integer,notnull - product_id:integer,notnull - color_choice - size_choice - style_choice + order_id:integer,notnull + product_id:integer,notnull + color_choice + size_choice + style_choice } ad_require_permission [ad_conn package_id] admin -doc_body_append "[ad_admin_header "Add Items, Cont."] +doc_body_append " + [ad_admin_header "Add Items, Cont."] -

      Add Items, Cont.

      +

      Add Items, Cont.

      -[ad_admin_context_bar [list "../" "Ecommerce([ec_system_name])"] [list "index" "Orders"] [list "one?order_id=$order_id" "One Order"] "Add Items, Cont."] + [ad_admin_context_bar [list "../" "Ecommerce([ec_system_name])"] [list "index" "Orders"] [list "one?order_id=$order_id" "One Order"] "Add Items, Cont."] -
      -" +
      " set item_id [db_nextval ec_item_id_sequence] -set user_id [db_string user_id_select "select user_id from ec_orders where order_id=:order_id"] +set user_id [db_string user_id_select " + select user_id + from ec_orders + where order_id=:order_id"] set lowest_price_and_price_name [ec_lowest_price_and_price_name_for_an_item $product_id $user_id ""] -doc_body_append "
      -[export_form_vars order_id product_id color_choice size_choice style_choice item_id] - -
      -This is the price that this user would normally receive for this product. -Make modifications as needed: - -
      - - ([ad_parameter -package_id [ec_id] Currency ecommerce]) -
      - -
      - -
      - -
      - - -[ad_admin_footer] -" +doc_body_append " +
      + [export_form_vars order_id product_id color_choice size_choice style_choice item_id] +
      +

      This is the price that this user would normally receive for this product. Make modifications as needed:

      +
      + + ([ad_parameter -package_id [ec_id] Currency ecommerce]) +
      +
      +
      + +
      + + [ad_admin_footer]" Index: openacs-4/packages/ecommerce/www/admin/orders/items-add-4.tcl =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/ecommerce/www/admin/orders/items-add-4.tcl,v diff -u -r1.2 -r1.3 --- openacs-4/packages/ecommerce/www/admin/orders/items-add-4.tcl 19 Mar 2002 00:34:25 -0000 1.2 +++ openacs-4/packages/ecommerce/www/admin/orders/items-add-4.tcl 26 May 2002 04:36:50 -0000 1.3 @@ -1,56 +1,139 @@ -# /www/[ec_url_concat [ec_url] /admin]/orders/items-add-4.tcl ad_page_contract { - Actually add the items. + Actually add the items. - @author Eve Andersson (eveander@arsdigita.com) - @creation-date Summer 1999 - @cvs-id items-add-4.tcl,v 3.3.2.3 2000/08/16 21:19:21 seb Exp - @author ported by Jerry Asher (jerry@theashergroup.com) + @author Eve Andersson (eveander@arsdigita.com) + @creation-date Summer 1999 + @author ported by Jerry Asher (jerry@theashergroup.com) + @author revised by Bart Teeuwisse + @revision-date April 2002 + } { - item_id:integer,notnull - order_id:integer,notnull - product_id:integer,notnull - color_choice - size_choice - style_choice - price_charged - price_name + item_id:integer,notnull + order_id:integer,notnull + product_id:integer,notnull + color_choice + size_choice + style_choice + price_charged + price_name } ad_require_permission [ad_conn package_id] admin -# double-click protection -if { [db_string doublclick_select "select count(*) from ec_items where item_id=:item_id"] > 0 } { +# Double-click protection + +if { [db_string doublclick_select " + select count(*) + from ec_items + where item_id = :item_id"] > 0 } { ad_returnredirect "one?[export_url_vars order_id]" return } -# must have associated credit card -if {[empty_string_p [db_string creditcard_id_select "select creditcard_id from ec_orders where order_id=:order_id"]]} { +# Must have associated credit card + +if {[empty_string_p [db_string creditcard_id_select " + select creditcard_id + from ec_orders + where order_id = :order_id"]]} { ad_return_error "Unable to add items to this order." " - This order does not have an associated credit card, so new items cannot be added. -
      Please create a new order instead." +

      This order does not have an associated credit card, so new items cannot be added.

      +

      Please create a new order instead.

      " return } -set shipping_method [db_string shipping_method_select "select shipping_method from ec_orders where order_id=:order_id"] +set shipping_method [db_string shipping_method_select " + select shipping_method + from ec_orders + where order_id = :order_id"] db_transaction { - db_dml ec_items_insert "insert into ec_items - (item_id, product_id, color_choice, size_choice, style_choice, order_id, in_cart_date, item_state, price_charged, price_name) - values - (:item_id, :product_id, :color_choice, :size_choice, :style_choice, :order_id, sysdate, 'to_be_shipped', :price_charged, :price_name) - " + db_dml ec_items_insert " + insert into ec_items + (item_id, product_id, color_choice, size_choice, style_choice, order_id, in_cart_date, item_state, price_charged, price_name) + values + (:item_id, :product_id, :color_choice, :size_choice, :style_choice, :order_id, sysdate, 'to_be_shipped', :price_charged, :price_name)" - # I calculate the shipping after it's inserted because this procedure goes and checks - # whether this is the first instance of this product in this order. - # I know it's non-ideal efficiency-wise, but this procedure (written for the user pages) - # is already written and it works. + # Check if a shipping gateway has been selected. - set shipping_price [ec_shipping_price_for_one_item $item_id $product_id $order_id $shipping_method] + set shipping_gateway [ad_parameter ShippingGateway] + if {[acs_sc_binding_exists_p ShippingGateway $shipping_gateway]} { - db_dml ec_items_update "update ec_items set shipping_charged=:shipping_price where item_id=:item_id" + # Replace the default ecommerce shipping calculations with the + # charges from the shipping gateway. Contact the shipping + # gateway to recalculate the total shipping charges. + + db_1row select_shipping_address " + select country_code, zip_code + from ec_addresses a, ec_orders o + where address_id = o.shipping_address + and o.order_id = :order_id" + + # Calculate the total value of the shipment. + + set shipment_value [db_string select_shipment_value " + select sum(coalesce(i.price_charged, 0)) + from ec_products p, ec_items i + where i.product_id = p.product_id + and p.no_shipping_avail_p = 'f' + and i.item_state not in ('void', 'received_back', 'expired') + and i.order_id = :order_id"] + set value_currency_code [ad_parameter Currency ecommerce] + set weight_unit_of_measure [ad_parameter WeightUnits ecommerce] + + # Get the list of services and their charges. + + set rates_and_services [acs_sc_call "ShippingGateway" "RatesAndServicesSelection" \ + [list "" "" "$country_code" "$zip_code" "$shipment_value" "$value_currency_code" "" "$weight_unit_of_measure"] \ + "$shipping_gateway"] + + # Find the charges for the selected service for the order. + + foreach service $rates_and_services { + array set rate_and_service $service + set order_shipping_cost $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"] + + # Unfortunately checking on the description of the + # shipping service is required as only the description is + # stored with the order as the shipping method. + + if {[string equal $service_description $shipping_method]} { + break + } + } + + # Calculate the tax on shipping and update the shipping cost + # of the order. + + set tax_on_order_shipping_cost [db_string get_shipping_tax " + select ec_tax(0, :order_shipping_cost, :order_id)"] + + 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" + + } else { + + # I calculate the shipping after it's inserted because this + # procedure goes and checks whether this is the first instance + # of this product in this order. I know it's non-ideal + # efficiency-wise, but this procedure (written for the user + # pages) # is already written and it works. + + set shipping_price [ec_shipping_price_for_one_item $item_id $product_id $order_id $shipping_method] + + db_dml ec_items_update " + update ec_items + set shipping_charged = :shipping_price + where item_id = :item_id" + + } } ad_returnredirect "one?[export_url_vars order_id]" Index: openacs-4/packages/ecommerce/www/admin/orders/items-add.tcl =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/ecommerce/www/admin/orders/items-add.tcl,v diff -u -r1.2 -r1.3 --- openacs-4/packages/ecommerce/www/admin/orders/items-add.tcl 29 Jan 2002 00:11:46 -0000 1.2 +++ openacs-4/packages/ecommerce/www/admin/orders/items-add.tcl 26 May 2002 04:36:50 -0000 1.3 @@ -1,47 +1,41 @@ -# /www/[ec_url_concat [ec_url] /admin]/orders/items-add.tcl ad_page_contract { - Add an item to an order. + Add an item to an order. - @author Eve Andersson (eveander@arsdigita.com) - @creation-date Summer 1999 - @cvs-id items-add.tcl,v 3.2.2.2 2000/08/16 21:19:21 seb Exp - @author ported by Jerry Asher (jerry@theashergroup.com) + @author Eve Andersson (eveander@arsdigita.com) + @creation-date Summer 1999 + @author ported by Jerry Asher (jerry@theashergroup.com) + @author revised by Bart Teeuwisse + @revision-date April 2002 + } { - order_id:integer,notnull + order_id:integer,notnull } ad_require_permission [ad_conn package_id] admin -doc_body_append "[ad_admin_header "Add Items"] +doc_body_append " + [ad_admin_header "Add Items"] -

      Add Items

      +

      Add Items

      -[ad_admin_context_bar [list "../" "Ecommerce([ec_system_name])"] [list "index" "Orders"] [list "one?order_id=$order_id" "One Order"] "Add Items"] + [ad_admin_context_bar [list "../" "Ecommerce([ec_system_name])"] [list "index" "Orders"] [list "one?order_id=$order_id" "One Order"] "Add Items"] -
      -
      -Search for a product to add: +
      +
      +

      Search for a product to add:

      +
      + [export_form_vars order_id] +
        +
      • By Name:
      • +
      + +
      + [export_form_vars order_id] +
        +
      • By SKU:
      • +
      + +
      + [ad_admin_footer]" -
        - -
        -[export_form_vars order_id] -
      • By Name: - - - -

        - -
        -[export_form_vars order_id] -

      • By SKU: - - - -
      - -
      -[ad_admin_footer] -" - Index: openacs-4/packages/ecommerce/www/admin/orders/items-return-2-oracle.xql =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/ecommerce/www/admin/orders/items-return-2-oracle.xql,v diff -u -r1.1 -r1.2 --- openacs-4/packages/ecommerce/www/admin/orders/items-return-2-oracle.xql 10 Jul 2001 20:33:53 -0000 1.1 +++ openacs-4/packages/ecommerce/www/admin/orders/items-return-2-oracle.xql 26 May 2002 04:36:50 -0000 1.2 @@ -1,13 +1,34 @@ - oracle8.1.6 + oracle8.1.6 - - - select nvl(shipping_charged,0) - nvl(shipping_refunded,0) from ec_orders where order_id=:order_id - - + + + select nvl(shipping_charged,0) - nvl(shipping_refunded,0) + from ec_orders + where order_id=:order_id + + + + + + select i.item_id, p.product_name, i.price_charged, nvl(i.shipping_charged,0) as shipping_charged + from ec_items i, ec_products p + where i.product_id=p.product_id + and i.item_id in ([join $item_id_list ", "]) + and i.item_state in ('shipped','arrived') + + - + + + select i.item_id, p.product_name, i.price_charged, nvl(i.shipping_charged,0) as shipping_charged + from ec_items i, ec_products p + where i.product_id=p.product_id + and i.order_id=:order_id + and i.item_state in ('shipped','arrived') + + + Index: openacs-4/packages/ecommerce/www/admin/orders/items-return-2.tcl =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/ecommerce/www/admin/orders/items-return-2.tcl,v diff -u -r1.3 -r1.4 --- openacs-4/packages/ecommerce/www/admin/orders/items-return-2.tcl 31 Jan 2002 22:43:54 -0000 1.3 +++ openacs-4/packages/ecommerce/www/admin/orders/items-return-2.tcl 26 May 2002 04:36:50 -0000 1.4 @@ -1,8 +1,9 @@ -# /www/[ec_url_concat [ec_url] /admin]/orders/items-return-2.tcl ad_page_contract { @cvs-id items-return-2.tcl,v 3.2.6.9 2000/09/22 01:34:57 kevin Exp @author ported by Jerry Asher (jerry@theashergroup.com) + @author revised by Bart Teeuwisse + @revision-date April 2002 } { @@ -24,30 +25,32 @@ append received_back_datetime " 12:00:00AM" } +# The customer service rep must be logged on -# the customer service rep must be logged on set customer_service_rep [ad_get_user_id] - if {$customer_service_rep == 0} { set return_url "[ad_conn url]?[export_entire_form_as_url_vars]" ad_returnredirect "/register?[export_url_vars return_url]" return } +# Make sure they haven't already inserted this refund - -# make sure they haven't already inserted this refund -if { [db_string get_refund_count "select count(*) from ec_refunds where refund_id=:refund_id"] > 0 } { - ad_return_complaint 1 "
    • This refund has already been inserted into the database; it looks like you are using an old form. Return to the order." +if { [db_string get_refund_count " + select count(*) + from ec_refunds + where refund_id=:refund_id"] > 0 } { + ad_return_complaint 1 " +
    • This refund has already been inserted into the database. Are you using an old form? Return to the order." return } set exception_count 0 set exception_text "" -# they must have either checked "All items" and none of the rest, or -# at least one of the rest and not "All items" -# they also need to have shipment_date filled in +# They must have either checked "All items" and none of the rest, or +# at least one of the rest and not "All items". They also need to have +# shipment_date filled in if { [info exists all_items_p] && [info exists item_id] } { incr exception_count @@ -63,40 +66,29 @@ return } +append doc_body " + [ad_admin_header "Specify refund amount"] -append doc_body "[ad_admin_header "Specify refund amount"] +

      Specify refund amount

      -

      Specify refund amount

      + [ad_admin_context_bar [list "../" "Ecommerce([ec_system_name])"] [list "index" "Orders"] [list "one?[export_url_vars order_id]" "One"] "Mark Items Returned"] +
      " -[ad_admin_context_bar [list "../" "Ecommerce([ec_system_name])"] [list "index" "Orders"] [list "one?[export_url_vars order_id]" "One"] "Mark Items Returned"] - -
      -" - set shipping_refund_percent [ad_parameter -package_id [ec_id] ShippingRefundPercent ecommerce] if { ![info exists all_items_p] } { set item_id_list $item_id - - set sql "select i.item_id, p.product_name, i.price_charged, i.shipping_charged - from ec_items i, ec_products p - where i.product_id=p.product_id - and i.item_id in ([join $item_id_list ", "]) - and i.item_state in ('shipped','arrived')" - # the last line is for error checking (we don't want them to push "back" and - # try to do a refund again for the same items) + set sql [db_map all_items_select] } else { - set sql "select i.item_id, p.product_name, i.price_charged, i.shipping_charged - from ec_items i, ec_products p - where i.product_id=p.product_id - and i.order_id=:order_id - and i.item_state in ('shipped','arrived')" + set sql [db_map selected_items_select] } -# If they select "All items", I want to generate a list of the items because, regardless -# of what happens elsewhere on the site (e.g. an item is added to the order, thereby causing -# the query for all items to return one more item), I want only the items that they confirm -# here to be recorded as part of this return. +# Generate a list of the items if they selected "All items" because, +# regardless of what happens elsewhere on the site (e.g. an item is +# added to the order, thereby causing the query for all items to +# return one more item), only the items that they confirm here should +# be recorded as part of this return. + if { [info exists all_items_p] } { set item_id_list [list] } @@ -107,38 +99,43 @@ if { [info exists all_items_p] } { lappend item_id_list $item_id } - append items_to_print "
    " + append items_to_print " + + + + + " } -append doc_body " -[export_form_vars refund_id order_id item_id_list received_back_datetime reason_for_return] -
    -
    IDDate IssuedGift Certificate StatePurchased ByRecipientAmount
    $gift_certificate_id[ec_nbsp_if_null [util_AnsiDatetoPrettyDate $issue_date]]$gift_certificate_state[ec_decode $last_name "" " " "$last_name, $first_names"]$recipient_email[ec_pretty_price $amount]
    $gift_certificate_id[ec_nbsp_if_null [util_AnsiDatetoPrettyDate $issue_date]]$gift_certificate_state[ec_decode $last_name "" " " "$last_name, $first_names"]$recipient_email[ec_pretty_price $amount]
    $product_name (out of [ec_pretty_price $price_charged]) (out of [ec_pretty_price $shipping_charged])
    $product_name (out of [ec_pretty_price $price_charged]) + (out of [ec_pretty_price $shipping_charged])
    - -$items_to_print -
    ItemPrice to RefundShipping to Refund
    -

    -" +append doc_body " + + [export_form_vars refund_id order_id item_id_list received_back_datetime reason_for_return] +

    + + + + + $items_to_print +
    ItemPrice to RefundShipping to Refund
    " -# we assume that, although only one refund may be done on an item, multiple refunds -# may be done on the base shipping cost, so we show them shipping_charged - shipping_refunded -set base_shipping [db_string unused "select nvl(shipping_charged,0) - nvl(shipping_refunded,0) from ec_orders where order_id=:order_id"] +# Although only one refund may be done on an item, multiple refunds +# may be done on the base shipping cost, so show shipping_charged - +# shipping_refunded. -append doc_body "Base shipping charge to refund: - (out of [ec_pretty_price $base_shipping]) +set base_shipping [db_string base_shipping_select " + select nvl(shipping_charged,0) - nvl(shipping_refunded,0) + from ec_orders + where order_id=:order_id"] -

    +append doc_body " +

    Base shipping charge to refund: + + (out of [ec_pretty_price $base_shipping])

    +
    -
    +
    -
    - -
    + [ad_admin_footer]" -[ad_admin_footer] -" - doc_return 200 text/html $doc_body - - - Index: openacs-4/packages/ecommerce/www/admin/orders/items-return-2.xql =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/ecommerce/www/admin/orders/items-return-2.xql,v diff -u -r1.1 -r1.2 --- openacs-4/packages/ecommerce/www/admin/orders/items-return-2.xql 10 Jul 2001 20:33:53 -0000 1.1 +++ openacs-4/packages/ecommerce/www/admin/orders/items-return-2.xql 26 May 2002 04:36:50 -0000 1.2 @@ -1,18 +1,12 @@ - - - select count(*) from ec_refunds where refund_id=:refund_id - - - - - - - select coalesce(shipping_charged,0) - coalesce(shipping_refunded,0) from ec_orders where order_id=:order_id - - - - + + + select count(*) + from ec_refunds + where refund_id=:refund_id + + + Index: openacs-4/packages/ecommerce/www/admin/orders/items-return-3-oracle.xql =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/ecommerce/www/admin/orders/items-return-3-oracle.xql,v diff -u -r1.1 -r1.2 --- openacs-4/packages/ecommerce/www/admin/orders/items-return-3-oracle.xql 10 Jul 2001 20:33:53 -0000 1.1 +++ openacs-4/packages/ecommerce/www/admin/orders/items-return-3-oracle.xql 26 May 2002 04:36:50 -0000 1.2 @@ -1,41 +1,52 @@ - oracle8.1.6 + oracle8.1.6 - - - select ec_tax(:tax_price_to_refund,0,:order_id) from dual - - + + + select i.item_id, p.product_name, nvl(i.price_charged,0) as price_charged, nvl(i.shipping_charged,0) as shipping_charged, + nvl(i.price_tax_charged,0) as price_tax_charged, nvl(i.shipping_tax_charged,0) as shipping_tax_charged + from ec_items i, ec_products p + where i.product_id=p.product_id + and i.item_id in ([join $item_id_list ", "]) + + - - - - select ec_tax(0,$shipping_to_refund($item_id),$order_id) from dual - - + + + select ec_tax(:tax_price_to_refund, 0, :order_id) + from dual + + - - - - select nvl(shipping_charged,0) - nvl(shipping_refunded,0) as base_shipping, nvl(shipping_tax_charged,0) - nvl(shipping_tax_refunded,0) as base_shipping_tax from ec_orders where order_id=:order_id - - + + + select ec_tax(0, $shipping_to_refund($item_id), :order_id) + from dual + + - - - - select ec_tax(0,:base_shipping,:order_id) from dual - - + + + select nvl(shipping_charged,0) - nvl(shipping_refunded,0) as base_shipping, nvl(shipping_tax_charged,0) - nvl(shipping_tax_refunded,0) as base_shipping_tax + from ec_orders + where order_id = :order_id + + - - - - select ec_cash_amount_to_refund(:total_amount_to_refund,:order_id) from dual - - + + + select ec_tax(0, :base_shipping, :order_id) + from dual + + - + + + select ec_cash_amount_to_refund(:total_amount_to_refund, :order_id) + from dual + + + Index: openacs-4/packages/ecommerce/www/admin/orders/items-return-3-postgresql.xql =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/ecommerce/www/admin/orders/items-return-3-postgresql.xql,v diff -u -r1.1 -r1.2 --- openacs-4/packages/ecommerce/www/admin/orders/items-return-3-postgresql.xql 10 Jul 2001 20:33:53 -0000 1.1 +++ openacs-4/packages/ecommerce/www/admin/orders/items-return-3-postgresql.xql 26 May 2002 04:36:50 -0000 1.2 @@ -1,34 +1,48 @@ - postgresql7.1 + postgresql7.1 - - - select ec_tax(:tax_price_to_refund,0,:order_id) - - + + + select i.item_id, p.product_name, coalesce(i.price_charged,0) as price_charged, coalesce(i.shipping_charged,0) as shipping_charged, coalesce(i.price_tax_charged,0) as price_tax_charged, + coalesce(i.shipping_tax_charged,0) as shipping_tax_charged + from ec_items i, ec_products p + where i.product_id=p.product_id + and i.item_id in ([join $item_id_list ", "]) + + - - - - select ec_tax(0,$shipping_to_refund($item_id),$order_id) - - + + + select ec_tax(:tax_price_to_refund, 0, :order_id) + + - - - - select ec_tax(0,:base_shipping,:order_id) - - + + + select ec_tax(0, $shipping_to_refund($item_id), :order_id) + + - - - - select ec_cash_amount_to_refund(:total_amount_to_refund,:order_id) - - + + + select coalesce(shipping_charged,0) - coalesce(shipping_refunded,0) as base_shipping, coalesce(shipping_tax_charged,0) - coalesce(shipping_tax_refunded,0) as base_shipping_tax + from ec_orders + where order_id = :order_id + + - + + + select ec_tax(0, :base_shipping, :order_id) + + + + + + select ec_cash_amount_to_refund(:total_amount_to_refund, :order_id) + + + Index: openacs-4/packages/ecommerce/www/admin/orders/items-return-3.tcl =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/ecommerce/www/admin/orders/items-return-3.tcl,v diff -u -r1.1 -r1.2 --- openacs-4/packages/ecommerce/www/admin/orders/items-return-3.tcl 20 Apr 2001 20:51:14 -0000 1.1 +++ openacs-4/packages/ecommerce/www/admin/orders/items-return-3.tcl 26 May 2002 04:36:50 -0000 1.2 @@ -1,4 +1,3 @@ -# /www/[ec_url_concat [ec_url] /admin]/orders/items-return-3.tcl ad_page_contract { @param refund_id @@ -12,8 +11,10 @@ @author @creation-date - @cvs-id items-return-3.tcl,v 3.2.6.7 2000/09/22 01:34:57 kevin Exp @author ported by Jerry Asher (jerry@theashergroup.com) + @author revised by Bart Teeuwisse + @revision-date April 2002 + } { refund_id:notnull,naturalnum order_id:notnull,naturalnum @@ -25,44 +26,41 @@ base_shipping_to_refund } -ad_require_permission [ad_conn package_id] admin +# The customer service rep must be logged on -# the customer service rep must be logged on +ad_require_permission [ad_conn package_id] admin set customer_service_rep [ad_get_user_id] -if {$customer_service_rep == 0} { - set return_url "[ad_conn url]?[export_entire_form_as_url_vars]" - ad_returnredirect "/register?[export_url_vars return_url]" - return -} +# Error checking: Make sure price_to_refund($item_id) is <= +# price_charged for that item same with shipping. Make sure +# base_shipping_to_refund is <= base shipping charged - refunded +# Make sure they haven't already inserted this refund -# error checking: -# make sure price_to_refund($item_id) is <= price_charged for that item -# same with shipping -# make sure base_shipping_to_refund is <= base shipping charged - refunded - - -# make sure they haven't already inserted this refund -if { [db_string get_count_refunds "select count(*) from ec_refunds where refund_id=:refund_id"] > 0 } { - ad_return_complaint 1 "
  • This refund has already been inserted into the database; it looks like you are using an old form. Return to the order." +if { [db_string get_count_refunds " + select count(*) + from ec_refunds + where refund_id=:refund_id"] > 0 } { + ad_return_complaint 1 " +
  • This refund has already been inserted into the database.Are you using an old form? Return to the order." return } set exception_count 0 set exception_text "" -set sql "select i.item_id, p.product_name, nvl(i.price_charged,0) as price_charged, nvl(i.shipping_charged,0) as shipping_charged, nvl(i.price_tax_charged,0) as price_tax_charged, nvl(i.shipping_tax_charged,0) as shipping_tax_charged -from ec_items i, ec_products p -where i.product_id=p.product_id -and i.item_id in ([join $item_id_list ", "])" +# Add up the items' price/shipping/tax to refund as we go -# add up the items' price/shipping/tax to refund as we go set total_price_to_refund 0 set total_shipping_to_refund 0 set total_price_tax_to_refund 0 set total_shipping_tax_to_refund 0 -db_foreach get_items_for_return $sql { +db_foreach get_items_for_return " + select i.item_id, p.product_name, nvl(i.price_charged,0) as price_charged, nvl(i.shipping_charged,0) as shipping_charged, + nvl(i.price_tax_charged,0) as price_tax_charged, nvl(i.shipping_tax_charged,0) as shipping_tax_charged + from ec_items i, ec_products p + where i.product_id=p.product_id + and i.item_id in ([join $item_id_list ", "])" { if { [empty_string_p $price_to_refund($item_id)] } { incr exception_count @@ -75,11 +73,16 @@ append exception_text "
  • Please enter a price to refund for $product_name that is less than or equal to [ec_pretty_price $price_charged]." } else { set total_price_to_refund [expr $total_price_to_refund + $price_to_refund($item_id)] - # tax will be the minimum of the tax actually charged and the tax that would have been charged on the price to refund - # (tax rates may have changed in the meantime and we don't want to refund more than they paid) - set tax_price_to_refund $price_to_refund($item_id) - set iteration_price_tax_to_refund [ec_min $price_tax_charged [db_string get_ec_tax "select ec_tax(:tax_price_to_refund,0,:order_id) from dual"]] + # Tax will be the minimum of the tax actually charged and the + # tax that would have been charged on the price to refund (tax + # rates may have changed in the meantime and we don't want to + # refund more than they paid) + + set tax_price_to_refund $price_to_refund($item_id) + set iteration_price_tax_to_refund [ec_min $price_tax_charged [db_string get_ec_tax " + select ec_tax(:tax_price_to_refund,0,:order_id) + from dual"]] set total_price_tax_to_refund [expr $total_price_tax_to_refund + $iteration_price_tax_to_refund] } @@ -95,14 +98,19 @@ } else { set total_shipping_to_refund [expr $total_shipping_to_refund + $shipping_to_refund($item_id)] - set iteration_shipping_tax_to_refund [ec_min $shipping_tax_charged [db_string get_it_shipping_tax_refund "select ec_tax(0,$shipping_to_refund($item_id),$order_id) from dual"]] + set iteration_shipping_tax_to_refund [ec_min $shipping_tax_charged [db_string get_it_shipping_tax_refund " + select ec_tax(0,$shipping_to_refund($item_id), $order_id) + from dual"]] set total_shipping_tax_to_refund [expr $total_shipping_tax_to_refund + $iteration_shipping_tax_to_refund] } } -db_1row get_shipping_charged_values "select nvl(shipping_charged,0) - nvl(shipping_refunded,0) as base_shipping, nvl(shipping_tax_charged,0) - nvl(shipping_tax_refunded,0) as base_shipping_tax from ec_orders where order_id=:order_id" +db_1row get_shipping_charged_values " + select nvl(shipping_charged,0) - nvl(shipping_refunded,0) as base_shipping, + nvl(shipping_tax_charged,0) - nvl(shipping_tax_refunded,0) as base_shipping_tax + from ec_orders + where order_id=:order_id" - if { [empty_string_p $base_shipping_to_refund] } { incr exception_count append exception_text "
  • Please enter a base shipping amount to refund." @@ -114,10 +122,10 @@ append exception_text "
  • Please enter a base shipping amount to refund that is less than or equal to [ec_pretty_price $base_shipping]." } else { set total_shipping_to_refund [expr $total_shipping_to_refund + $base_shipping_to_refund] - - set iteration_shipping_tax_to_refund [ec_min $base_shipping_tax [db_string get_base_shipping_it_refund "select ec_tax(0,:base_shipping,:order_id) from dual"]] + set iteration_shipping_tax_to_refund [ec_min $base_shipping_tax [db_string get_base_shipping_it_refund " + select ec_tax(0,:base_shipping,:order_id) + from dual"]] set total_shipping_tax_to_refund [expr $total_shipping_tax_to_refund + $iteration_shipping_tax_to_refund] - } if { $exception_count > 0 } { @@ -128,87 +136,112 @@ set total_tax_to_refund [expr $total_price_tax_to_refund + $total_shipping_tax_to_refund] set total_amount_to_refund [expr $total_price_to_refund + $total_shipping_to_refund + $total_tax_to_refund] -# determine how much of this will be refunded in cash -set cash_amount_to_refund [db_string get_cash_refunded "select ec_cash_amount_to_refund(:total_amount_to_refund,:order_id) from dual"] +# Determine how much of this will be refunded in cash -# calculate gift certificate amount and tax to refund +set cash_amount_to_refund [db_string get_cash_refunded " + select ec_cash_amount_to_refund(:total_amount_to_refund,:order_id) + from dual"] + +# Calculate gift certificate amount and tax to refund + set certificate_amount_to_reinstate [expr $total_amount_to_refund - $cash_amount_to_refund] if { $certificate_amount_to_reinstate < 0 } { - # because of rounding + + # Because of rounding + set certificate_amount_to_reinstate 0 } -# see if the credit card data is still in the database (otherwise they'll have to type in the query password) -set creditcard_number [db_string get_cc_number "select creditcard_number from ec_orders o, ec_creditcards c where o.creditcard_id=c.creditcard_id and o.order_id=:order_id" -default ""] +# See if the credit card data is still in the database. If not the +# credit card number has to be re-entered. +if {![db_0or1row get_billing_info " + select c.creditcard_id, c.creditcard_type, c.creditcard_last_four, + substring(creditcard_expire for 2) as card_exp_month, substring(creditcard_expire from 4 for 2) as card_exp_year, + p.first_names || ' ' || p.last_name as card_name, + a.line1 as billing_street, a.city as billing_city, a.usps_abbrev as billing_state, a.zip_code as billing_zip, a.country_code as billing_country + from ec_orders o, ec_creditcards c, persons p, ec_addresses a + where o.creditcard_id = c.creditcard_id + and c.billing_address = a.address_id + and c.user_id = p.person_id + and o.order_id=:order_id"]} { + + set creditcard_number "" + set creditcard_id "" + set creditcard_type "" + set creditcard_last_four "" + set card_expiration "" + set card_name "" + set billing_street "" + set billing_state "" + set billing_zip "" + set billing_country "" +} -append doc_body "[ad_admin_header "Refund Totals"] +append doc_body " + [ad_admin_header "Refund Totals"] -

    Refund Totals

    +

    Refund Totals

    -[ad_admin_context_bar [list "../" "Ecommerce([ec_system_name])"] [list "index" "Orders"] [list "one?[export_url_vars order_id]" "One"] "Refund Totals"] + [ad_admin_context_bar [list "../" "Ecommerce([ec_system_name])"] [list "index" "Orders"] [list "one?[export_url_vars order_id]" "One"] "Refund Totals"] -
    - -[export_entire_form] -[export_form_vars cash_amount_to_refund certificate_amount_to_reinstate] -
    -Total refund amount: [ec_pretty_price $total_amount_to_refund] (price: [ec_pretty_price $total_price_to_refund], shipping: [ec_pretty_price $total_shipping_to_refund], tax: [ec_pretty_price $total_tax_to_refund]) -

    -

      -
    • [ec_pretty_price $certificate_amount_to_reinstate] will be reinstated in gift certificates.
      -
    • [ec_pretty_price $cash_amount_to_refund] will be refunded to the customer's credit card.
      -
    -" +
    + + [export_entire_form] + [export_form_vars cash_amount_to_refund certificate_amount_to_reinstate] +
    +

    Total refund amount: [ec_pretty_price $total_amount_to_refund] (price: [ec_pretty_price $total_price_to_refund], shipping: [ec_pretty_price $total_shipping_to_refund], tax: [ec_pretty_price $total_tax_to_refund])

    +
      +
    • [ec_pretty_price $certificate_amount_to_reinstate] will be reinstated in gift certificates.
      +
    • [ec_pretty_price $cash_amount_to_refund] will be refunded to the customer's credit card.
      +
    " -# have them type in the query password +# Request the credit card number to be re-entered if it is no longer +# on file, yet there is money to refund. + if { [empty_string_p $creditcard_number] && $cash_amount_to_refund > 0 } { - append doc_body "
    - Enter either your CyberCash card-query password (which we can use to try to obtain - the credit card number used on this order) or enter a new credit card: -
    + append doc_body " +

    Please re-enter the credit card number of the card used for this order:

    - - - - + -
    Password for card-query:
    New Credit Card: - not yet functional +
    - - + + + + + - - - + + - - - - - + +
    Credit card number: + [ec_creditcard_widget $creditcard_type disabled]
    Ending in:xxxxxxxxxxxx$creditcard_last_four
    Type:[ec_creditcard_widget]
    Expires:$card_expiration
    Expires:[ec_creditcard_expire_1_widget] [ec_creditcard_expire_2_widget]
    Billing zip code:Billing address:$billing_street
    + $billing_city, $billing_state $billing_zip
    + $billing_country
    -
    -
    - " + + + " +} else { + append doc_body " + [export_form_vars creditcard_id creditcard_number]" } +append doc_body " + [export_form_vars creditcard_type]" -append doc_body "
    -
    -
    - -
    +append doc_body " +
    +
    + [export_form_vars creditcard_last_four] +
    + +
    -[ad_admin_footer] -" +[ad_admin_footer]" - - - -doc_return 200 text/html $doc_body - - - +doc_return 200 text/html $doc_body Index: openacs-4/packages/ecommerce/www/admin/orders/items-return-3.xql =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/ecommerce/www/admin/orders/items-return-3.xql,v diff -u -r1.2 -r1.3 --- openacs-4/packages/ecommerce/www/admin/orders/items-return-3.xql 24 Nov 2001 03:30:46 -0000 1.2 +++ openacs-4/packages/ecommerce/www/admin/orders/items-return-3.xql 26 May 2002 04:36:50 -0000 1.3 @@ -3,38 +3,24 @@ - select count(*) from ec_refunds where refund_id=:refund_id + select count(*) + from ec_refunds + where refund_id=:refund_id - + - select i.item_id, p.product_name, coalesce(i.price_charged,0) as price_charged, coalesce(i.shipping_charged,0) as shipping_charged, coalesce(i.price_tax_charged,0) as price_tax_charged, coalesce(i.shipping_tax_charged,0) as shipping_tax_charged - from ec_items i, ec_products p - where i.product_id=p.product_id - and i.item_id in ([join $item_id_list ", "]) + select c.creditcard_id, c.creditcard_type, c.creditcard_number, c.creditcard_last_four, + c.creditcard_expire as card_expiration, + p.first_names || ' ' || p.last_name as card_name, + a.line1 as billing_street, a.city as billing_city, a.usps_abbrev as billing_state, a.zip_code as billing_zip, a.country_code as billing_country + from ec_orders o, ec_creditcards c, persons p, ec_addresses a + where o.creditcard_id = c.creditcard_id + and c.billing_address=a.address_id + and c.user_id = p.person_id + and o.order_id=:order_id - - - select coalesce(shipping_charged,0) - coalesce(shipping_refunded,0) as base_shipping, coalesce(shipping_tax_charged,0) - coalesce(shipping_tax_refunded,0) as base_shipping_tax from ec_orders where order_id=:order_id - - - - - - - select creditcard_number from ec_orders o, ec_creditcards c where o.creditcard_id=c.creditcard_id and o.order_id=:order_id - - - - - - - select zip_code from ec_orders o, ec_addresses a where o.shipping_address=a.address_id and o.order_id=:order_id - - - - Index: openacs-4/packages/ecommerce/www/admin/orders/items-return-4-oracle.xql =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/ecommerce/www/admin/orders/items-return-4-oracle.xql,v diff -u -r1.2 -r1.3 --- openacs-4/packages/ecommerce/www/admin/orders/items-return-4-oracle.xql 29 Jan 2002 00:11:46 -0000 1.2 +++ openacs-4/packages/ecommerce/www/admin/orders/items-return-4-oracle.xql 26 May 2002 04:36:50 -0000 1.3 @@ -1,117 +1,126 @@ - oracle8.1.6 + + oracle + 8.1.6 + - - + + insert into ec_refunds - (refund_id, order_id, refund_amount, refund_date, refunded_by, refund_reasons) - values - (:refund_id, :order_id, :cash_amount_to_refund, sysdate, :customer_service_rep,:reason_for_return) - - - + (refund_id, order_id, refund_amount, refund_date, refunded_by, refund_reasons) + values + (:refund_id, :order_id, :cash_amount_to_refund, sysdate, :customer_service_rep,:reason_for_return) + + - - - - select nvl(price_tax_charged,0) as price_tax_charged, nvl(shipping_tax_charged,0) as shipping_tax_charged from ec_items where item_id=:item_id - - + + + select nvl(price_tax_charged,0) as price_tax_charged, + nvl(shipping_tax_charged,0) as shipping_tax_charged + from ec_items + where item_id=:item_id + + - - - - select ec_tax(:price_bind_variable,0,:order_id) from dual - - + + + select ec_tax(:price_bind_variable,0,:order_id) + from dual + + - - - - select ec_tax(0,:shipping_bind_variable,:order_id) from dual - - + + + select ec_tax(0,:shipping_bind_variable,:order_id) + from dual + + - - - - select nvl(shipping_tax_charged,0) from ec_orders where order_id=:order_id - - + + + select nvl(shipping_tax_charged,0) + from ec_orders + where order_id=:order_id + + - - - - select ec_tax(0,:base_shipping_to_refund,:order_id) from dual - - + + + select ec_tax(0,:base_shipping_to_refund,:order_id) + from dual + + - - - + + insert into ec_financial_transactions - (transaction_id, order_id, refund_id, creditcard_id, transaction_amount, transaction_type, inserted_date) - values - (:transaction_id, :order_id, :refund_id, :creditcard_id, :cash_amount_to_refund, 'refund', sysdate) - - - + (transaction_id, order_id, refund_id, creditcard_id, transaction_amount, transaction_type, inserted_date) + values + (:transaction_id, :order_id, :refund_id, :creditcard_id, :cash_amount_to_refund, 'refund', sysdate) + + - - - - select ec_order_gift_cert_amount(:order_id) from dual - - + + + select ec_order_gift_cert_amount(:order_id) + from dual + + - - - + + insert into ec_problems_log - (problem_id, problem_date, problem_details, order_id) - values - (ec_problem_id_sequence.nextval, sysdate, :errorstring, :order_id) - - - + (problem_id, problem_date, problem_details, order_id) + values + (ec_problem_id_sequence.nextval, sysdate, :errorstring, :order_id) + + - - - - select gift_certificate_amount_left(:cert) from dual - - + + + select u.gift_certificate_id, nvl(sum(u.amount_used),0) - nvl(sum(u.amount_reinstated),0) as reinstateable_amount + from ec_gift_certificate_usage u, ec_gift_certificates c + where u.gift_certificate_id = c.gift_certificate_id + and u.order_id = :order_id + group by u.gift_certificate_id, c.expires + order by expires desc, gift_certificate_id desc + + - - - + + insert into ec_gift_certificate_usage - (gift_certificate_id, order_id, amount_reinstated, reinstated_date) - values - (:cert, :order_id, :iteration_reinstate_amount, sysdate) - - - + (gift_certificate_id, order_id, amount_reinstated, reinstated_date) + values + (:gift_certificate_id, :order_id, least(to_number(:certificate_amount_to_reinstate), to_number(:reinstateable_amount)), sysdate) + + - - - + + insert into ec_problems_log - (problem_id, problem_date, problem_details, order_id) - values - (ec_problem_id_sequence.nextval, sysdate, :errorstring, :order_id) - - - + (problem_id, problem_date, problem_details, order_id) + values + (ec_problem_id_sequence.nextval, sysdate, :errorstring, :order_id) + + - - - - update ec_financial_transactions set refunded_date=sysdate where transaction_id=:transaction_id - - + + + update ec_financial_transactions + set refunded_date=sysdate + where transaction_id=:pgw_transaction_id + + - + + + update ec_financial_transactions + set to_be_captured_date = sysdate + where transaction_id = :transaction_id + + + Index: openacs-4/packages/ecommerce/www/admin/orders/items-return-4-postgresql.xql =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/ecommerce/www/admin/orders/items-return-4-postgresql.xql,v diff -u -r1.2 -r1.3 --- openacs-4/packages/ecommerce/www/admin/orders/items-return-4-postgresql.xql 29 Jan 2002 00:11:46 -0000 1.2 +++ openacs-4/packages/ecommerce/www/admin/orders/items-return-4-postgresql.xql 26 May 2002 04:36:50 -0000 1.3 @@ -1,103 +1,174 @@ - postgresql7.1 + postgresql7.1 - - + + insert into ec_refunds - (refund_id, order_id, refund_amount, refund_date, refunded_by, refund_reasons) - values - (:refund_id, :order_id, :cash_amount_to_refund, current_timestamp, :customer_service_rep,:reason_for_return) - - - + (refund_id, order_id, refund_amount, refund_date, refunded_by, refund_reasons) + values + (:refund_id, :order_id, :cash_amount_to_refund, current_timestamp, :customer_service_rep,:reason_for_return) + + - - - - select ec_tax(:price_bind_variable,0,:order_id) - - + + + select coalesce(price_tax_charged,0) as price_tax_charged, + coalesce(shipping_tax_charged,0) as shipping_tax_charged + from ec_items + where item_id=:item_id + + - - - - select ec_tax(0,:shipping_bind_variable,:order_id) - - + + + select ec_tax(:price_bind_variable, 0, :order_id) + + + + + + select coalesce(shipping_tax_charged,0) + from ec_orders + where order_id=:order_id + + - - - + + + select ec_tax(0,:shipping_bind_variable,:order_id) + + + + + select ec_tax(0,:base_shipping_to_refund,:order_id) - - + + - - - + + + select transaction_id as charged_transaction_id, marked_date + from ec_financial_transactions + where order_id = :order_id + and transaction_type = 'charge' + and (transaction_amount - :refund_amount) < 0.01::numeric + and (transaction_amount - :refund_amount) > 0::numeric + and refunded_amount is null + and marked_date is not null + and failed_p = 'f' + order by transaction_id + limit 1 + + + + + insert into ec_financial_transactions - (transaction_id, order_id, refund_id, creditcard_id, transaction_amount, transaction_type, inserted_date) - values - (:transaction_id, :order_id, :refund_id, :creditcard_id, :cash_amount_to_refund, 'refund', current_timestamp) - - - + (transaction_id, refunded_transaction_id, order_id, refund_id, creditcard_id, transaction_amount, transaction_type, inserted_date, to_be_captured_date) + values + (:refund_transaction_id, :charged_transaction_id, :order_id, :refund_id, :creditcard_id, :refund_amount, 'refund', current_timestamp, :scheduled_hour) + + - - - + + + update ec_financial_transactions + set refunded_amount = coalesce(refunded_amount, 0) + :refund_amount + where transaction_id = :charged_transaction_id + + + + + + select transaction_id as charged_transaction_id, (transaction_amount - coalesce(refunded_amount, 0)) as unrefunded_amount, marked_date + from ec_financial_transactions + where order_id = :order_id + and transaction_type = 'charge' + and (transaction_amount - coalesce(refunded_amount, 0)) > 0.01::numeric + and marked_date is not null + and failed_p = 'f' + order by (transaction_amount - coalesce(refunded_amount, 0)) desc + limit 1 + + + + + + insert into ec_financial_transactions + (transaction_id, refunded_transaction_id, order_id, refund_id, creditcard_id, transaction_amount, transaction_type, inserted_date, to_be_captured_date) + values + (:refund_transaction_id, :charged_transaction_id, :order_id, :refund_id, :creditcard_id, :unrefunded_amount, 'refund', current_timestamp, :scheduled_hour) + + + + + + update ec_financial_transactions + set refunded_amount = coalesce(refunded_amount, 0) + :unrefunded_amount + where transaction_id = :charged_transaction_id + + + + + select ec_order_gift_cert_amount(:order_id) - - + + - - - + + insert into ec_problems_log - (problem_id, problem_date, problem_details, order_id) - values - (ec_problem_id_sequence.nextval, current_timestamp, :errorstring, :order_id) - - - + (problem_id, problem_date, problem_details, order_id) + values + (ec_problem_id_sequence.nextval, current_timestamp, :errorstring, :order_id) + + - - - - select gift_certificate_amount_left(:cert) - - + + + select u.gift_certificate_id, coalesce(sum(u.amount_used),0) - coalesce(sum(u.amount_reinstated),0) as reinstateable_amount + from ec_gift_certificate_usage u, ec_gift_certificates c + where u.gift_certificate_id = c.gift_certificate_id + and u.order_id = :order_id + group by u.gift_certificate_id, c.expires + order by expires desc, gift_certificate_id desc + + - - - + + insert into ec_gift_certificate_usage - (gift_certificate_id, order_id, amount_reinstated, reinstated_date) - values - (:cert, :order_id, :iteration_reinstate_amount, current_timestamp) - - - + (gift_certificate_id, order_id, amount_reinstated, reinstated_date) + values + (:gift_certificate_id, :order_id, least(:certificate_amount_to_reinstate, :reinstateable_amount), current_timestamp) + + - - - + + insert into ec_problems_log - (problem_id, problem_date, problem_details, order_id) - values - (ec_problem_id_sequence.nextval, current_timestamp, :errorstring, :order_id) - - - + (problem_id, problem_date, problem_details, order_id) + values + (ec_problem_id_sequence.nextval, current_timestamp, :errorstring, :order_id) + + - - - - update ec_financial_transactions set refunded_date=current_timestamp where transaction_id=:transaction_id - - + + + update ec_financial_transactions + set refunded_date = current_timestamp + where transaction_id=:pgw_transaction_id + + - + + + update ec_financial_transactions + set to_be_captured_date = current_timestamp + where transaction_id = :transaction_id + + + Index: openacs-4/packages/ecommerce/www/admin/orders/items-return-4.tcl =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/ecommerce/www/admin/orders/items-return-4.tcl,v diff -u -r1.2 -r1.3 --- openacs-4/packages/ecommerce/www/admin/orders/items-return-4.tcl 29 Jan 2002 00:11:46 -0000 1.2 +++ openacs-4/packages/ecommerce/www/admin/orders/items-return-4.tcl 26 May 2002 04:36:50 -0000 1.3 @@ -1,12 +1,11 @@ -# /www/[ec_url_concat [ec_url] /admin]/orders/items-return-4.tcl ad_page_contract { - This script does the following: - 1. tries to get credit card number (insert it if new) - 2. puts records into ec_refunds, individual items, the order, and - ec_financial transactions - 3. does the gift certificate reinstatements - 4. tries to do refund + This script does the following: + 1. tries to get credit card number (insert it if new) + 2. puts records into ec_refunds, individual items, the order, and + ec_financial transactions + 3. does the gift certificate reinstatements + 4. tries to do refund @param refund_id @param order_id @@ -19,13 +18,9 @@ @param cash_amount_to_refund @param certificate_amount_to_reinstate - @param card_query_p - @param card_query_password - @param creditcard_number + @param creditcard_id @param creditcard_type - @param creditcard_expire_1 - @param creditcard_expire_2 - @param billing_zip_code + @param creditcard_number @author Eve Andersson (eveander@arsdigita.com) @creation-date July 22, 1999 @@ -40,360 +35,482 @@ price_to_refund:array shipping_to_refund:array base_shipping_to_refund - cash_amount_to_refund + cash_amount_to_refund:optional certificate_amount_to_reinstate - card_query_p:optional - card_query_password:optional - creditcard_number:optional + creditcard_id:optional creditcard_type:optional - creditcard_expire_1:optional - creditcard_expire_2:optional - billing_zip_code:optional - + creditcard_number:optional + creditcard_last_four:optional } -ad_require_permission [ad_conn package_id] admin +# The customer service rep must be logged on and have admin +# privileges. -# the customer service rep must be logged on +ad_require_permission [ad_conn package_id] admin set customer_service_rep [ad_get_user_id] -if {$customer_service_rep == 0} { - set return_url "[ad_conn url]?[export_entire_form_as_url_vars]" - ad_returnredirect "/register?[export_url_vars return_url]" - return -} +# Get rid of spaces and dashes -if { [info exists creditcard_number] } { - # get rid of spaces and dashes - regsub -all -- "-" $creditcard_number "" creditcard_number - regsub -all " " $creditcard_number "" creditcard_number -} +regsub -all -- "-" $creditcard_number "" creditcard_number +regsub -all -- " " $creditcard_number "" creditcard_number -# error checking: -# unless the credit card number is in the database or if the total -# amount to refund is $0.00, card_query_p -# should exist and be "t" or "f". If it's "t", we need a password -# and no new credit card number. If it's "f", we need new credit -# card information and no card-query password. +# Error checking: unless the credit card number is in the database or +# if the total amount to refund is $0.00 the credit card number needs +# to be re-entered. set exception_count 0 set exception_text "" +# Make sure that this refund hasn't been processed before. (Double +# click prevention.) - -set user_id [db_string get_user_id "select user_id from ec_orders where order_id=:order_id"] - -# make sure they haven't already inserted this refund -if { [db_string get_refund_id_check "select count(*) from ec_refunds where refund_id=:refund_id"] > 0 } { - ad_return_complaint 1 "
  • This refund has already been inserted into the database; it looks like you are using an old form. Return to the order." +if { [db_string get_refund_id_check " + select count(*) + from ec_refunds + where refund_id=:refund_id"] > 0 } { + ad_return_complaint 1 " +
  • This refund has already been inserted into the database. Are you using an old form? Return to the order.
  • " return } -if { [expr $cash_amount_to_refund] > 0 && [empty_string_p [db_string get_credit_card_id "select creditcard_number from ec_orders o, ec_creditcards c where o.creditcard_id=c.creditcard_id and o.order_id=:order_id"]]} { +# Check if money needs to be refunded and if the credit card number is +# still on file. + +if { [expr $cash_amount_to_refund] > 0 } { + + # Make sure that all the credit card information is there. + + if {![info exists creditcard_id] || ([info exists creditcard_id] && [empty_string_p $creditcard_id])} { + incr exception_count + append exception_text " +
  • + You forgot to provide the creditcard that was used to purchase the items to be returned. +
  • " + } + if {![info exists creditcard_type] || ([info exists creditcard_type] && [empty_string_p $creditcard_type])} { + incr exception_count + append exception_text " +
  • + You forgot to provide type of the creditcard that was used to purchase the items to be returned. +
  • " + } + if {![info exists creditcard_number] || ([info exists creditcard_number] && [empty_string_p $creditcard_number])} { + incr exception_count + append exception_text " +
  • + You forgot to provide card number of the creditcard that was used to purchase the items to be returned. +
  • " + } + if {![info exists creditcard_last_four] || ([info exists creditcard_last_four] && [empty_string_p $creditcard_last_four])} { + incr exception_count + append exception_text " +
  • + You forgot to provide card number of the creditcard that was used to purchase the items to be returned. +
  • " + } - # then we need a card query or a new credit card number - if { ![info exists card_query_p] || [empty_string_p $card_query_p] } { + # The credit card has been re-entered. Check that the number is + # correct. + + if { [regexp {[^0-9]} $creditcard_number] } { incr exception_count - append exception_text "
  • You must specify whether you want to query CyberCash for the old credit card number or whether you want to use a new credit card." - } elseif { $card_query_p == "t" } { - if { [empty_string_p $card_query_password] } { - incr exception_count - append exception_text "
  • You specified that you want to query CyberCash for the old credit card number, but you didn't type in the card-query password." - } - if { ![empty_string_p $creditcard_number] } { - incr exception_count - append exception_text "
  • You specified that you want to query CyberCash for the old credit card number, but you entered a new credit card number. Please choose one or the other." - } - } else { - - # card_query_p is "f" - if { ![empty_string_p $card_query_password] } { - incr exception_count - append exception_text "
  • You specified that you want to use a new credit card number, but you entered a card-query password. Please choose one or the other." - } - - 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 - incr exception_count - append exception_text "
  • You forgot to specify which credit card you'd like to use." - } else { - # then they are using a new credit card and we just have to check that they - # got it all right - - 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 billing_zip_code] || [empty_string_p $billing_zip_code] } { - incr exception_count - append exception_text "
  • You forgot to enter the billing zip code." - } - - if { ![info exists creditcard_type] || [empty_string_p $creditcard_type] } { - incr exception_count - append exception_text "
  • You forgot to enter the credit card type." - } - - # make sure the credit card type is right & that it has the right number - # of digits - set additional_count_and_text [ec_check_creditcard_type_number_match $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 "
  • Please enter the full credit card expiration date (month and year)" - } - } + append exception_text "
  • The credit card number contains invalid characters.
  • " } + + if {[string length $creditcard_number] > 4 && ![string match *$creditcard_last_four $creditcard_number]} { + incr exception_count + append exception_text "
  • The last for digits of the credit card number do not match the digits on file.
    + Make sure to enter the card number of the credit card that was used to pay for the order.
  • " + } + + if {[info exists creditcard_type]} { + + # Make sure the credit card number matches the credit card + # type # and that the number 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 { $exception_count > 0 } { ad_return_complaint $exception_count $exception_text return } -# done with error checking +# Done with error checking +# 2. Put records into ec_refunds, individual items, the order, and +# ec_financial_transactions -set case_a_p 0 -set case_b_p 0 +db_dml update_cc_number_incctable " + update ec_creditcards + set creditcard_number=:creditcard_number + where creditcard_id=:creditcard_id" +db_dml insert_new_ec_refund " + insert into ec_refunds + (refund_id, order_id, refund_amount, refund_date, refunded_by, refund_reasons) + values + (:refund_id, :order_id, :cash_amount_to_refund, sysdate, :customer_service_rep,:reason_for_return)" -if { [expr $cash_amount_to_refund] > 0 } { - # 1. try to get credit card number (insert it if new) +foreach item_id $item_id_list { + + # This is annoying (doing these selects before each insert), + # but that's how it goes because we don't want to refund more + # tax than was actually paid even if the tax rates changed - if { [info exists card_query_p] && $card_query_p == "t" } { - set creditcard_id [db_string get_creditcard_id "select creditcard_id from ec_orders where order_id=:order_id"] - - # find the latest transaction with this card number, preferably one with authorized_date set - set transaction_to_query [db_string get_transaction_to_query " - select max(transaction_id) - from ec_financial_transactions - where creditcard_id=:creditcard_id - and (authorized_date is not null OR 0=(select count(*) from ec_financial_transactions where creditcard_id=:creditcard_id and authorized_date is not null) - "] - - # talk to CyberCash to get the card number - set cc_args [ns_set new] - set cc_output [ns_set new] - ns_set put $cc_args "order-id" $transaction_to_query - ns_set put $cc_args "passwd" $card_query_password - - cc_send_to_server_21 "card-query" $cc_args $cc_output - - set creditcard_number [ns_set get $cc_output "card-number"] - - - if { [empty_string_p $creditcard_number] } { - ad_return_complaint 1 "
  • The card-query was unsuccessful. Please try again (check the password) or manually enter a new credit card." - return - } else { - set case_a_p 1 - } - } elseif { [info exists card_query_p] && $card_query_p == "f" } { - set case_b_p 1 - } else { - set creditcard_id [db_string get_creditcard_id "select creditcard_id from ec_orders where order_id=:order_id"] - } + set price_bind_variable $price_to_refund($item_id) + set shipping_bind_variable $shipping_to_refund($item_id) + + db_1row get_tax_charged_on_item " + select nvl(price_tax_charged,0) as price_tax_charged, nvl(shipping_tax_charged,0) as shipping_tax_charged + from ec_items + where item_id=:item_id" + + set price_tax_to_refund [ec_min $price_tax_charged [db_string get_tax_charged " + select ec_tax(:price_bind_variable,0,:order_id) + from dual"]] + + set shipping_tax_to_refund [ec_min $shipping_tax_charged [db_string get_tax_shipping_to_refund " + select ec_tax(0,:shipping_bind_variable,:order_id) + from dual"]] + + db_dml update_item_return " + update ec_items + set item_state='received_back', received_back_date=to_date(:received_back_datetime,'YYYY-MM-DD HH12:MI:SSAM'), price_refunded=:price_bind_variable, + shipping_refunded=:shipping_bind_variable, price_tax_refunded=:price_tax_to_refund, shipping_tax_refunded=:shipping_tax_to_refund, refund_id=:refund_id + where item_id=:item_id" } -# 2. put records into ec_refunds, individual items, the order, and -# ec_financial_transactions +set base_shipping_tax_charged [db_string get_base_shipping_tax " + select nvl(shipping_tax_charged,0) + from ec_orders + where order_id=:order_id"] +set base_shipping_tax_to_refund [ec_min $base_shipping_tax_charged [db_string get_base_tax_to_refund " + select ec_tax(0,:base_shipping_to_refund,:order_id) + from dual"]] +db_dml update_ec_order_set_shipping_refunds " + update ec_orders + set shipping_refunded=:base_shipping_to_refund, shipping_tax_refunded=:base_shipping_tax_to_refund + where order_id=:order_id" -db_transaction { +# Match the refund up with prior charge transactions. Some payment +# gateways such Authorize.net require that each refund is linked +# to a prior charge transaction and that the refund amount does +# not exceed the amount of the charge transaction. The refund +# amount can exceed the charge amount when the order was shipped +# in parts and the customer returned items from various shipments. - if {$case_a_p} { - db_dml update_cc_number_incctable "update ec_creditcards set creditcard_number=:creditcard_number where creditcard_id=:creditcard_id" - } +set refund_amount $cash_amount_to_refund +while { $refund_amount > 0 } { + + # See if the refund matches a single charge transaction. The + # test < 0.01 is needed for reasons of rounding errors. + + if {[db_0or1row select_matching_charge_transaction " + select transaction_id as charged_transaction_id, marked_date + from ec_financial_transactions + where order_id = :order_id + and transaction_type = 'charge' + and (transaction_amount - :refund_amount) < 0.01::numeric + and (transaction_amount - :refund_amount) > 0::numeric + and refunded_amount is null + and marked_date is not null + and failed_p = 'f' + order by transaction_id + limit 1"]} { - if {$case_b_p} { - # insert a new credit card into ec_creditcards - set creditcard_id [db_nextval creditcard_id_sequence] - - set cc_thing "[string range $creditcard_number [expr [string length $creditcard_number] -4] [expr [string length $creditcard_number] -1]]" - - set expires "$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_zip_code) - values - (:creditcard_id, :user_id, :creditcard_number, :cc_thing, :creditcard_type,:expires,:billing_zip_code) - " - } + # Create a single refund financial transaction. + set refund_transaction_id [db_nextval ec_transaction_id_sequence] - db_dml insert_new_ec_refund "insert into ec_refunds - (refund_id, order_id, refund_amount, refund_date, refunded_by, refund_reasons) - values - (:refund_id, :order_id, :cash_amount_to_refund, sysdate, :customer_service_rep,:reason_for_return) - " + # Authorize.net is an example of a payment gateway that requires + # the original transaction to be settled before it accepts refunds + # for the transaction. Unfortunately there is no automated way to + # find out if the transaction has been settled. - foreach item_id $item_id_list { - # this is annoying (doing these selects before each insert), but that's how it goes because we don't - # want to refund more tax than was actually paid even if the tax rates changed - - set price_bind_variable $price_to_refund($item_id) - set shipping_bind_variable $shipping_to_refund($item_id) + # However, transactions are settled once a day (by all gateways) + # thus it is safe to assume that transactions are settled within + # 24 hours after they have been marked for settlement. - db_1row get_tax_charged_on_item "select nvl(price_tax_charged,0) as price_tax_charged, nvl(shipping_tax_charged,0) as shipping_tax_charged from ec_items where item_id=:item_id" - + set 24hr [expr 24 * 60 * 60] + set time_since_marking [expr [clock seconds] - [clock scan $marked_date]] + if { $time_since_marking > $24hr } { + set scheduled_hour [clock format [clock scan $marked_date] -format "%Y-%m-%d %H:%M:%S" -gmt true] + } else { + # It is too early to perform the refund now. First the + # original transaction needs to be settled by the payment + # gateway. Schedule the refund for 24 hours after the original + # transaction was marked for settlement. The procedure + # ec_unrefunded_transactions will then perform the shortly + # after the scheduled hour. - - set price_tax_to_refund [ec_min $price_tax_charged [db_string get_tax_charged "select ec_tax(:price_bind_variable,0,:order_id) from dual"]] - - set shipping_tax_to_refund [ec_min $shipping_tax_charged [db_string get_tax_shipping_to_refund "select ec_tax(0,:shipping_bind_variable,:order_id) from dual"]] - - db_dml update_item_return " - update ec_items set item_state='received_back', - received_back_date=to_date(:received_back_datetime,'YYYY-MM-DD HH12:MI:SSAM'), - price_refunded=:price_bind_variable, - shipping_refunded=:shipping_bind_variable, - price_tax_refunded=:price_tax_to_refund, - shipping_tax_refunded=:shipping_tax_to_refund, - refund_id=:refund_id - where item_id=:item_id" - } - - set base_shipping_tax_charged [db_string get_base_shipping_tax "select nvl(shipping_tax_charged,0) from ec_orders where order_id=:order_id"] - set base_shipping_tax_to_refund [ec_min $base_shipping_tax_charged [db_string get_base_tax_to_refund "select ec_tax(0,:base_shipping_to_refund,:order_id) from dual"]] - - db_dml update_ec_order_set_shipping_refunds "update ec_orders set shipping_refunded=:base_shipping_to_refund, shipping_tax_refunded=:base_shipping_tax_to_refund where order_id=:order_id" - - if { [expr $cash_amount_to_refund] > 0 } { - - # 1999-08-11: added refund_id to the insert - set transaction_id [db_nextval ec_transaction_id_sequence] - db_dml insert_new_financial_trans "insert into ec_financial_transactions - (transaction_id, order_id, refund_id, creditcard_id, transaction_amount, transaction_type, inserted_date) - values - (:transaction_id, :order_id, :refund_id, :creditcard_id, :cash_amount_to_refund, 'refund', sysdate) - " - } - - # 3. do the gift certificate reinstatements (start with ones that expire furthest in - # to future) - - if { $certificate_amount_to_reinstate > 0 } { - - # this will be a list of 2-element lists (gift_certificate_id, original_amount) - set certs_to_reinstate_list [list] - set sql "select u.gift_certificate_id, c.amount as original_amount - from ec_gift_certificate_usage u, ec_gift_certificates c - where u.gift_certificate_id = c.gift_certificate_id - and u.order_id = :order_id - order by expires desc - gift_certificate_id desc" - db_foreach get_gift_certs_to_reinstate $sql { - - lappend certs_to_reinstate_list [list $gift_certificate_id $original_amount] + set scheduled_hour [clock format [expr [clock scan $marked_date] + $24hr] -format "%Y-%m-%d %H:%M:%S" -gmt true] } - - # the amount used on that order - set certificate_amount_used [db_string get_gc_amount_used "select ec_order_gift_cert_amount(:order_id) from dual"] - - if { $certificate_amount_used < $certificate_amount_to_reinstate } { - - set errorstring "We were unable to reinstate the customer's gift certificate balance because the amount to be reinstated was larger than the original amount used. This shouldn't have happened unless there was a programming error or unless the database was incorrectly updated manually. This transaction was aborted (refund_id $refund_id), i.e. no refund was given to the customer." - - db_dml insert_too_little_gc "insert into ec_problems_log - (problem_id, problem_date, problem_details, order_id) + + db_dml insert_refund_transaction " + insert into ec_financial_transactions + (transaction_id, refunded_transaction_id, order_id, refund_id, creditcard_id, transaction_amount, transaction_type, inserted_date, to_be_captured_date) values - (ec_problem_id_sequence.nextval, sysdate, :errorstring, :order_id) - " - ad_return_error "Gift Certificate Error" "We were unable to reinstate the customer's gift certificate balance because the amount to be reinstated was larger than the original amount used. This shouldn't have happened unless there was a programming error or unless the database was incorrectly updated manually.

    This transaction has been aborted, i.e. no refund has been given to the customer. This has been logged in the problems log." - return + (:refund_transaction_id, :charged_transaction_id, :order_id, :refund_id, :creditcard_id, :refund_amount, 'refund', sysdate, :scheduled_hour)" + + # Record the amount that was refunded of the charge transaction. + + db_dml record_refunded_amount " + update ec_financial_transactions + set refunded_amount = coalesce(refunded_amount, 0) + :refund_amount + where transaction_id = :charged_transaction_id" + + # Set the amount to be refunded to zero to indicate that + # no more refunds are needed. + + set refund_amount 0 + } elseif {[db_0or1row select_unrefunded_charge_transaction " + select transaction_id as charged_transaction_id, (transaction_amount - coalesce(refunded_amount, 0)) as unrefunded_amount, marked_date + from ec_financial_transactions + where order_id = :order_id + and transaction_type = 'charge' + and (transaction_amount - coalesce(refunded_amount, 0)) > 0.01::numeric + and marked_date is not null + and failed_p = 'f' + order by (transaction_amount - coalesce(refunded_amount, 0)) desc + limit 1"]} { + + if { $unrefunded_amount >= $refund_amount } { + + # Create refund financial transaction for the refund + # amount. + + set refund_transaction_id [db_nextval ec_transaction_id_sequence] + + # Authorize.net is an example of a payment gateway that requires + # the original transaction to be settled before it accepts refunds + # for the transaction. Unfortunately there is no automated way to + # find out if the transaction has been settled. + + # However, transactions are settled once a day (by all gateways) + # thus it is safe to assume that transactions are settled within + # 24 hours after they have been marked for settlement. + + set 24hr [expr 24 * 60 * 60] + set time_since_marking [expr [clock seconds] - [clock scan $marked_date]] + if { $time_since_marking > $24hr } { + set scheduled_hour [clock format [clock scan $marked_date] -format "%Y-%m-%d %H:%M:%S" -gmt true] + } else { + + # It is too early to perform the refund now. First the + # original transaction needs to be settled by the payment + # gateway. Schedule the refund for 24 hours after the original + # transaction was marked for settlement. The procedure + # ec_unrefunded_transactions will then perform the shortly + # after the scheduled hour. + + set scheduled_hour [clock format [expr [clock scan $marked_date] + $24hr] -format "%Y-%m-%d %H:%M:%S" -gmt true] + } + + db_dml insert_refund_transaction " + insert into ec_financial_transactions + (transaction_id, refunded_transaction_id, order_id, refund_id, creditcard_id, transaction_amount, transaction_type, inserted_date, to_be_captured_date) + values + (:refund_transaction_id, :charged_transaction_id, :order_id, :refund_id, :creditcard_id, :refund_amount, 'refund', sysdate, :scheduled_hour)" + + # Record the amount that was refunded of the charge transaction. + + db_dml record_refunded_amount " + update ec_financial_transactions + set refunded_amount = coalesce(refunded_amount, 0) + :refund_amount + where transaction_id = :charged_transaction_id" + + # Set the amount to be refunded to zero to indicate that + # no more refunds are needed. + + set refund_amount 0 } else { - # go through and reinstate certificates in order; it's not so bad - # to loop through all of them because I don't expect there to be - # many - - set amount_to_reinstate $certificate_amount_to_reinstate - foreach cert_and_original_amount $certs_to_reinstate_list { - if { $amount_to_reinstate > 0 } { - set cert [lindex $cert_and_original_amount 0] - set original_amount [lindex $cert_and_original_amount 1] - set reinstatable_amount [expr $original_amount - [db_string get_gc_amt_left "select gift_certificate_amount_left(:cert) from dual"]] - if { $reinstatable_amount > 0 } { - set iteration_reinstate_amount [ec_min $reinstatable_amount $amount_to_reinstate] - - db_dml insert_new_gc_usage_reinstate "insert into ec_gift_certificate_usage - (gift_certificate_id, order_id, amount_reinstated, reinstated_date) - values - (:cert, :order_id, :iteration_reinstate_amount, sysdate) - " - - set amount_to_reinstate [expr $amount_to_reinstate - $iteration_reinstate_amount] - } - } + + # Create refund financial transaction for the unrefunded + # amount of the charge transaction. + + set refund_transaction_id [db_nextval ec_transaction_id_sequence] + + # Authorize.net is an example of a payment gateway that requires + # the original transaction to be settled before it accepts refunds + # for the transaction. Unfortunately there is no automated way to + # find out if the transaction has been settled. + + # However, transactions are settled once a day (by all gateways) + # thus it is safe to assume that transactions are settled within + # 24 hours after they have been marked for settlement. + + set 24hr [expr 24 * 60 * 60] + set time_since_marking [expr [clock seconds] - [clock scan $marked_date]] + if { $time_since_marking > $24hr } { + set scheduled_hour [clock format [clock scan $marked_date] -format "%Y-%m-%d %H:%M:%S" -gmt true] + } else { + + # It is too early to perform the refund now. First the + # original transaction needs to be settled by the payment + # gateway. Schedule the refund for 24 hours after the original + # transaction was marked for settlement. The procedure + # ec_unrefunded_transactions will then perform the shortly + # after the scheduled hour. + + set scheduled_hour [clock format [expr [clock scan $marked_date] + $24hr] -format "%Y-%m-%d %H:%M:%S" -gmt true] } - } - } -} -# end the transaction before going out to CyberCash to do the refund (if it fails, -# we still have a row in ec_financial_transactions telling us that it tried to do -# the refund, so we will know it needs to be done) + db_dml insert_unrefund_transaction " + insert into ec_financial_transactions + (transaction_id, refunded_transaction_id, order_id, refund_id, creditcard_id, transaction_amount, transaction_type, inserted_date, to_be_captured_date) + values + (:refund_transaction_id, :charged_transaction_id, :order_id, :refund_id, :creditcard_id, :unrefunded_amount, 'refund', sysdate, :scheduled_hour)" + # Record the amount that was refunded of the charge transaction. + db_dml record_unrefunded_amount " + update ec_financial_transactions + set refunded_amount = coalesce(refunded_amount, 0) + :unrefunded_amount + where transaction_id = :charged_transaction_id" -# 4. try to do refund + # Subtract the amount of the new refund transaction + # from the total amount to be refunded. -if { $cash_amount_to_refund > 0} { - # transaction_id should exist if the above is true - set refund_status [ec_creditcard_return $transaction_id] - if { $refund_status == "failure" || $refund_status == "invalid_input" } { + set refund_amount [expr $refund_amount - $unrefunded_amount] + } + } +} - set errorstring "When trying to refund refund_id $refund_id (transaction $transaction_id) at [ad_conn url], the following result occurred: $refund_status" +# 3. do the gift certificate reinstatements (start with ones that +# expire furthest in to future) - db_dml insert_cc_refund_problem "insert into ec_problems_log - (problem_id, problem_date, problem_details, order_id) - values - (ec_problem_id_sequence.nextval, sysdate, :errorstring, :order_id) - " - set results_explanation "The refund did not occur. We have made a record of this in the problems log so that the situation can be corrected manually." - } elseif { $refund_status == "inconclusive" } { - set results_explanation "The results of the refund attempt were inconclusive (perhaps due to a communications failure between us and CyberCash. A program will keep trying to complete the refund and the problems log will be updated if it the refund cannot be completed within 24 hours." - } else { - # refund successful - db_dml update_ft_set_success "update ec_financial_transactions set refunded_date=sysdate where transaction_id=:transaction_id" - set results_explanation "The refund is complete!" +if { $certificate_amount_to_reinstate > 0 } { + + set certificate_amount_used [db_string get_gc_amount_used " + select ec_order_gift_cert_amount(:order_id) + from dual"] + + if { $certificate_amount_used < $certificate_amount_to_reinstate } { + set errorstring " + We were unable to reinstate the customer's gift certificate balance because the amount to be reinstated was + larger than the original amount used. This shouldn't have happened unless there was a programming error or unless the + database was incorrectly updated manually. This transaction was aborted (refund_id $refund_id), i.e. no refund was + given to the customer." + db_dml record_reinstate_problem " + insert into ec_problems_log + (problem_id, problem_date, problem_details, order_id) + values + (ec_problem_id_sequence.nextval, sysdate, :errorstring, :order_id)" + ad_return_error " +

    Gift Certificate Error" "We were unable to reinstate the customer's gift certificate balance because the amount + to be reinstated was larger than the original amount used. This shouldn't have happened unless there was a programming error + or unless the database was incorrectly updated manually.

    +

    This transaction has been aborted, i.e. no refund has been given to the customer. This has been logged in the problems log.

    " + return } - set page_title "Refund completed with status $refund_status" + # Go through and reinstate certificates in order; it's not so bad + # to loop through all of them because there won't be many. -} else { - set page_title "No credit card refund needed." - set results_explanation "No credit card refund was necessary because the entire amount was refunded to the gift certificates the customer used when purchasing the order." + db_foreach reinstateable_gift_certificates " + select u.gift_certificate_id, coalesce(sum(u.amount_used),0) - coalesce(sum(u.amount_reinstated),0) as reinstateable_amount + from ec_gift_certificate_usage u, ec_gift_certificates c + where u.gift_certificate_id = c.gift_certificate_id + and u.order_id = :order_id + group by u.gift_certificate_id, c.expires + order by expires desc, gift_certificate_id desc" { + + if {$certificate_amount_to_reinstate > 0} { + db_dml reinstate_gift_certificate " + insert into ec_gift_certificate_usage + (gift_certificate_id, order_id, amount_reinstated, reinstated_date) + values + (:gift_certificate_id, :order_id, least(to_number(:certificate_amount_to_reinstate), to_number(:reinstateable_amount)) , sysdate)" + set $certificate_amount_to_reinstate [expr $certificate_amount_to_reinstate - \ + [expr ($certificate_amount_to_reinstate > $reinstateable_amount) ? $reinstateable_amount : $certificate_amount_to_reinstate]] + } + } } - +# 4. Try to do the refund(s) - -append doc_body "[ad_admin_header $page_title] -

    $page_title

    -[ad_admin_context_bar [list "../" "Ecommerce([ec_system_name])"] [list "index" "Orders"] [list "one?[export_url_vars order_id]" "One"] "Refund Complete"] +if {$cash_amount_to_refund > 0} { + set page_title "Refund results" + set results_explanation "" + db_foreach select_unrefund_transactions " + select transaction_id, transaction_amount, refunded_transaction_id, to_be_captured_date + from ec_financial_transactions + where order_id = :order_id + and transaction_type = 'refund' + and refunded_date is null + and failed_p = 'f'" { -
    -
    -$results_explanation -

    -Back to Order $order_id -

    + set now [clock format [clock seconds] -format "%Y-%m-%d %H:%M:%S" -gmt true] + if { [dt_interval_check $to_be_captured_date $now] > 0} { -[ad_admin_footer] -" + array set response [ec_creditcard_return $transaction_id] + set refund_status $response(response_code) + set pgw_transaction_id $response(transaction_id) + if { $refund_status == "failure" || $refund_status == "invalid_input" } { + set errorstring "Refund transaction $transaction_id for [ec_pretty_price $transaction_amount] of refund $refund_id at [ad_conn url], resulted in: $refund_status" + db_dml insert_cc_refund_problem " + insert into ec_problems_log + (problem_id, problem_date, problem_details, order_id) + values + (ec_problem_id_sequence.nextval, sysdate, :errorstring, :order_id)" + append results_explanation "

    Refund transaction $transaction_id for [ec_pretty_price $transaction_amount] did not occur. + We have made a record of this in the problems log so that the situation can be corrected manually.

    " + } elseif { $refund_status == "inconclusive" } { + # Set the to_be_captured_date so that the scheduled + # procedure ec_unrefunded_transactions will retry the + # transaction. -doc_return 200 text/html $doc_body + append results_explanation "

    The results of refund transaction $transaction_id for [ec_pretty_price $transaction_amount] were inconclusive + (perhaps due to a communications failure between us and the payment gateway). + A program will keep trying to complete this refund transaction and the problems log will be updated if it the refund transaction cannot be completed.

    " + } else { + # Refund successful + db_dml update_ft_set_success " + update ec_financial_transactions + set refunded_date=sysdate + where transaction_id=:pgw_transaction_id" + append results_explanation "

    Refund transaction $pgw_transaction_id for [ec_pretty_price $transaction_amount] is complete!

    ";# + } + } else { + # It is too early to perform the refund now. First the + # original transaction needs to be settled by the payment + # gateway. + append results_explanation "

    Refund transaction $transaction_id for [ec_pretty_price $transaction_amount] is scheduled for a later time. + Refunds can not be processed before the transaction charging the credit card has been completed by the gateway. + Transactions are completed with 24 hours after marking. Therefore the refund transaction has been scheduled for $to_be_captured_date

    " + } + } if_no_rows { + set page_title "No credit card refund needed." + set results_explanation "No credit card refund was necessary because the entire amount was refunded to the gift certificates the customer used when purchasing the order." + } +} else { + set page_title "No credit card refund needed." + set results_explanation "No credit card refund was necessary because the entire amount was refunded to the gift certificates the customer used when purchasing the order." +} +append doc_body " + [ad_admin_header $page_title] + +

    $page_title

    + + [ad_admin_context_bar [list "../" "Ecommerce([ec_system_name])"] [list "index" "Orders"] [list "one?[export_url_vars order_id]" "One"] "Refund Complete"] +
    +
    + $results_explanation + Back to Order $order_id +
    + [ad_admin_footer]" + +doc_return 200 text/html $doc_body Index: openacs-4/packages/ecommerce/www/admin/orders/items-return-4.xql =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/ecommerce/www/admin/orders/items-return-4.xql,v diff -u -r1.1 -r1.2 --- openacs-4/packages/ecommerce/www/admin/orders/items-return-4.xql 10 Jul 2001 20:33:53 -0000 1.1 +++ openacs-4/packages/ecommerce/www/admin/orders/items-return-4.xql 26 May 2002 04:36:50 -0000 1.2 @@ -1,105 +1,107 @@ - - - select user_id from ec_orders where order_id=:order_id - - + + + select user_id + from ec_orders + where order_id=:order_id + + - - - - select count(*) from ec_refunds where refund_id=:refund_id - - + + + select count(*) + from ec_refunds + where refund_id=:refund_id + + + + + + select creditcard_number + from ec_orders o, ec_creditcards c + where o.creditcard_id=c.creditcard_id + and o.order_id=:order_id + + - - - - select creditcard_number from ec_orders o, ec_creditcards c where o.creditcard_id=c.creditcard_id and o.order_id=:order_id - - + + + select creditcard_id + from ec_orders + where order_id=:order_id + + - - - - select creditcard_id from ec_orders where order_id=:order_id - - + + + select max(transaction_id) + from ec_financial_transactions + where creditcard_id=:creditcard_id + and (authorized_date is not null or 0=(select count(*) + from ec_financial_transactions + where creditcard_id=:creditcard_id + and authorized_date is not null) + + - - - - - select max(transaction_id) - from ec_financial_transactions - where creditcard_id=:creditcard_id - and (authorized_date is not null OR 0=(select count(*) from ec_financial_transactions where creditcard_id=:creditcard_id and authorized_date is not null) - - - + + + select creditcard_id + from ec_orders + where order_id=:order_id + + - - - - select creditcard_id from ec_orders where order_id=:order_id - - + + + update ec_creditcards + set creditcard_number=:creditcard_number + where creditcard_id=:creditcard_id + + - - - - update ec_creditcards set creditcard_number=:creditcard_number where creditcard_id=:creditcard_id - - - - - - + + insert into ec_creditcards - (creditcard_id, user_id, creditcard_number, creditcard_last_four, creditcard_type, creditcard_expire, billing_zip_code) - values - (:creditcard_id, :user_id, :creditcard_number, :cc_thing, :creditcard_type,:expires,:billing_zip_code) - - - + (creditcard_id, user_id, creditcard_number, creditcard_last_four, creditcard_type, creditcard_expire, billing_address) + values + (:creditcard_id, :user_id, :creditcard_number, :cc_thing, :creditcard_type, :expires, :address_id) + + - - - - select coalesce(price_tax_charged,0) as price_tax_charged, coalesce(shipping_tax_charged,0) as shipping_tax_charged from ec_items where item_id=:item_id - - + + + update ec_items + set item_state='received_back', + received_back_date=to_date(:received_back_datetime,'YYYY-MM-DD HH12:MI:SSAM'), + price_refunded=:price_bind_variable, + shipping_refunded=:shipping_bind_variable, + price_tax_refunded=:price_tax_to_refund, + shipping_tax_refunded=:shipping_tax_to_refund, + refund_id=:refund_id + where item_id=:item_id + + - - - - - update ec_items set item_state='received_back', - received_back_date=to_date(:received_back_datetime,'YYYY-MM-DD HH12:MI:SSAM'), - price_refunded=:price_bind_variable, - shipping_refunded=:shipping_bind_variable, - price_tax_refunded=:price_tax_to_refund, - shipping_tax_refunded=:shipping_tax_to_refund, - refund_id=:refund_id - where item_id=:item_id - - + + + update ec_orders + set shipping_refunded=:base_shipping_to_refund, shipping_tax_refunded=:base_shipping_tax_to_refund + where order_id=:order_id + + - - - - select coalesce(shipping_tax_charged,0) from ec_orders where order_id=:order_id - - + + + select transaction_id, transaction_amount, refunded_transaction_id, to_be_captured_date + from ec_financial_transactions + where order_id = :order_id + and transaction_type = 'refund' + and refunded_date is null + and failed_p = 'f' + + - - - - update ec_orders set shipping_refunded=:base_shipping_to_refund, shipping_tax_refunded=:base_shipping_tax_to_refund where order_id=:order_id - - - - Index: openacs-4/packages/ecommerce/www/admin/orders/items-return.tcl =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/ecommerce/www/admin/orders/items-return.tcl,v diff -u -r1.2 -r1.3 --- openacs-4/packages/ecommerce/www/admin/orders/items-return.tcl 29 Jan 2002 00:11:46 -0000 1.2 +++ openacs-4/packages/ecommerce/www/admin/orders/items-return.tcl 26 May 2002 04:36:50 -0000 1.3 @@ -1,64 +1,62 @@ -# /www/[ec_url_concat [ec_url] /admin]/orders/items-return.tcl ad_page_contract { - Return items. + Return items. - @author Eve Andersson (eveander@arsdigita.com) - @creation-date Summer 1999 - @cvs-id items-return.tcl,v 3.3.2.4 2000/08/17 15:19:14 seb Exp - @author ported by Jerry Asher (jerry@theashergroup.com) + @author Eve Andersson (eveander@arsdigita.com) + @creation-date Summer 1999 + @author ported by Jerry Asher (jerry@theashergroup.com) + @author revised by Bart Teeuwisse + @revision-date April 2002 + } { - order_id:integer,notnull + order_id:integer,notnull } ad_require_permission [ad_conn package_id] admin -# in case they reload this page after completing the refund process: -if { [db_string doubleclick_select "select count(*) from ec_items_refundable where order_id=:order_id"] == 0 } { - ad_return_complaint 1 "
  • This order doesn't contain any refundable items; perhaps you are using an old form. Return to the order." +# In case they reload this page after completing the refund process: + +if { [db_string doubleclick_select " + select count(*) + from ec_items_refundable + where order_id=:order_id"] == 0 } { + + ad_return_complaint 1 " +
  • This order doesn't contain any refundable items; perhaps you are using an old form. Return to the order." return } -doc_body_append "[ad_admin_header "Mark Items Returned"] +doc_body_append " + [ad_admin_header "Mark Items Returned"] -

    Mark Items Returned

    +

    Mark Items Returned

    -[ad_admin_context_bar [list "../" "Ecommerce([ec_system_name])"] [list "index" "Orders"] [list "one?order_id=$order_id" "One Order"] "Mark Items Returned"] + [ad_admin_context_bar [list "../" "Ecommerce([ec_system_name])"] [list "index" "Orders"] [list "one?order_id=$order_id" "One Order"] "Mark Items Returned"] +
    " -
    -" +# Generate the new refund_id to prevent reusing this form. -# generate the new refund_id here (we don't want them reusing this form) set refund_id [db_nextval refund_id_sequence] -doc_body_append "
    -[export_form_vars order_id refund_id] +doc_body_append " + + [export_form_vars order_id refund_id] -
    -Date received back: -[ad_dateentrywidget received_back_date] [ec_timeentrywidget received_back_time] +
    +

    Date received back: [ad_dateentrywidget received_back_date] [ec_timeentrywidget received_back_time]

    -

    +

    Please check off the items that were received back:

    +
    + [ec_items_for_fulfillment_or_return $order_id "f"] +
    -Please check off the items that were received back: -
    -[ec_items_for_fulfillment_or_return $order_id "f"] -
    +

    Reason for return (if known):

    +
    + +
    +
    -Reason for return (if known): -
    - -
    +
    + -
    - -

    -

    - -
    - - - -[ad_admin_footer] -" + [ad_admin_footer]" Index: openacs-4/packages/ecommerce/www/admin/orders/items-void-2.tcl =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/ecommerce/www/admin/orders/items-void-2.tcl,v diff -u -r1.1 -r1.2 --- openacs-4/packages/ecommerce/www/admin/orders/items-void-2.tcl 20 Apr 2001 20:51:14 -0000 1.1 +++ openacs-4/packages/ecommerce/www/admin/orders/items-void-2.tcl 26 May 2002 04:36:50 -0000 1.2 @@ -1,25 +1,27 @@ -# /www/[ec_url_concat [ec_url] /admin]/orders/items-void-2.tcl ad_page_contract { - Void items. + Void items. - @author Eve Andersson (eveander@arsdigita.com) - @creation-date Summer 1999 - @cvs-id items-void-2.tcl,v 3.2.2.3 2000/08/17 15:19:15 seb Exp - @author ported by Jerry Asher (jerry@theashergroup.com) + @author Eve Andersson (eveander@arsdigita.com) + @creation-date Summer 1999 + @author ported by Jerry Asher (jerry@theashergroup.com) + @author revised by Bart Teeuwisse + @revision-date April 2002 + } { - order_id:integer,notnull - product_id:integer,notnull - item_id:multiple,optional + order_id:integer,notnull + product_id:integer,notnull + item_id:multiple,optional } ad_require_permission [ad_conn package_id] admin set customer_service_rep [ad_get_user_id] -# See if there's a gift certificate amount applied to this order that's being -# tied up by unshipped items, in which case we may need to reinstate some or -# all of it. +# See if there's a gift certificate amount applied to this order +# that's being tied up by unshipped items, in which case we may need +# to reinstate some or all of it. + # The equations are: # (tied up g.c. amount) = (g.c. bal applied to order) - (amount paid for shipped items) # + (amount refunded for shipped items) @@ -34,83 +36,182 @@ # + (cost of to-be-voided items) # = (g.c. bal applied to order) - (total amount for all nonvoid items in the order after these are voided) # + total amount refunded on nonvoid items -# This equation is now officially simple to solve. G.c. balance should be calculated first, then things -# should be voided, then final calculation should be made and g.c.'s should be reinstated. +# This equation is now officially simple to solve. G.c. balance +# should be calculated first, then things should be voided, then final +# calculation should be made and g.c.'s should be reinstated. - db_transaction { - set gift_certificate_amount [db_string gift_certificate_amount_select "select ec_order_gift_cert_amount(:order_id) from dual"] + set gift_certificate_amount [db_string gift_certificate_amount_select " + select ec_order_gift_cert_amount(:order_id) + from dual"] - # see if there's more than one item in this order with that order_id & product_id + # See if there's more than one item in this order with that + # order_id & product_id - set n_items [db_string num_items_select "select count(*) from ec_items where order_id=:order_id and product_id=:product_id"] + set n_items [db_string num_items_select " + select count(*) + from ec_items + where order_id = :order_id + and product_id = :product_id"] - if { $n_items > 1 } { - # make sure they checked at least one checkbox - set item_id_list $item_id - if { [llength $item_id_list] == 1 && [lindex 0 $item_id_list] == 0 } { - ad_return_complaint 1 "
  • You didn't check off any items." - return - } - db_dml item_state_update "update ec_items set item_state='void', voided_date=sysdate, voided_by=:customer_service_rep where item_id in ([join $item_id_list ", "])" - } else { - db_dml item_state_update2 "update ec_items set item_state='void', voided_date=sysdate, voided_by=:customer_service_rep where order_id=:order_id and product_id=:product_id" - } + if { $n_items > 1 } { - set amount_charged_minus_refunded_for_nonvoid_items [db_string amount_charged_minus_refunded_for_nonvoid_items_select "select nvl(sum(nvl(price_charged,0)) + sum(nvl(shipping_charged,0)) + sum(nvl(price_tax_charged,0)) + sum(nvl(shipping_tax_charged,0)) - sum(nvl(price_refunded,0)) - sum(nvl(shipping_refunded,0)) + sum(nvl(price_tax_refunded,0)) - sum(nvl(shipping_tax_refunded,0)),0) from ec_items where item_state <> 'void' and order_id=:order_id"] + # Make sure they checked at least one checkbox - set certificate_amount_to_reinstate [expr $gift_certificate_amount - $amount_charged_minus_refunded_for_nonvoid_items] + set item_id_list $item_id + if { [llength $item_id_list] == 1 && [lindex 0 $item_id_list] == 0 } { + ad_return_complaint 1 "
  • You didn't check off any items.
  • " + return + } + db_dml item_state_update " + update ec_items + set item_state = 'void', voided_date = sysdate, voided_by = :customer_service_rep + where item_id in ([join $item_id_list ", "])" + } else { + db_dml item_state_update2 " + update ec_items + set item_state = 'void', voided_date = sysdate, voided_by = :customer_service_rep + where order_id = :order_id + and product_id = :product_id" + } - if { $certificate_amount_to_reinstate > 0 } { + set amount_charged_minus_refunded_for_nonvoid_items [db_string amount_charged_minus_refunded_for_nonvoid_items_select " + select nvl(sum(nvl(price_charged,0)) + sum(nvl(shipping_charged,0)) + sum(nvl(price_tax_charged,0)) + sum(nvl(shipping_tax_charged,0)) - sum(nvl(price_refunded,0)) - + sum(nvl(shipping_refunded,0)) + sum(nvl(price_tax_refunded,0)) - sum(nvl(shipping_tax_refunded,0)),0) + from ec_items + where item_state <> 'void' + and order_id = :order_id"] - set certs_to_reinstate_list [list] + set certificate_amount_to_reinstate [expr $gift_certificate_amount - $amount_charged_minus_refunded_for_nonvoid_items] - set certs_to_reinstate_list [db_list certs_to_reinstate_list_select "select u.gift_certificate_id - from ec_gift_certificate_usage u, ec_gift_certificates c - where u.gift_certificate_id = c.gift_certificate_id - and u.order_id = :order_id - order by expires desc"] + if { $certificate_amount_to_reinstate > 0 } { + set certs_to_reinstate_list [list] + set certs_to_reinstate_list [db_list certs_to_reinstate_list_select " + select u.gift_certificate_id + from ec_gift_certificate_usage u, ec_gift_certificates c + where u.gift_certificate_id = c.gift_certificate_id + and u.order_id = :order_id + order by expires desc"] - # the amount used on that order - set certificate_amount_used [db_string certificate_amount_used_select "select ec_order_gift_cert_amount(:order_id) from dual"] + # The amount used on that order - if { $certificate_amount_used < $certificate_amount_to_reinstate } { - db_dml problems_log_insert "insert into ec_problems_log - (problem_id, problem_date, problem_details, order_id) - values - (ec_problem_id_sequence.nextval, sysdate, 'We were unable to reinstate the customer''s gift certificate balance because the amount to be reinstated was larger than the original amount used. This shouldn''t have happened unless there was a programming error or unless the database was incorrectly updated manually. The voiding of this order has been aborted.', :order_id) - " - ad_return_error "Gift Certificate Error" "We were unable to reinstate the customer's gift certificate balance because the amount to be reinstated was larger than the original amount used. This shouldn't have happened unless there was a programming error or unless the database was incorrectly updated manually.

    The voiding of this order has been aborted. This has been logged in the problems log." - return - } else { - # go through and reinstate certificates in order; it's not so bad - # to loop through all of them because I don't expect there to be - # many + set certificate_amount_used [db_string certificate_amount_used_select " + select ec_order_gift_cert_amount(:order_id) + from dual"] - set amount_to_reinstate $certificate_amount_to_reinstate - foreach cert $certs_to_reinstate_list { - if { $amount_to_reinstate > 0 } { - - # any amount up to the original amount used on this order can be reinstated - set reinstatable_amount [db_string reinstatable_amount_select "select ec_one_gift_cert_on_one_order(:cert,:order_id) from dual"] + if { $certificate_amount_used < $certificate_amount_to_reinstate } { + db_dml problems_log_insert " + insert into ec_problems_log + (problem_id, problem_date, problem_details, order_id) + values + (ec_problem_id_sequence.nextval, sysdate, 'We were unable to reinstate the customer''s gift certificate balance because the amount to be reinstated was larger than the original amount used. This shouldn''t have happened unless there was a programming error or unless the database was incorrectly updated manually. The voiding of this order has been aborted.', :order_id)" + ad_return_error "Gift Certificate Error" " +

    We were unable to reinstate the customer's gift certificate balance because the amount to be reinstated was larger than the original amount used. + This shouldn't have happened unless there was a programming error or unless the database was incorrectly updated manually.

    +

    The voiding of this order has been aborted. This has been logged in the problems log.

    " + return + } else { - if { $reinstatable_amount > 0 } { - set iteration_reinstate_amount [ec_min $reinstatable_amount $amount_to_reinstate] + # Go through and reinstate certificates in order; it's not + # so bad to loop through all of them because I don't + # expect there to be many + + set amount_to_reinstate $certificate_amount_to_reinstate + foreach cert $certs_to_reinstate_list { + if { $amount_to_reinstate > 0 } { - db_dml reinstate_gift_certificate_insert "insert into ec_gift_certificate_usage - (gift_certificate_id, order_id, amount_reinstated, reinstated_date) - values - (:cert, :order_id, :iteration_reinstate_amount, sysdate) - " - - set amount_to_reinstate [expr $amount_to_reinstate - $iteration_reinstate_amount] - } + # Any amount up to the original amount used on + # this order can be reinstated + + set reinstatable_amount [db_string reinstatable_amount_select " + select ec_one_gift_cert_on_one_order(:cert,:order_id) + from dual"] + + if { $reinstatable_amount > 0 } { + set iteration_reinstate_amount [ec_min $reinstatable_amount $amount_to_reinstate] + db_dml reinstate_gift_certificate_insert " + insert into ec_gift_certificate_usage + (gift_certificate_id, order_id, amount_reinstated, reinstated_date) + values + (:cert, :order_id, :iteration_reinstate_amount, sysdate)" + set amount_to_reinstate [expr $amount_to_reinstate - $iteration_reinstate_amount] + } + } + } } - } } - } } +# Check if a shipping gateway has been selected. + +set shipping_gateway [ad_parameter ShippingGateway] +if {[acs_sc_binding_exists_p ShippingGateway $shipping_gateway]} { + + # Replace the default ecommerce shipping calculations with the + # charges from the shipping gateway. Contact the shipping + # gateway to recalculate the total shipping charges. + + db_1row select_shipping_address " + select country_code, zip_code + from ec_addresses a, ec_orders o + where address_id = o.shipping_address + and o.order_id = :order_id" + + # Calculate the total value of the shipment. + + set shipment_value [db_string select_shipment_value " + select sum(coalesce(i.price_charged, 0)) + from ec_products p, ec_items i + where i.product_id = p.product_id + and p.no_shipping_avail_p = 'f' + and i.item_state not in ('void', 'received_back', 'expired') + and i.order_id = :order_id"] + set value_currency_code [ad_parameter Currency] + set weight_unit_of_measure [ad_parameter WeightUnits] + + # Get the list of services and their charges. + + set rates_and_services [acs_sc_call "ShippingGateway" "RatesAndServicesSelection" \ + [list "" "" "$country_code" "$zip_code" "$shipment_value" "$value_currency_code" "" "$weight_unit_of_measure"] \ + "$shipping_gateway"] + + # Find the charges for the selected service for the order. + + set shipping_method [db_string shipping_method_select " + select shipping_method + from ec_orders + where order_id = :order_id"] + + foreach service $rates_and_services { + array set rate_and_service $service + set order_shipping_cost $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"] + + # Unfortunately checking on the description of the + # shipping service is required as only the description is + # stored with the order as the shipping method. + + if {[string equal $service_description $shipping_method]} { + break + } + } + + # Calculate the tax on shipping and update the shipping cost + # of the order. + + set tax_on_order_shipping_cost [db_string get_shipping_tax " + select ec_tax(0, :order_shipping_cost, :order_id)"] + + 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" + +} + ad_returnredirect "one?[export_url_vars order_id]" Index: openacs-4/packages/ecommerce/www/admin/orders/items-void.tcl =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/ecommerce/www/admin/orders/items-void.tcl,v diff -u -r1.1 -r1.2 --- openacs-4/packages/ecommerce/www/admin/orders/items-void.tcl 20 Apr 2001 20:51:14 -0000 1.1 +++ openacs-4/packages/ecommerce/www/admin/orders/items-void.tcl 26 May 2002 04:36:50 -0000 1.2 @@ -1,114 +1,151 @@ -# /www/[ec_url_concat [ec_url] /admin]/orders/items-void.tcl ad_page_contract { - @author Eve Andersson (eveander@arsdigita.com) - @creation-date Summer 1999 - @cvs-id items-void.tcl,v 3.2.6.3 2000/08/17 15:19:15 seb Exp - @author ported by Jerry Asher (jerry@theashergroup.com) + @author Eve Andersson (eveander@arsdigita.com) + @creation-date Summer 1999 + @author ported by Jerry Asher (jerry@theashergroup.com) + @author revised by Bart Teeuwisse + @revision-date April 2002 + } { - order_id:integer,notnull - product_id:integer,notnull + order_id:integer,notnull + product_id:integer,notnull } ad_require_permission [ad_conn package_id] admin -# in case they reload this page after completing the void process: -if { [db_string num_non_void_items_select "select count(*) from ec_items where order_id=:order_id and product_id=:product_id and item_state<>'void'"] == 0 } { - ad_return_complaint 1 "
  • These items are already void; perhaps you are using an old form. Return to the order." +# In case they reload this page after completing the void process: + +if { [db_string num_non_void_items_select " + select count(*) + from ec_items + where order_id = :order_id + and product_id = :product_id + and item_state <> 'void'"] == 0 } { + ad_return_complaint 1 " +
  • These items are already void; perhaps you are using an old form. Return to the order.
  • " return } -set n_items [db_string num_items_select "select count(*) from ec_items where order_id=:order_id and product_id=:product_id"] +set n_items [db_string num_items_select " + select count(*) + from ec_items + where order_id = :order_id + and product_id = :product_id"] if { $n_items > 1 } { set item_or_items "Items" } else { set item_or_items "Item" } -doc_body_append "[ad_admin_header "Void $item_or_items"] +doc_body_append " + [ad_admin_header "Void $item_or_items"] -

    Void $item_or_items

    +

    Void $item_or_items

    + + [ad_admin_context_bar [list "../" "Ecommerce([ec_system_name])"] [list "index" "Orders"] [list "one?[export_url_vars order_id]" "One Order"] "$item_or_items"] -[ad_admin_context_bar [list "../" "Ecommerce([ec_system_name])"] [list "index" "Orders"] [list "one?[export_url_vars order_id]" "One Order"] "$item_or_items"] +
    +
    +
    + [export_form_vars order_id product_id]" -
    -
    - -[export_form_vars order_id product_id] -" - -# we have to take care of some cases (hopefully #1, the simplest, will be most -# prevalent) -# different cases get different wording and cases 1-2 are functionally different -# than cases 3-4 -# 1. there's only one item in this order with this product_id and it hasn't shipped yet -# 2. there's only one item in this order with this product_id and it's already shipped -# 3. more than one item in this order with this product_id and no non-void items have +# We have to take care of some cases (hopefully #1, the simplest, will +# be most prevalent) different cases get different wording and cases +# 1-2 are functionally different than cases 3-4 +# 1. There's only one item in this order with this product_id and it +# hasn't shipped yet +# 2. There's only one item in this order with this product_id and it's # already shipped -# 4. more than one item in this order with this product_id and at least one non-void -# item has already shipped +# 3. More than one item in this order with this product_id and no +# non-void items have already shipped +# 4. More than one item in this order with this product_id and at +# least one non-void item has already shipped if { $n_items == 1 } { - # cases 1 & 2 (only differ by a warning message) - # we assume it's not void, otherwise they wouldn't have been given the link to + + # Cases 1 & 2 (only differ by a warning message) we assume it's + # not void, otherwise they wouldn't have been given the link to # this page - set item_state [db_string item_state_select "select item_state from ec_items where order_id=:order_id and product_id=:product_id"] + set item_state [db_string item_state_select " + select item_state + from ec_items + where order_id = :order_id + and product_id = :product_id"] + if { $item_state == "shipped" || $item_state == "arrived" || $item_state == "received_back" } { - doc_body_append "Warning: our records show that this item has already - shipped, which means that the customer has already been charged for this - item. Voiding an item will not cause the customer's credit card to be - refunded (you can only do that by marking it \"received back\"). -

    - " + doc_body_append " +

    Warning: our records show that this item has already + shipped, which means that the customer has already been charged for this + item. Voiding an item will not cause the customer's credit card to be + refunded (you can only do that by marking it \"received back\").

    " } - doc_body_append "Please confirm that you want to void this item. - " + db_foreach order_products_select " + select i.item_id, i.item_state, p.product_name, i.price_name, i.price_charged + from ec_items i, ec_products p + where i.product_id = p.product_id + and i.order_id = :order_id + and i.product_id = :product_id" { + + doc_body_append " +

    Please confirm that you want to void $product_name; $price_name: [ec_pretty_price $price_charged] $item_state

    " + } } else { - # cases 3 & 4 (only differ by a warning message) - set n_shipped_items [db_string num_shipped_items_select "select count(*) from ec_items where order_id=:order_id and product_id=:product_id and item_state in ('shipped','arrived','received_back')"] + # Cases 3 & 4 (only differ by a warning message) + + set n_shipped_items [db_string num_shipped_items_select " + select count(*) + from ec_items + where order_id = :order_id + and product_id=:product_id + and item_state in ('shipped','arrived','received_back')"] + if { $n_shipped_items > 0 } { - doc_body_append "Warning: our records show that at least one of these - items has already shipped, which means that the customer has already - been charged (for shipped items only). Voiding an item will not cause - the customer's credit card to be refunded (you can only do that by marking - it \"received back\"). -

    - " + doc_body_append " +

    Warning: our records show that at least one of these + items has already shipped, which means that the customer has already + been charged (for shipped items only). Voiding an item will not cause + the customer's credit card to be refunded + (you can only do that by marking it \"received back\").

    " } - doc_body_append "Please check off the item(s) you wish to void. - - " + doc_body_append " +

    Please check off the item(s) you wish to void.

    +
    Void ItemProductItem State
    + + + + " - db_foreach order_products_select "select i.item_id, i.item_state, p.product_name, i.price_name, i.price_charged - from ec_items i, ec_products p - where i.product_id=p.product_id - and i.order_id=:order_id - and i.product_id=:product_id" { - doc_body_append " + " + doc_body_append " + + + " } - doc_body_append "
    Void ItemProductItem State
    " + db_foreach order_products_select " + select i.item_id, i.item_state, p.product_name, i.price_name, i.price_charged + from ec_items i, ec_products p + where i.product_id = p.product_id + and i.order_id = :order_id + and i.product_id = :product_id" { + + doc_body_append " +
    " if { $item_state == "void" } { doc_body_append " (already void) " } else { - doc_body_append "" + doc_body_append "" } - doc_body_append "$product_name; $price_name: [ec_pretty_price $price_charged]$item_state
    $product_name; $price_name: [ec_pretty_price $price_charged]$item_state
    " - } -doc_body_append "

    - -

    -
    - -
    - -
    - -[ad_admin_footer] -" +doc_body_append " +
    +
    + +
    + + [ad_admin_footer]" Index: openacs-4/packages/ecommerce/www/admin/orders/one.tcl =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/ecommerce/www/admin/orders/one.tcl,v diff -u -r1.1 -r1.2 --- openacs-4/packages/ecommerce/www/admin/orders/one.tcl 20 Apr 2001 20:51:14 -0000 1.1 +++ openacs-4/packages/ecommerce/www/admin/orders/one.tcl 26 May 2002 04:36:50 -0000 1.2 @@ -1,101 +1,100 @@ -# /www/[ec_url_concat [ec_url] /admin]/orders/one.tcl ad_page_contract { - Display one order. - @author Eve Andersson (eveander@arsdigita.com) - @creation-date Summer 1999 - @cvs-id one.tcl,v 3.5.2.4 2000/08/17 15:19:15 seb Exp - @author ported by Jerry Asher (jerry@theashergroup.com) + Display one order. + + @author Eve Andersson (eveander@arsdigita.com) + @creation-date Summer 1999 + @author ported by Jerry Asher (jerry@theashergroup.com) + @author revised by Bart Teeuwisse + @revision-date April 2002 + } { - order_id:integer,notnull + order_id:integer,notnull } ad_require_permission [ad_conn package_id] admin db_1row order_select " -select o.order_state, o.creditcard_id, o.confirmed_date, o.cs_comments, - o.shipping_method, o.shipping_address, o.in_basket_date, - o.authorized_date, o.shipping_charged, o.voided_by, o.voided_date, - o.reason_for_void, u.user_id, u.first_names, u.last_name -from ec_orders o, cc_users u -where order_id=:order_id -and o.user_id = u.user_id(+) -" + select o.order_state, o.creditcard_id, o.confirmed_date, o.cs_comments, + o.shipping_method, o.shipping_address, o.in_basket_date, + o.authorized_date, o.shipping_charged, o.voided_by, o.voided_date, + o.reason_for_void, u.user_id, u.first_names, u.last_name, c.billing_address + from ec_orders o, cc_users u, ec_creditcards + where order_id=:order_id + and o.user_id = u.user_id(+) + and o.creditcard_id = c.creditcard_id(+)" -doc_body_append "[ad_admin_header "One Order"] +doc_body_append " + [ad_admin_header "One Order"] -

    One Order

    +

    One Order

    -[ad_admin_context_bar [list "../" "Ecommerce([ec_system_name])"] [list "index" "Orders"] "One Order"] + [ad_admin_context_bar [list "../" "Ecommerce([ec_system_name])"] [list "index" "Orders"] "One Order"] -
    +
    -

    Overview

    +

    Overview

    -[ec_decode $order_state "void" "" "
    "] - - - - - - - - - - - - - - - - - -
    Order ID$order_id[ec_decode $order_state "void" "" "
    [ec_formatted_price_shipping_gift_certificate_and_tax_in_an_order $order_id]
    "]
    Ordered by$first_names $last_name
    Confirmed date[util_AnsiDatetoPrettyDate $confirmed_date]
    Order state[ec_decode $order_state "void" "void" $order_state]
    -

    + [ec_decode $order_state "void" "" "
    "] + + + + + + + + + + + + + + + + + +
    Order ID$order_id[ec_decode $order_state "void" "" "
    [ec_formatted_price_shipping_gift_certificate_and_tax_in_an_order $order_id]
    "]
    Ordered by$first_names $last_name
    Confirmed date[ec_formatted_full_date $confirmed_date]
    Order state[ec_decode $order_state "void" "void" $order_state]
    " -

    -" - if { $order_state == "void" } { - doc_body_append "

    Details of Void

    -
    -Voided by: [db_string voided_by_name_select "select first_names || ' ' || last_name from cc_users where user_id=:voided_by" -default ""] -
    -Date: [util_AnsiDatetoPrettyDate $voided_date] -
    -[ec_decode $reason_for_void "" "" "Reason: [ec_display_as_html $reason_for_void]"] -
    -" + doc_body_append " +

    Details of Void

    + +
    + Voided by: [db_string voided_by_name_select " + select first_names || ' ' || last_name from cc_users where user_id = :voided_by" -default ""]
    + Date: [ec_formatted_full_date $voided_date]
    + [ec_decode $reason_for_void "" "" "Reason: [ec_display_as_html $reason_for_void]"] +
    " } doc_body_append " -[ec_decode $cs_comments "" "" "

    Comments

    \n
    [ec_display_as_html $cs_comments]
    "] + [ec_decode $cs_comments "" "" "

    Comments

    \n
    [ec_display_as_html $cs_comments]
    "] - + -

    Items

    -
      -" +

      Items

      +
        " set items_ul "" # We want to display these by item (with all order states in parentheses), like: -# Quantity 3: #2 Standard Pencils; Our Price: $0.99 (2 shipped, 1 to_be_shipped). +# Quantity 3: 2 Standard Pencils; Our Price: $0.99 (2 shipped, 1 to_be_shipped). # This UI will break if the customer has more than one of the same product with # different prices in the same order (the shipment summary is by product_id). set old_product_color_size_style_price_price_name [list] -# set old_product_id 0 set item_quantity 0 set state_list [list] -db_foreach products_select "select p.product_name, p.product_id, i.price_name, i.price_charged, count(*) as quantity, i.item_state, i.color_choice, i.size_choice, i.style_choice -from ec_items i, ec_products p -where i.product_id=p.product_id -and i.order_id=:order_id -group by p.product_name, p.product_id, i.price_name, i.price_charged, i.item_state, i.color_choice, i.size_choice, i.style_choice" { +db_foreach products_select " + select p.product_name, p.product_id, i.price_name, i.price_charged, count(*) as quantity, i.item_state, i.color_choice, i.size_choice, i.style_choice + from ec_items i, ec_products p + where i.product_id=p.product_id + and i.order_id=:order_id + group by p.product_name, p.product_id, i.price_name, i.price_charged, i.item_state, i.color_choice, i.size_choice, i.style_choice" { + set product_color_size_style_price_price_name [list $product_id $color_choice $size_choice $style_choice $price_charged $price_name] set option_list [list] @@ -110,186 +109,220 @@ } set options [join $option_list ", "] - # it's OK to compare tcl lists with != because lists are really strings in tcl + # It's OK to compare tcl lists with != because lists are really + # strings in tcl + if { $product_color_size_style_price_price_name != $old_product_color_size_style_price_price_name && [llength $old_product_color_size_style_price_price_name] != 0 } { - append items_ul "
      • Quantity $item_quantity: - $item_description ([join $item_state_list ", "]) - " + append items_ul " +
      • + Quantity $item_quantity: $item_description ([join $item_state_list ", "])" if { [llength $item_state_list] != 1 || [lindex [split [lindex $item_state_list 0] " "] 1] != "void" } { + # i.e., if the items of this product_id are not all void # (I know that "if" statement could be written more compactly, # but I didn't want to offend Philip by relying on Tcl's internal # representation of a list) # EVE: have to make items-void.tcl take more than just product_id - append items_ul "(remove)" + + append items_ul " + + (remove) + " } - - append items_ul "
        - [ec_shipment_summary_sub [lindex $old_product_color_size_style_price_price_name 0] [lindex $old_product_color_size_style_price_price_name 1] [lindex $old_product_color_size_style_price_price_name 2] [lindex $old_product_color_size_style_price_price_name 3] [lindex $old_product_color_size_style_price_price_name 4] [lindex $old_product_color_size_style_price_price_name 5] $order_id] - " + append items_ul " +
        + [ec_shipment_summary_sub [lindex $old_product_color_size_style_price_price_name 0] [lindex $old_product_color_size_style_price_price_name 1] [lindex $old_product_color_size_style_price_price_name 2] [lindex $old_product_color_size_style_price_price_name 3] [lindex $old_product_color_size_style_price_price_name 4] [lindex $old_product_color_size_style_price_price_name 5] $order_id] +
      • " set item_state_list [list] set item_quantity 0 } lappend item_state_list "$quantity $item_state" set item_quantity [expr $item_quantity + $quantity] - set item_description "$product_name; [ec_decode $options "" "" "$options; "]$price_name: [ec_pretty_price $price_charged]" + set item_description " + $product_name; + [ec_decode $options "" "" "$options; "]$price_name: [ec_pretty_price $price_charged]" set old_product_color_size_style_price_price_name [list $product_id $color_choice $size_choice $style_choice $price_charged $price_name] } if { [llength $old_product_color_size_style_price_price_name] != 0 } { + # append the last line - append items_ul "
      • Quantity $item_quantity: - $item_description ([join $item_state_list ", "]) - " + + append items_ul " +
      • + Quantity $item_quantity: $item_description ([join $item_state_list ", "])" if { [llength $item_state_list] != 1 || [lindex [split [lindex $item_state_list 0] " "] 1] != "void" } { - # i.e., if the items of this product_id are not all void - append items_ul "(remove)" + + # I.e., if the items of this product_id are not all void + + append items_ul " + + (remove) + " } - append items_ul "
        - [ec_shipment_summary_sub [lindex $old_product_color_size_style_price_price_name 0] [lindex $old_product_color_size_style_price_price_name 1] [lindex $old_product_color_size_style_price_price_name 2] [lindex $old_product_color_size_style_price_price_name 3] [lindex $old_product_color_size_style_price_price_name 4] [lindex $old_product_color_size_style_price_price_name 5] $order_id] - " + append items_ul " +
        + [ec_shipment_summary_sub [lindex $old_product_color_size_style_price_price_name 0] [lindex $old_product_color_size_style_price_price_name 1] [lindex $old_product_color_size_style_price_price_name 2] [lindex $old_product_color_size_style_price_price_name 3] [lindex $old_product_color_size_style_price_price_name 4] [lindex $old_product_color_size_style_price_price_name 5] $order_id] +
      • " } doc_body_append "$items_ul" -if { $order_state == "authorized_plus_avs" || $order_state == "authorized_minus_avs" || $order_state == "partially_fulfilled" } { - doc_body_append "

        -

      • Record a Shipment -
      • Add Items - " +if { $order_state == "authorized" || $order_state == "partially_fulfilled" } { + doc_body_append " +
      • Record a Shipment
      • +
      • Add Items
      • " } if { $order_state == "fulfilled" || $order_state == "partially_fulfilled" } { - doc_body_append "

      • Mark Items Returned" + doc_body_append " +
      • Mark Items Returned
      • " } -doc_body_append "
      +doc_body_append " +
    -

    +

    Details

    + + + + + + + + + + + + + + + + + + + + +
    [ec_decode $shipping_method "pickup" "Address" "no shipping" "Address" "Ship to"][ec_display_as_html [ec_pretty_mailing_address_from_ec_addresses $shipping_address]]
    " -

    Details

    - - - - - - -" + + " if { ![empty_string_p $creditcard_id] } { - doc_body_append " - - - \n" + doc_body_append " + + + + + + " } doc_body_append " - - - - - - - - - - - - - - - - -
    [ec_decode $shipping_method "pickup" "Address" "no shipping" "Address" "Ship to"][ec_display_as_html [ec_pretty_mailing_address_from_ec_addresses $shipping_address]]
    -" -if { $order_state == "confirmed" || $order_state == "authorized_plus_avs" || $order_state == "authorized_minus_avs" || $order_state == "partially_fulfilled" } { - doc_body_append "(modify)" +if { $order_state == "confirmed" || $order_state == "authorized" || $order_state == "partially_fulfilled" } { + doc_body_append " + (modify)" } + doc_body_append " -
    Credit card[ec_display_as_html [ec_creditcard_summary $creditcard_id] ] -
    - (modify)
    Bill to[ec_display_as_html [ec_pretty_mailing_address_from_ec_addresses $billing_address]]
    + (modify)
    Credit card[ec_display_as_html [ec_creditcard_summary $creditcard_id] ]
    + (modify)
    In basket date[util_AnsiDatetoPrettyDate $in_basket_date]
    Confirmed date[util_AnsiDatetoPrettyDate $confirmed_date]
    Authorized date[util_AnsiDatetoPrettyDate $authorized_date]
    Base shipping charged[ec_pretty_price $shipping_charged] [ec_decode $shipping_method "pickup" "(Pickup)" "no shipping" "(No Shipping)" ""]
    +
    In basket date[ec_formatted_full_date $in_basket_date]
    Confirmed date[ec_formatted_full_date $confirmed_date]
    Authorized date[ec_formatted_full_date $authorized_date]
    Base shipping charged[ec_pretty_price $shipping_charged] [ec_decode $shipping_method "pickup" "(Pickup)" "no shipping" "(No Shipping)" ""]
    + +

    Financial Transactions

    " -

    Financial Transactions

    -" +set table_header " + + + + + + + + + + + + + " -set table_header "
    IDDateCreditcard Last 4AmountTypeTo Be CapturedAuth DateMark DateRefund DateFailed
    - -" - set transaction_counter 0 -db_foreach financial_transactions_select "select t.transaction_id, t.inserted_date, t.transaction_amount, t.transaction_type, t.to_be_captured_p, t.authorized_date, t.marked_date, t.settled_date, t.refunded_date, t.refund_settled_date, t.failed_p, c.creditcard_last_four -from ec_financial_transactions t, ec_creditcards c -where t.creditcard_id=c.creditcard_id -and t.order_id=:order_id -order by transaction_id" { +db_foreach financial_transactions_select " + select t.transaction_id, t.inserted_date, t.transaction_amount, t.transaction_type, t.to_be_captured_p, t.authorized_date, + t.marked_date, t.refunded_date, t.failed_p, c.creditcard_last_four + from ec_financial_transactions t, ec_creditcards c + where t.creditcard_id=c.creditcard_id + and t.order_id=:order_id + order by transaction_id" { + if { $transaction_counter == 0 } { doc_body_append $table_header } - doc_body_append " - - - - - - - - - - - - - - " + doc_body_append " + + + + + + + + + + + + " incr transaction_counter -} - +} + if { $transaction_counter != 0 } { - doc_body_append "
    IDDateCreditcard Last 4AmountTypeTo Be CapturedAuth DateMark DateSett DateRefund DateRefund Sett DateFailed
    $transaction_id[ec_nbsp_if_null [util_AnsiDatetoPrettyDate $inserted_date]]$creditcard_last_four[ec_pretty_price $transaction_amount][ec_decode $transaction_type "charge" "authorization to charge" "intent to refund"][ec_nbsp_if_null [ec_decode $transaction_type "refund" "Yes" [ec_decode $to_be_captured_p "t" "Yes" "f" "No" ""]]][ec_nbsp_if_null [util_AnsiDatetoPrettyDate $authorized_date]][ec_nbsp_if_null [util_AnsiDatetoPrettyDate $marked_date]][ec_nbsp_if_null [util_AnsiDatetoPrettyDate $settled_date]][ec_nbsp_if_null [util_AnsiDatetoPrettyDate $refunded_date]][ec_nbsp_if_null [util_AnsiDatetoPrettyDate $refund_settled_date]][ec_nbsp_if_null [ec_decode $failed_p "t" "Yes" "f" "No" ""]]
    $transaction_id[ec_nbsp_if_null [ec_formatted_full_date $inserted_date]]$creditcard_last_four[ec_pretty_price $transaction_amount][ec_decode $transaction_type "charge" "authorization to charge" "intent to refund"][ec_nbsp_if_null [ec_decode $transaction_type "refund" "Yes" [ec_decode $to_be_captured_p "t" "Yes" "f" "No" ""]]][ec_nbsp_if_null [ec_formatted_full_date $authorized_date]][ec_nbsp_if_null [ec_formatted_full_date $marked_date]][ec_nbsp_if_null [ec_formatted_full_date $refunded_date]][ec_nbsp_if_null [ec_decode $failed_p "t" "Yes" "f" "No" ""]]
    - " + doc_body_append "" } else { doc_body_append "
    None Found
    " } doc_body_append " -

    Shipments

    -
    -" +

    Shipments

    +
    " set old_shipment_id 0 -db_foreach shipments_items_products_select "select s.shipment_id, s.address_id, s.shipment_date, s.expected_arrival_date, s.carrier, s.tracking_number, s.actual_arrival_date, s.actual_arrival_detail, p.product_name, p.product_id, i.price_name, i.price_charged, count(*) as quantity -from ec_shipments s, ec_items i, ec_products p -where i.shipment_id=s.shipment_id -and i.product_id=p.product_id -and s.order_id=:order_id -group by s.shipment_id, s.address_id, s.shipment_date, s.expected_arrival_date, s.carrier, s.tracking_number, s.actual_arrival_date, s.actual_arrival_detail, p.product_name, p.product_id, i.price_name, i.price_charged -order by s.shipment_id" { +db_foreach shipments_items_products_select " + select s.shipment_id, s.address_id, s.shipment_date, s.expected_arrival_date, s.carrier, s.tracking_number, s.actual_arrival_date, s.actual_arrival_detail, + p.product_name, p.product_id, i.price_name, i.price_charged, count(*) as quantity + from ec_shipments s, ec_items i, ec_products p + where i.shipment_id=s.shipment_id + and i.product_id=p.product_id + and s.order_id=:order_id + group by s.shipment_id, s.address_id, s.shipment_date, s.expected_arrival_date, s.carrier, s.tracking_number, s.actual_arrival_date, s.actual_arrival_detail, + p.product_name, p.product_id, i.price_name, i.price_charged + order by s.shipment_id" { if { $shipment_id != $old_shipment_id } { if { $old_shipment_id != 0 } { - doc_body_append " -
    -

    " + doc_body_append "" } - doc_body_append " - - - -
    Shipment ID: $shipment_id
    - Date: [util_AnsiDatetoPrettyDate $shipment_date]
    - [ec_decode $expected_arrival_date "" "" "Expected Arrival: [util_AnsiDatetoPrettyDate $expected_arrival_date]
    "] - [ec_decode $carrier "" "" "Carrier: $carrier
    "] - [ec_decode $tracking_number "" "" "Tracking #: $tracking_number
    "] - [ec_decode $actual_arrival_date "" "" "Actual Arrival Date: [util_AnsiDatetoPrettyDate $actual_arrival_date]
    "] - [ec_decode $actual_arrival_detail "" "" "Actual Arrival Detail: $actual_arrival_detail
    "] - (track) -
    [ec_display_as_html [ec_pretty_mailing_address_from_ec_addresses $address_id]]
    -

      - " + doc_body_append " + + + + + +
      + Shipment ID: $shipment_id
      + Date: [util_AnsiDatetoPrettyDate $shipment_date]
      + [ec_decode $expected_arrival_date "" "" "Expected Arrival: [util_AnsiDatetoPrettyDate $expected_arrival_date]
      "] + [ec_decode $carrier "" "" "Carrier: $carrier
      "] + [ec_decode $tracking_number "" "" "Tracking #: $tracking_number
      "] + [ec_decode $actual_arrival_date "" "" "Actual Arrival Date: [util_AnsiDatetoPrettyDate $actual_arrival_date]
      "] + [ec_decode $actual_arrival_detail "" "" "Actual Arrival Detail: $actual_arrival_detail
      "] + (track) +
      + [ec_display_as_html [ec_pretty_mailing_address_from_ec_addresses $address_id]] +
      +
        " } - doc_body_append "
      • Quantity $quantity: $product_name" + doc_body_append "
      • Quantity $quantity: $product_name
      • " set old_shipment_id $shipment_id } @@ -299,35 +332,36 @@ doc_body_append "
      " } -doc_body_append "
    -

    Returns

    -
    -" +doc_body_append " +
    +

    Returns

    + +
    " + set old_refund_id 0 -db_foreach refunds_select "select r.refund_id, r.refund_date, r.refunded_by, r.refund_reasons, r.refund_amount, u.first_names, u.last_name, p.product_name, p.product_id, i.price_name, i.price_charged, count(*) as quantity -from ec_refunds r, cc_users u, ec_items i, ec_products p -where r.order_id=:order_id -and r.refunded_by=u.user_id -and i.refund_id=r.refund_id -and p.product_id=i.product_id -group by r.refund_id, r.refund_date, r.refunded_by, r.refund_reasons, r.refund_amount, u.first_names, u.last_name, p.product_name, p.product_id, i.price_name, i.price_charged" { +db_foreach refunds_select " + select r.refund_id, r.refund_date, r.refunded_by, r.refund_reasons, r.refund_amount, u.first_names, u.last_name, p.product_name, p.product_id, i.price_name, i.price_charged, count(*) as quantity + from ec_refunds r, cc_users u, ec_items i, ec_products p + where r.order_id=:order_id + and r.refunded_by=u.user_id + and i.refund_id=r.refund_id + and p.product_id=i.product_id + group by r.refund_id, r.refund_date, r.refunded_by, r.refund_reasons, r.refund_amount, u.first_names, u.last_name, p.product_name, p.product_id, i.price_name, i.price_charged" { if { $refund_id != $old_refund_id } { if { $old_refund_id != 0 } { - doc_body_append " -
    -

    " + doc_body_append "" } - doc_body_append "Refund ID: $refund_id
    - Date: [util_AnsiDatetoPrettyDate $refund_date]
    - Amount: [ec_pretty_price $refund_amount]
    - Refunded by: $first_names $last_name
    - Reason: $refund_reasons -

      - " + doc_body_append " + Refund ID: $refund_id
      + Date: [ec_formatted_full_date $refund_date]
      + Amount: [ec_pretty_price $refund_amount]
      + Refunded by: $first_names $last_name
      + Reason: $refund_reasons +
        " } - doc_body_append "
      • Quantity $quantity: $product_name" + doc_body_append "
      • Quantity $quantity: $product_name
      • " set old_refund_id $refund_id } @@ -340,11 +374,10 @@ doc_body_append "
    " if { $order_state != "void" } { - doc_body_append "

    Actions

    -
      -
    • Void Order - " + doc_body_append " +

      Actions

      + -[ad_admin_footer] -" +[ad_admin_footer]" Index: openacs-4/packages/ecommerce/www/admin/orders/one.xql =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/ecommerce/www/admin/orders/one.xql,v diff -u -r1.1 -r1.2 --- openacs-4/packages/ecommerce/www/admin/orders/one.xql 10 Jul 2001 20:33:53 -0000 1.1 +++ openacs-4/packages/ecommerce/www/admin/orders/one.xql 26 May 2002 04:36:50 -0000 1.2 @@ -1,74 +1,74 @@ - - - -select o.order_state, o.creditcard_id, o.confirmed_date, o.cs_comments, - o.shipping_method, o.shipping_address, o.in_basket_date, - o.authorized_date, o.shipping_charged, o.voided_by, o.voided_date, - o.reason_for_void, u.user_id, u.first_names, u.last_name -from ec_orders o - LEFT JOIN cc_users u using (user_id) -where order_id=:order_id - - - - - - - - select first_names || ' ' || last_name from cc_users where user_id=:voided_by - - - - - - + + + select o.order_state, o.creditcard_id, o.confirmed_date, o.cs_comments, + o.shipping_method, o.shipping_address, o.in_basket_date, + o.authorized_date, o.shipping_charged, o.voided_by, o.voided_date, + o.reason_for_void, u.user_id, u.first_names, u.last_name, c.billing_address + from ec_orders o + left join cc_users u using (user_id) + left join ec_creditcards c using (creditcard_id) + where order_id=:order_id + + + + + + select first_names || ' ' || last_name + from cc_users + where user_id=:voided_by + + + + + select p.product_name, p.product_id, i.price_name, i.price_charged, count(*) as quantity, i.item_state, i.color_choice, i.size_choice, i.style_choice -from ec_items i, ec_products p -where i.product_id=p.product_id -and i.order_id=:order_id -group by p.product_name, p.product_id, i.price_name, i.price_charged, i.item_state, i.color_choice, i.size_choice, i.style_choice - - - - - - - select t.transaction_id, t.inserted_date, t.transaction_amount, t.transaction_type, t.to_be_captured_p, t.authorized_date, t.marked_date, t.settled_date, t.refunded_date, t.refund_settled_date, t.failed_p, c.creditcard_last_four -from ec_financial_transactions t, ec_creditcards c -where t.creditcard_id=c.creditcard_id -and t.order_id=:order_id -order by transaction_id - - - - - - - select s.shipment_id, s.address_id, s.shipment_date, s.expected_arrival_date, s.carrier, s.tracking_number, s.actual_arrival_date, s.actual_arrival_detail, p.product_name, p.product_id, i.price_name, i.price_charged, count(*) as quantity -from ec_shipments s, ec_items i, ec_products p -where i.shipment_id=s.shipment_id -and i.product_id=p.product_id -and s.order_id=:order_id -group by s.shipment_id, s.address_id, s.shipment_date, s.expected_arrival_date, s.carrier, s.tracking_number, s.actual_arrival_date, s.actual_arrival_detail, p.product_name, p.product_id, i.price_name, i.price_charged -order by s.shipment_id - - - - - - - select r.refund_id, r.refund_date, r.refunded_by, r.refund_reasons, r.refund_amount, u.first_names, u.last_name, p.product_name, p.product_id, i.price_name, i.price_charged, count(*) as quantity -from ec_refunds r, cc_users u, ec_items i, ec_products p -where r.order_id=:order_id -and r.refunded_by=u.user_id -and i.refund_id=r.refund_id -and p.product_id=i.product_id -group by r.refund_id, r.refund_date, r.refunded_by, r.refund_reasons, r.refund_amount, u.first_names, u.last_name, p.product_name, p.product_id, i.price_name, i.price_charged - - - - + from ec_items i, ec_products p + where i.product_id=p.product_id + and i.order_id=:order_id + group by p.product_name, p.product_id, i.price_name, i.price_charged, i.item_state, i.color_choice, i.size_choice, i.style_choice + + + + + + select t.transaction_id, t.inserted_date, t.transaction_amount, t.transaction_type, t.to_be_captured_p, + t.authorized_date, t.marked_date, t.refunded_date, t.failed_p, c.creditcard_last_four + from ec_financial_transactions t, ec_creditcards c + where t.creditcard_id=c.creditcard_id + and t.order_id=:order_id + order by transaction_id + + + + + + select s.shipment_id, s.address_id, s.shipment_date, s.expected_arrival_date, s.carrier, s.tracking_number, + s.actual_arrival_date, s.actual_arrival_detail, p.product_name, p.product_id, i.price_name, i.price_charged, count(*) as quantity + from ec_shipments s, ec_items i, ec_products p + where i.shipment_id=s.shipment_id + and i.product_id=p.product_id + and s.order_id=:order_id + group by s.shipment_id, s.address_id, s.shipment_date, s.expected_arrival_date, s.carrier, s.tracking_number, + s.actual_arrival_date, s.actual_arrival_detail, p.product_name, p.product_id, i.price_name, i.price_charged + order by s.shipment_id + + + + + + select r.refund_id, r.refund_date, r.refunded_by, r.refund_reasons, r.refund_amount, u.first_names, u.last_name, + p.product_name, p.product_id, i.price_name, i.price_charged, count(*) as quantity + from ec_refunds r, cc_users u, ec_items i, ec_products p + where r.order_id=:order_id + and r.refunded_by=u.user_id + and i.refund_id=r.refund_id + and p.product_id=i.product_id + group by r.refund_id, r.refund_date, r.refunded_by, r.refund_reasons, r.refund_amount, u.first_names, u.last_name, + p.product_name, p.product_id, i.price_name, i.price_charged + + + Index: openacs-4/packages/ecommerce/www/admin/orders/refunds.tcl =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/ecommerce/www/admin/orders/refunds.tcl,v diff -u -r1.2 -r1.3 --- openacs-4/packages/ecommerce/www/admin/orders/refunds.tcl 23 Jul 2001 06:02:16 -0000 1.2 +++ openacs-4/packages/ecommerce/www/admin/orders/refunds.tcl 26 May 2002 04:36:50 -0000 1.3 @@ -1,34 +1,36 @@ -# /www/[ec_url_concat [ec_url] /admin]/orders/refunds.tcl ad_page_contract { - View refunds. - @author Eve Andersson (eveander@arsdigita.com) - @creation-date Summer 1999 - @cvs-id refunds.tcl,v 3.2.2.3 2000/08/17 15:19:15 seb Exp - @author ported by Jerry Asher (jerry@theashergroup.com) + View refunds. + + @author Eve Andersson (eveander@arsdigita.com) + @creation-date Summer 1999 + @author ported by Jerry Asher (jerry@theashergroup.com) + @author revised by Bart Teeuwisse + @revision-date April 2002 + } { - {view_refund_date "all"} - {order_by "refund_id"} + {view_refund_date "last_24"} + {order_by "refund_id"} } ad_require_permission [ad_conn package_id] admin -doc_body_append "[ad_admin_header "Refund History"] +doc_body_append " + [ad_admin_header "Refund History"] -

      Refund History

      +

      Refund History

      + + [ad_admin_context_bar [list "../" "Ecommerce([ec_system_name])"] [list "index" "Orders"] "Refund History"] + +
      -[ad_admin_context_bar [list "../" "Ecommerce([ec_system_name])"] [list "index" "Orders"] "Refund History"] + + + + + +
      Refund Date
      " -
      - - - - - - - + +
      Refund Date
      -" - set refund_date_list [list [list last_24 "last 24 hrs"] [list last_week "last week"] [list last_month "last month"] [list all all]] set linked_refund_date_list [list] @@ -41,73 +43,75 @@ } } -doc_body_append "\[ [join $linked_refund_date_list " | "] \] +doc_body_append " + \[ [join $linked_refund_date_list " | "] \] +
      -
      + +
      " - -
      -" - if { $view_refund_date == "last_24" } { - #set refund_date_query_bit "and sysdate-r.refund_date <= 1" set refund_date_query_bit [db_map last_24] } elseif { $view_refund_date == "last_week" } { - #set refund_date_query_bit "and sysdate-r.refund_date <= 7" set refund_date_query_bit [db_map last_week] } elseif { $view_refund_date == "last_month" } { - #set refund_date_query_bit "and months_between(sysdate,r.refund_date) <= 1" set refund_date_query_bit [db_map last_month] } else { set refund_date_query_bit "" } set link_beginning "refunds?[export_url_vars view_refund_date]" -set order_by_clause [util_decode $order_by \ - "refund_id" "r.refund_id" \ - "refund_date" "r.refund_date" \ - "order_id" "r.order_id" \ - "refund_amount" "r.refund_amount" \ - "n_items" "n_items" \ - "name" "u.last_name, u.first_names"] +set order_by_clause [ec_decode $order_by \ + "refund_id" "r.refund_id" \ + "refund_date" "r.refund_date" \ + "order_id" "r.order_id" \ + "refund_amount" "r.refund_amount" \ + "n_items" "n_items" \ + "name" "u.last_name, u.first_names"] -set table_header " - - - - - - - -" +set table_header " +
      Refund IDDate RefundedOrder IDAmount# of ItemsBy
      + + + + + + + + " - set row_counter 0 -db_foreach refunds_select "select r.refund_id, r.refund_date, r.order_id, r.refund_amount, r.refunded_by, u.first_names, u.last_name, count(*) as n_items -from ec_refunds r, cc_users u, ec_items i -where r.refunded_by=u.user_id -and i.refund_id=r.refund_id -$refund_date_query_bit -group by r.refund_id, r.refund_date, r.order_id, r.refund_amount, r.refunded_by, u.first_names, u.last_name -order by $order_by_clause" { +db_foreach refunds_select " + select r.refund_id, r.refund_date, r.order_id, r.refund_amount, r.refunded_by, u.first_names, u.last_name, count(*) as n_items + from ec_refunds r, cc_users u, ec_items i + where r.refunded_by=u.user_id + and i.refund_id=r.refund_id + $refund_date_query_bit + group by r.refund_id, r.refund_date, r.order_id, r.refund_amount, r.refunded_by, u.first_names, u.last_name + order by $order_by_clause" { + if { $row_counter == 0 } { doc_body_append $table_header } - # even rows are white, odd are grey + + # Even rows are white, odd are grey + if { [expr floor($row_counter/2.)] == [expr $row_counter/2.] } { set bgcolor "white" } else { set bgcolor "ececec" } - doc_body_append " - - - - - - - " + doc_body_append " + + + + + + + " incr row_counter } @@ -117,7 +121,7 @@ doc_body_append "
      None Found
      " } -doc_body_append " +doc_body_append " + -[ad_admin_footer] -" + [ad_admin_footer]" Index: openacs-4/packages/ecommerce/www/admin/orders/revenue-oracle.xql =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/ecommerce/www/admin/orders/revenue-oracle.xql,v diff -u -r1.1 -r1.2 --- openacs-4/packages/ecommerce/www/admin/orders/revenue-oracle.xql 10 Jul 2001 20:33:53 -0000 1.1 +++ openacs-4/packages/ecommerce/www/admin/orders/revenue-oracle.xql 26 May 2002 04:36:50 -0000 1.2 @@ -1,66 +1,72 @@ - oracle8.1.6 + oracle8.1.6 - - - select to_char(inserted_date,'YYYY') as transaction_year, to_char(inserted_date,'Q') as transaction_quarter, sum(case when transaction_type = 'charge' then transaction_amount else -1*transaction_amount end) as revenue -from ec_fin_transactions_reportable -group by to_char(inserted_date,'YYYY'), to_char(inserted_date,'Q') -order by to_char(inserted_date,'YYYY') || to_char(inserted_date,'Q') - - - - - - + + + select to_char(inserted_date,'YYYY') as transaction_year, to_char(inserted_date,'Q') as transaction_quarter, + sum(case when transaction_type = 'charge' then transaction_amount else -1*transaction_amount end) as revenue + from ec_fin_transactions_reportable + group by to_char(inserted_date,'YYYY'), to_char(inserted_date,'Q') + order by to_char(inserted_date,'YYYY') || to_char(inserted_date,'Q') + + + + + select to_char(shipment_date,'YYYY') as shipment_year, -to_char(shipment_date,'Q') as shipment_quarter, -nvl(sum(bal_price_charged),0) as total_price_charged, -nvl(sum(bal_shipping_charged + case when mv.shipment_id = (select min(s2.shipment_id) from ec_shipments s2 where s2.order_id=mv.order_id) then (select nvl(o.shipping_charged else 0 end-nvl(o.shipping_refunded,0) from ec_orders o where o.order_id=mv.order_id),0)),0) as total_shipping_charged, -nvl(sum(bal_tax_charged + case when mv.shipment_id = (select min(s2.shipment_id) from ec_shipments s2 where s2.order_id=mv.order_id) then (select nvl(o.shipping_tax_charged else 0 end-nvl(o.shipping_tax_refunded,0) from ec_orders o where o.order_id=mv.order_id),0)),0) as total_tax_charged -from ec_items_money_view mv -group by to_char(shipment_date,'YYYY'), to_char(shipment_date,'Q') -order by to_char(shipment_date,'YYYY') || to_char(shipment_date,'Q') - - - - - - + to_char(shipment_date,'Q') as shipment_quarter, + nvl(sum(bal_price_charged),0) as total_price_charged, + nvl(sum(bal_shipping_charged + case when mv.shipment_id = ( + select min(s2.shipment_id) + from ec_shipments s2 + where s2.order_id=mv.order_id) then ( + select nvl(o.shipping_charged else 0 end-nvl(o.shipping_refunded,0) + from ec_orders o + where o.order_id=mv.order_id),0)),0) as total_shipping_charged, + nvl(sum(bal_tax_charged + case when mv.shipment_id = ( + select min(s2.shipment_id) + from ec_shipments s2 where s2.order_id=mv.order_id) then ( + select nvl(o.shipping_tax_charged else 0 end-nvl(o.shipping_tax_refunded,0) + from ec_orders o where o.order_id=mv.order_id),0)),0) as total_tax_charged + from ec_items_money_view mv + group by to_char(shipment_date,'YYYY'), to_char(shipment_date,'Q') + order by to_char(shipment_date,'YYYY') || to_char(shipment_date,'Q') + + + + + select to_char(issue_date,'YYYY') as issue_year, -to_char(issue_date,'Q') as issue_quarter, -nvl(sum(amount),0) as amount -from ec_gift_certificates where gift_certificate_state in ('authorized_plus_avs','authorized_minus_avs') -group by to_char(issue_date,'YYYY'), to_char(issue_date,'Q') -order by to_char(issue_date,'YYYY') || to_char(issue_date,'Q') - - - - - - + to_char(issue_date,'Q') as issue_quarter, + nvl(sum(amount),0) as amount + from ec_gift_certificates where gift_certificate_state = 'authorized' + group by to_char(issue_date,'YYYY'), to_char(issue_date,'Q') + order by to_char(issue_date,'YYYY') || to_char(issue_date,'Q') + + + + + select to_char(issue_date,'YYYY') as issue_year, -to_char(issue_date,'Q') as issue_quarter, -nvl(sum(amount),0) as amount -from ec_gift_certificates where gift_certificate_state in ('authorized_plus_avs','authorized_minus_avs') -group by to_char(issue_date,'YYYY'), to_char(issue_date,'Q') -order by to_char(issue_date,'YYYY') || to_char(issue_date,'Q') - - - - - - + to_char(issue_date,'Q') as issue_quarter, + nvl(sum(amount),0) as amount + from ec_gift_certificates where gift_certificate_state = 'authorized' + group by to_char(issue_date,'YYYY'), to_char(issue_date,'Q') + order by to_char(issue_date,'YYYY') || to_char(issue_date,'Q') + + + + + select to_char(expires,'YYYY') as expires_year, -to_char(expires,'Q') as expires_quarter, -nvl(sum(gift_certificate_amount_left(gift_certificate_id)),0) + nvl(sum(ec_gift_cert_unshipped_amount(gift_certificate_id)),0) as amount_outstanding -from ec_gift_certificates_approved -group by to_char(expires,'YYYY'), to_char(expires,'Q') -order by to_char(expires,'YYYY') || to_char(expires,'Q') - - + to_char(expires,'Q') as expires_quarter, + nvl(sum(gift_certificate_amount_left(gift_certificate_id)),0) + nvl(sum(ec_gift_cert_unshipped_amount(gift_certificate_id)),0) as amount_outstanding + from ec_gift_certificates_approved + group by to_char(expires,'YYYY'), to_char(expires,'Q') + order by to_char(expires,'YYYY') || to_char(expires,'Q') + + - Index: openacs-4/packages/ecommerce/www/admin/orders/revenue-postgresql.xql =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/ecommerce/www/admin/orders/revenue-postgresql.xql,v diff -u -r1.2 -r1.3 --- openacs-4/packages/ecommerce/www/admin/orders/revenue-postgresql.xql 23 Jul 2001 06:21:47 -0000 1.2 +++ openacs-4/packages/ecommerce/www/admin/orders/revenue-postgresql.xql 26 May 2002 04:36:50 -0000 1.3 @@ -1,78 +1,68 @@ - postgresql7.1 + postgresql7.1 - - - select to_char(inserted_date,'YYYY') as transaction_year, to_char(inserted_date,'Q') as transaction_quarter, sum(case when transaction_type = 'charge' then transaction_amount else -1*transaction_amount end) as revenue -from ec_fin_transactions_reportable -group by to_char(inserted_date,'YYYY'), to_char(inserted_date,'Q') -order by to_char(inserted_date,'YYYY') || to_char(inserted_date,'Q') - - - - - - + + + select to_char(inserted_date,'YYYY') as transaction_year, to_char(inserted_date,'Q') as transaction_quarter, + sum(case when transaction_type = 'charge' then transaction_amount else -1*transaction_amount end) as revenue + from ec_fin_transactions_reportable + group by to_char(inserted_date,'YYYY'), to_char(inserted_date,'Q') + order by to_char(inserted_date,'YYYY') || to_char(inserted_date,'Q') + + + + + select to_char(shipment_date,'YYYY') as shipment_year, -to_char(shipment_date,'Q') as shipment_quarter, -coalesce(sum(bal_price_charged),0) as total_price_charged, -coalesce( - sum(bal_shipping_charged + - case when mv.shipment_id = (select min(s2.shipment_id) from ec_shipments s2 where s2.order_id=mv.order_id) - then (select coalesce(o.shipping_charged,0) - coalesce(o.shipping_refunded,0) from ec_orders o where o.order_id=mv.order_id) - else 0 end - ) -,0) as total_shipping_charged, -coalesce( - sum(bal_tax_charged + - case when mv.shipment_id = (select min(s2.shipment_id) from ec_shipments s2 where s2.order_id=mv.order_id) - then (select coalesce(o.shipping_tax_charged,0) - coalesce(o.shipping_tax_refunded,0) from ec_orders o where o.order_id=mv.order_id) - else 0 end - ) -,0) as total_tax_charged -from ec_items_money_view mv -group by to_char(shipment_date,'YYYY'), to_char(shipment_date,'Q') -order by to_char(shipment_date,'YYYY') || to_char(shipment_date,'Q') - - - - - - + to_char(shipment_date,'Q') as shipment_quarter, + coalesce(sum(bal_price_charged),0) as total_price_charged, + coalesce(sum(bal_shipping_charged + + case when mv.shipment_id = (select min(s2.shipment_id) from ec_shipments s2 where s2.order_id=mv.order_id) + then (select coalesce(o.shipping_charged,0) - coalesce(o.shipping_refunded,0) from ec_orders o where o.order_id=mv.order_id) + else 0 end), 0) as total_shipping_charged, + coalesce(sum(bal_tax_charged + + case when mv.shipment_id = (select min(s2.shipment_id) from ec_shipments s2 where s2.order_id=mv.order_id) + then (select coalesce(o.shipping_tax_charged,0) - coalesce(o.shipping_tax_refunded,0) from ec_orders o where o.order_id=mv.order_id) + else 0 end), 0) as total_tax_charged + from ec_items_money_view mv + group by to_char(shipment_date,'YYYY'), to_char(shipment_date,'Q') + order by to_char(shipment_date,'YYYY') || to_char(shipment_date,'Q') + + + + + select to_char(issue_date,'YYYY') as issue_year, -to_char(issue_date,'Q') as issue_quarter, -coalesce(sum(amount),0) as amount -from ec_gift_certificates where gift_certificate_state in ('authorized_plus_avs','authorized_minus_avs') -group by to_char(issue_date,'YYYY'), to_char(issue_date,'Q') -order by to_char(issue_date,'YYYY') || to_char(issue_date,'Q') - - - - - - + to_char(issue_date,'Q') as issue_quarter, + coalesce(sum(amount),0) as amount + from ec_gift_certificates where gift_certificate_state = 'authorized' + group by to_char(issue_date,'YYYY'), to_char(issue_date,'Q') + order by to_char(issue_date,'YYYY') || to_char(issue_date,'Q') + + + + + select to_char(issue_date,'YYYY') as issue_year, -to_char(issue_date,'Q') as issue_quarter, -coalesce(sum(amount),0) as amount -from ec_gift_certificates where gift_certificate_state in ('authorized_plus_avs','authorized_minus_avs') -group by to_char(issue_date,'YYYY'), to_char(issue_date,'Q') -order by to_char(issue_date,'YYYY') || to_char(issue_date,'Q') - - + to_char(issue_date,'Q') as issue_quarter, + coalesce(sum(amount),0) as amount + from ec_gift_certificates where gift_certificate_state = 'authorized' + group by to_char(issue_date,'YYYY'), to_char(issue_date,'Q') + order by to_char(issue_date,'YYYY') || to_char(issue_date,'Q') + + - - - + + select to_char(expires,'YYYY') as expires_year, -to_char(expires,'Q') as expires_quarter, -coalesce(sum(gift_certificate_amount_left(gift_certificate_id)),0) + coalesce(sum(ec_gift_cert_unshipped_amount(gift_certificate_id)),0) as amount_outstanding -from ec_gift_certificates_approved -group by to_char(expires,'YYYY'), to_char(expires,'Q') -order by to_char(expires,'YYYY') || to_char(expires,'Q') - - - - + to_char(expires,'Q') as expires_quarter, + coalesce(sum(gift_certificate_amount_left(gift_certificate_id)),0) + coalesce(sum(ec_gift_cert_unshipped_amount(gift_certificate_id)),0) as amount_outstanding + from ec_gift_certificates_approved + group by to_char(expires,'YYYY'), to_char(expires,'Q') + order by to_char(expires,'YYYY') || to_char(expires,'Q') + + + Index: openacs-4/packages/ecommerce/www/admin/orders/revenue.tcl =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/ecommerce/www/admin/orders/revenue.tcl,v diff -u -r1.1 -r1.2 --- openacs-4/packages/ecommerce/www/admin/orders/revenue.tcl 20 Apr 2001 20:51:14 -0000 1.1 +++ openacs-4/packages/ecommerce/www/admin/orders/revenue.tcl 26 May 2002 04:36:50 -0000 1.2 @@ -1,11 +1,13 @@ -# /www/[ec_url_concat [ec_url] /admin]/orders/revenue.tcl ad_page_contract { - Financial reports. - @author Eve Andersson (eveander@arsdigita.com) - @creation-date Summer 1999 - @cvs-id revenue.tcl,v 3.1.2.3 2000/08/17 15:19:15 seb Exp - @author ported by Jerry Asher (jerry@theashergroup.com) + Financial reports. + + @author Eve Andersson (eveander@arsdigita.com) + @creation-date Summer 1999 + @author ported by Jerry Asher (jerry@theashergroup.com) + @author revised by Bart Teeuwisse + @revision-date March 2002 + } { } @@ -87,7 +89,7 @@ db_foreach gift_certificates_select "select to_char(issue_date,'YYYY') as issue_year, to_char(issue_date,'Q') as issue_quarter, nvl(sum(amount),0) as amount -from ec_gift_certificates where gift_certificate_state in ('authorized_plus_avs','authorized_minus_avs') +from ec_gift_certificates where gift_certificate_state = 'authorized' group by to_char(issue_date,'YYYY'), to_char(issue_date,'Q') order by to_char(issue_date,'YYYY') || to_char(issue_date,'Q')" { set amount_sum [expr $amount_sum + $amount] @@ -159,13 +161,13 @@
      1 Revenue: the actual amount of credit card charges minus the amount of credit card refunds.

      -2 Sales: the price charged, the shipping charged, and the tax charged (minus the amounts refunded) for shipped items (most companies recognize revenue when items are shipped so that they don't risk double counting an account receivable and an item in inventory; see the ecommerce chapter of Philip & Alex's Guide to Web Publishing). Note that this is different from revenue because revenue includes sales of gift certificates. Additionally, some products were paid for using gift certificates. +2 Sales: the price charged, the shipping charged, and the tax charged (minus the amounts refunded) for shipped items (most companies recognize revenue when items are shipped so that they don't risk double counting an account receivable and an item in inventory; see the ecommerce chapter of Philip & Alex's Guide to Web Publishing). Note that this is different from revenue because revenue includes sales of gift certificates. Additionally, some products were paid for using gift certificates.

      3 Gift Certificate Sales: the amount of gift certificates purchased (recognized on date of purchase).

      4 Gift Certificates Issued: the amount of gift certificates issued to customers free of charge by web site administrators.

      5 Gift Certificates Outstanding: gift certificates which have not yet been applied to shipped items (therefore they are -considered a liability). + considered a liability). [ad_admin_footer] " Index: openacs-4/packages/ecommerce/www/admin/orders/shipments.tcl =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/ecommerce/www/admin/orders/shipments.tcl,v diff -u -r1.2 -r1.3 --- openacs-4/packages/ecommerce/www/admin/orders/shipments.tcl 22 Jul 2001 07:04:48 -0000 1.2 +++ openacs-4/packages/ecommerce/www/admin/orders/shipments.tcl 26 May 2002 04:36:50 -0000 1.3 @@ -1,38 +1,41 @@ -# /www/[ec_url_concat [ec_url] /admin]/orders/shipments.tcl ad_page_contract { - @author Eve Andersson (eveander@arsdigita.com) - @creation-date Summer 1999 - @cvs-id shipments.tcl,v 3.2.2.4 2000/08/18 20:23:44 stevenp Exp - @author ported by Jerry Asher (jerry@theashergroup.com) + @author Eve Andersson (eveander@arsdigita.com) + @creation-date Summer 1999 + @author ported by Jerry Asher (jerry@theashergroup.com) + @author revised by Bart Teeuwisse + @revision-date April 2002 + } { - {view_carrier "all"} - {view_shipment_date "all"} - {order_by "shipment_id"} + {view_carrier "all"} + {view_shipment_date "last_24"} + {order_by "shipment_id"} } ad_require_permission [ad_conn package_id] admin -doc_body_append "[ad_admin_header "Shipment History"] +doc_body_append " + [ad_admin_header "Shipment History"] -

      Shipment History

      +

      Shipment History

      -[ad_admin_context_bar [list "../" "Ecommerce([ec_system_name])"] [list "index" "Orders"] "Shipment History"] + [ad_admin_context_bar [list "../" "Ecommerce([ec_system_name])"] [list "index" "Orders"] "Shipment History"] -
      +
      -
      Refund IDDate RefundedOrder IDAmount# of ItemsBy
      $refund_id[util_AnsiDatetoPrettyDate $refund_date]$order_id[ec_pretty_price $refund_amount]$n_items$last_name, $first_names
      $refund_id[util_AnsiDatetoPrettyDate $refund_date]$order_id[ec_pretty_price $refund_amount]$n_items$last_name, $first_names
      - - - - - -
      CarrierShipment Date
      -" + + + + + + + - + + +
      CarrierShipment Date
      " - - -set carrier_list [db_list get_carrier_list "select unique carrier from ec_shipments where carrier is not null order by carrier"] +set carrier_list [db_list get_carrier_list " + select unique carrier + from ec_shipments + where carrier is not null + order by carrier"] set carrier_list [concat "all" $carrier_list] set linked_carrier_list [list] @@ -45,10 +48,10 @@ } } -doc_body_append "\[ [join $linked_carrier_list " | "] \] - -" +doc_body_append " + \[ [join $linked_carrier_list " | "] \] + " set shipment_date_list [list [list last_24 "last 24 hrs"] [list last_week "last week"] [list last_month "last month"] [list all all]] @@ -62,14 +65,15 @@ } } -doc_body_append "\[ [join $linked_shipment_date_list " | "] \] +doc_body_append " + \[ [join $linked_shipment_date_list " | "] \] +
      -
      + +
      " - -
      -" - if { $view_carrier == "all" } { set carrier_query_bit "" } else { @@ -101,58 +105,54 @@ set link_beginning "shipments?[export_url_vars view_carrier view_shipment_date]" -set order_by_clause [util_decode $order_by \ - "shipment_id" "s.shipment_id" \ - "shipment_date" "s.shipment_date" \ - "order_id" "s.order_id" \ - "carrier" "s.carrier" \ - "n_items" "n_items" \ - "full_or_partial" "full_or_partial"] +set order_by_clause [ec_decode $order_by \ + "shipment_id" "s.shipment_id" \ + "shipment_date" "s.shipment_date" \ + "order_id" "s.order_id" \ + "carrier" "s.carrier" \ + "n_items" "n_items" \ + "full_or_partial" "full_or_partial"] -set table_header " - - - - - - - -" +set table_header " +
      Shipment IDDate ShippedOrder IDCarrier# of ItemsFull / Partial
      + + + + + + + + " -# set selection [ns_db select $db "select s.shipment_id, s.shipment_date, s.order_id, s.carrier, decode((select count(*) from ec_items where order_id=s.order_id),(select count(*) from ec_items where shipment_id=s.shipment_id),'Full','Partial') as full_or_partial, (select count(*) from ec_items where shipment_id=s.shipment_id) as n_items -# from ec_shipments s -# $where_clause -# order by $order_by"] - set row_counter 0 db_foreach shipments_select " -select s.shipment_id, - s.shipment_date, - s.order_id, - s.carrier, + select s.shipment_id, s.shipment_date, s.order_id, s.carrier, decode(nvl((select count(*) from ec_items where order_id=s.order_id),0),nvl((select count(*) from ec_items where shipment_id=s.shipment_id),0),'Full','Partial') as full_or_partial, nvl((select count(*) from ec_items where shipment_id=s.shipment_id),0) as n_items -from ec_shipments s -$where_clause -order by $order_by_clause" { + from ec_shipments s + $where_clause + order by $order_by_clause" { + if { $row_counter == 0 } { doc_body_append $table_header } - # even rows are white, odd are grey + + # Even rows are white, odd are grey + if { [expr floor($row_counter/2.)] == [expr $row_counter/2.] } { set bgcolor "white" } else { set bgcolor "ececec" } - doc_body_append " - - - - - - - " + doc_body_append " + + + + + + + " incr row_counter } @@ -162,7 +162,7 @@ doc_body_append "
      None Found
      " } -doc_body_append " +doc_body_append " + -[ad_admin_footer] -" + [ad_admin_footer]" Index: openacs-4/packages/ecommerce/www/admin/problems/index-oracle.xql =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/ecommerce/www/admin/problems/index-oracle.xql,v diff -u -r1.1 -r1.2 --- openacs-4/packages/ecommerce/www/admin/problems/index-oracle.xql 10 Jul 2001 20:33:53 -0000 1.1 +++ openacs-4/packages/ecommerce/www/admin/problems/index-oracle.xql 26 May 2002 04:36:50 -0000 1.2 @@ -1,21 +1,22 @@ - oracle8.1.6 + oracle8.1.6 - - - - select - l.*, - u.first_names || ' ' || u.last_name as user_name - from ec_problems_log l, - cc_users u - where l.resolved_by = u.user_id(+) - $sql_clause - order by problem_date asc - - + + + and resolved_date is null + + - + + + select l.*, u.first_names || ' ' || u.last_name as user_name + from ec_problems_log l + where l.resolved_by = u.user_id(+) + $sql_clause + order by problem_date asc + + + Index: openacs-4/packages/ecommerce/www/admin/problems/index.tcl =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/ecommerce/www/admin/problems/index.tcl,v diff -u -r1.1 -r1.2 --- openacs-4/packages/ecommerce/www/admin/problems/index.tcl 20 Apr 2001 20:51:14 -0000 1.1 +++ openacs-4/packages/ecommerce/www/admin/problems/index.tcl 26 May 2002 04:36:50 -0000 1.2 @@ -1,83 +1,75 @@ -# www/[ec_url_concat [ec_url] /admin]/problems/index.tcl - ad_page_contract { - This page dislpays the problems in the problem log, if display_all is - not set then only unresolved problems are displayed. - @author Jesse Koontz (jkoontz@arsdigita.com) - @creation-date July 21, 1999 - @cvs-id index.tcl,v 3.2.2.3 2000/08/18 20:23:44 stevenp Exp - @author ported by Jerry Asher (jerry@theashergroup.com) + This page dislpays the problems in the problem log, if display_all is + not set then only unresolved problems are displayed. + + @author Jesse Koontz (jkoontz@arsdigita.com) + @creation-date July 21, 1999 + @author ported by Jerry Asher (jerry@theashergroup.com) + @author revised by Bart Teeuwisse + @revision-date April 2002 + } { - display_all:optional + display_all:optional } ad_require_permission [ad_conn package_id] admin -doc_body_append "[ad_admin_header "Potental Problems"] +doc_body_append " + [ad_admin_header "Potental Problems"] +

      Potential Problems

      -

      Potential Problems

      + [ad_admin_context_bar [list "[ec_url_concat [ec_url] /admin]/" Ecommerce([ec_system_name])] "Potential Problems"] +
      " -[ad_admin_context_bar [list "[ec_url_concat [ec_url] /admin]/" Ecommerce([ec_system_name])] "Potential Problems"] +set problem_count [db_string problem_count " + select count(*) + from ec_problems_log"] +set unresolved_problem_count [db_string unresolved_count " + select count(*) + from ec_problems_log where resolved_date is null"] -
      -" - -set problem_count [db_string unused_all "select count(*) from ec_problems_log"] -set unresolved_problem_count [db_string unused_null "select count(*) from ec_problems_log where resolved_date is null"] - if { ![info exists display_all] } { - set sql_clause "and resolved_date is null" + set sql_clause [db_map include_resolved_date] doc_body_append " - Unresolved Problems ($unresolved_problem_count) | All Problems ($problem_count) -

      - " +

      Unresolved Problems ($unresolved_problem_count) | + All Problems ($problem_count)

      " } else { set sql_clause "" doc_body_append " - Unresolved Problems ($unresolved_problem_count) | All Problems ($problem_count) -

      - " +

      Unresolved Problems ($unresolved_problem_count) | + All Problems ($problem_count)

      " } -doc_body_append " -
        -" +doc_body_append "
          " db_foreach problems_select " - select - l.*, - u.first_names || ' ' || u.last_name as user_name - from ec_problems_log l, - cc_users u - where l.resolved_by = u.user_id(+) - $sql_clause - order by problem_date asc" { - doc_body_append " -

          -

        • [util_AnsiDatetoPrettyDate $problem_date] (" + select l.*, u.first_names || ' ' || u.last_name as user_name + from ec_problems_log l, cc_users u + where l.resolved_by = u.user_id(+) + $sql_clause + order by problem_date asc" { - if { ![empty_string_p $order_id] } { - doc_body_append "order #$order_id | " - } + doc_body_append " +
        • [util_AnsiDatetoPrettyDate $problem_date] (" - if { [empty_string_p $resolved_date] } { - doc_body_append "mark resolved" - } else { - doc_body_append "resolved by [ec_admin_present_user $resolved_by $user_name] on [util_AnsiDatetoPrettyDate $resolved_date]" - } + if { ![empty_string_p $order_id] } { + doc_body_append "order #$order_id | " + } - doc_body_append ") -

          - $problem_details -

          - " + if { [empty_string_p $resolved_date] } { + doc_body_append "mark resolved" + } else { + doc_body_append "resolved by [ec_admin_present_user $resolved_by $user_name] on [util_AnsiDatetoPrettyDate $resolved_date]" + } + + doc_body_append ") +

          $problem_details

          +
        • " } doc_body_append " -
        +
      + [ad_admin_footer]" -[ad_admin_footer] -" - Index: openacs-4/packages/ecommerce/www/admin/problems/index.xql =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/ecommerce/www/admin/problems/index.xql,v diff -u -r1.1 -r1.2 --- openacs-4/packages/ecommerce/www/admin/problems/index.xql 10 Jul 2001 20:33:53 -0000 1.1 +++ openacs-4/packages/ecommerce/www/admin/problems/index.xql 26 May 2002 04:36:50 -0000 1.2 @@ -1,33 +1,19 @@ - - - select count(*) from ec_problems_log - - + + + select count(*) + from ec_problems_log + + + + + + select count(*) from + ec_problems_log + where resolved_date is null + + - - - - select count(*) from ec_problems_log where resolved_date is null - - - - - - - - select - l.*, - u.first_names || ' ' || u.last_name as user_name - from ec_problems_log l - LEFT JOIN cc_users u on (l.resolved_by = u.user_id) - $sql_clause - order by problem_date asc - - - - - - + \ No newline at end of file Index: openacs-4/packages/ecommerce/www/admin/products/add-2.xql =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/ecommerce/www/admin/products/add-2.xql,v diff -u -r1.1 -r1.2 --- openacs-4/packages/ecommerce/www/admin/products/add-2.xql 10 Jul 2001 20:33:53 -0000 1.1 +++ openacs-4/packages/ecommerce/www/admin/products/add-2.xql 26 May 2002 04:36:50 -0000 1.2 @@ -1,30 +1,27 @@ - - - - select column_type, field_identifier, field_name - from ec_custom_product_fields - where column_type in ('date','integer') - and active_p='t' - - - - - - - - select field_identifier from ec_custom_product_fields where active_p='t' - - - - - - + + + select column_type, field_identifier, field_name + from ec_custom_product_fields + where column_type in ('date','integer') + and active_p='t' + + + + + + select field_identifier + from ec_custom_product_fields + where active_p='t' + + + + + select user_class_id from ec_user_classes - - - - + + + Index: openacs-4/packages/ecommerce/www/admin/products/add-3.xql =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/ecommerce/www/admin/products/add-3.xql,v diff -u -r1.1 -r1.2 --- openacs-4/packages/ecommerce/www/admin/products/add-3.xql 10 Jul 2001 20:33:53 -0000 1.1 +++ openacs-4/packages/ecommerce/www/admin/products/add-3.xql 26 May 2002 04:36:50 -0000 1.2 @@ -1,47 +1,44 @@ - - - select user_class_id, user_class_name from ec_user_classes order by user_class_name - - - - - - - - select field_identifier, field_name, column_type - from ec_custom_product_fields - where active_p = 't' - - - - - - - - select template_name from ec_templates where template_id=:template_id - - - - - - - - select field_identifier, field_name, column_type - from ec_custom_product_fields - where active_p = 't' - - - - - - - - select user_class_id from ec_user_classes - - - - + + + select user_class_id, user_class_name + from ec_user_classes + order by user_class_name + + + + + + select field_identifier, field_name, column_type + from ec_custom_product_fields + where active_p = 't' + + + + + + select template_name + from ec_templates + where template_id=:template_id + + + + + + select field_identifier, field_name, column_type + from ec_custom_product_fields + where active_p = 't' + + + + + + select user_class_id, user_class_name + from ec_user_classes + order by user_class_name + + + Index: openacs-4/packages/ecommerce/www/admin/products/categories-upload-2.tcl =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/ecommerce/www/admin/products/categories-upload-2.tcl,v diff -u -r1.2 -r1.3 --- openacs-4/packages/ecommerce/www/admin/products/categories-upload-2.tcl 24 Nov 2001 03:34:36 -0000 1.2 +++ openacs-4/packages/ecommerce/www/admin/products/categories-upload-2.tcl 26 May 2002 04:36:50 -0000 1.3 @@ -58,7 +58,7 @@ select c.category_id, c.category_name, s.subcategory_id, s.subcategory_name from ec_subcategories s, ec_categories c where c.category_id = s.category_id - and upper(:category) like upper(subcategory_name) || '%'" { + and upper(:category) like upper(subcategory_name)" { set submatch_p 1 # add this product to the matched subcategory @@ -77,7 +77,7 @@ # see if this matches any categories set match_p 0 - db_foreach category_match_select "select category_id, category_name from ec_categories where upper(:category) like upper(category_name) || '%'" { + db_foreach category_match_select "select category_id, category_name from ec_categories where upper(:category) like upper(category_name)" { set match_p 1 set sql "insert into ec_category_product_map (product_id, category_id, publisher_favorite_p, last_modified, last_modifying_user, modified_ip_address) values (:product_id, :category_id, 'f', sysdate, :user_id, :ip)" if { [catch {db_dml category_insert $sql} errmsg] } { Index: openacs-4/packages/ecommerce/www/admin/products/categories-upload-2.xql =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/ecommerce/www/admin/products/categories-upload-2.xql,v diff -u -r1.1 -r1.2 --- openacs-4/packages/ecommerce/www/admin/products/categories-upload-2.xql 10 Jul 2001 20:33:53 -0000 1.1 +++ openacs-4/packages/ecommerce/www/admin/products/categories-upload-2.xql 26 May 2002 04:36:50 -0000 1.2 @@ -1,22 +1,21 @@ - - - - select c.category_id, c.category_name, s.subcategory_id, - s.subcategory_name from ec_subcategories s, ec_categories c - where c.category_id = s.category_id - and upper(:category) like upper(subcategory_name) || '%' - - - - - - - select category_id, category_name from ec_categories where upper(:category) like upper(category_name) || '%' - - - - + + + select c.category_id, c.category_name, s.subcategory_id, + s.subcategory_name from ec_subcategories s, ec_categories c + where c.category_id = s.category_id + and upper(:category) like upper(subcategory_name) + + + + + + select category_id, category_name + from ec_categories + where upper(:category) like upper(category_name) + + + Index: openacs-4/packages/ecommerce/www/admin/products/custom-field-add-2.tcl =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/ecommerce/www/admin/products/custom-field-add-2.tcl,v diff -u -r1.1 -r1.2 --- openacs-4/packages/ecommerce/www/admin/products/custom-field-add-2.tcl 20 Apr 2001 20:51:14 -0000 1.1 +++ openacs-4/packages/ecommerce/www/admin/products/custom-field-add-2.tcl 26 May 2002 04:36:50 -0000 1.2 @@ -1,16 +1,18 @@ -# www/[ec_url_concat [ec_url] /admin]/products/custom-field-add-2.tcl ad_page_contract { - Add a custom product field. - @author Eve Andersson (eveander@arsdigita.com) - @creation-date Summer 1999 - @cvs-id custom-field-add-2.tcl,v 3.2.2.2 2000/07/22 07:57:37 ron Exp - @author ported by Jerry Asher (jerry@theashergroup.com) + Add a custom product field. + + @author Eve Andersson (eveander@arsdigita.com) + @creation-date Summer 1999 + @author ported by Jerry Asher (jerry@theashergroup.com) + @author revised by Bart Teeuwisse + @revision-date April 2002 + } { - field_identifier - field_name - default_value - column_type + field_identifier + field_name + default_value + column_type } ad_require_permission [ad_conn package_id] admin @@ -22,79 +24,75 @@ if { [empty_string_p $field_identifier] } { incr exception_count - append exception_text "
    • You forgot to enter a unique identifier." + append exception_text "
    • You forgot to enter a unique identifier.
    • " } elseif { [regexp {[^a-z]} $field_identifier] } { incr exception_count - append exception_text "
    • The unique identifier can only contain lowercase letters; no other characters are allowed." + append exception_text "
    • The unique identifier can only contain lowercase letters; no other characters are allowed.
    • " } elseif { [string length $field_identifier] > 30 } { incr exception_count - append exception_text "
    • The unique identifier is too long. It can be at most 30 characters. The current length is [string length $field_identifier] characters." + append exception_text "
    • The unique identifier is too long. It can be at most 30 characters. The current length is [string length $field_identifier] characters.
    • " } else { if { [db_string dupliciate_field_identifier_select "select count(*) from ec_custom_product_fields where field_identifier=:field_identifier"] > 0 } { incr exception_count - append exception_text "
    • The identifier $field_identifier has already been used. Please choose another." + append exception_text "
    • The identifier $field_identifier has already been used. Please choose another.
    • " } elseif { [db_string ec_products_column_conflict_select "select count(*) from user_tab_columns where column_name=upper(:field_identifier) and table_name='EC_PRODUCTS'"] } { incr exception_count - append exception_text "
    • The identifier $field_identifer is already being used by the system in a different table. Please choose another identifier to avoid ambiguity." + append exception_text "
    • The identifier $field_identifer is already being used by the system in a different table. Please choose another identifier to avoid ambiguity.
    • " } } if { [empty_string_p $field_name] } { incr exception_count - append exception_text "
    • You forgot to enter a field name." + append exception_text "
    • You forgot to enter a field name.
    • " } if { [empty_string_p $column_type] } { incr exception_count - append exception_text "
    • You forgot to enter the kind of information." + append exception_text "
    • You forgot to enter the kind of information.
    • " } if { $exception_count > 0 } { ad_return_complaint $exception_count $exception_text return } -doc_body_append "[ad_admin_header "Confirm Custom Field"] +doc_body_append " + [ad_admin_header "Confirm Custom Field"] -

      Confirm Custom Field

      +

      Confirm Custom Field

      -[ad_admin_context_bar [list "../" "Ecommerce([ec_system_name])"] [list "index.tcl" "Products"] [list "custom-fields.tcl" "Custom Fields"] "Confirm New Custom Field"] + [ad_admin_context_bar [list "../" "Ecommerce([ec_system_name])"] [list "index.tcl" "Products"] [list "custom-fields.tcl" "Custom Fields"] "Confirm New Custom Field"] -
      +
      -
      Shipment IDDate ShippedOrder IDCarrier# of ItemsFull / Partial
      $shipment_id[ec_nbsp_if_null [util_AnsiDatetoPrettyDate $shipment_date]]$order_id[ec_nbsp_if_null $carrier]$n_items$full_or_partial
      $shipment_id[ec_nbsp_if_null [util_AnsiDatetoPrettyDate $shipment_date]]$order_id[ec_nbsp_if_null $carrier]$n_items$full_or_partial
      - - - - - - - - - - - - - - - - -
      Unique Identifier:$field_identifier
      Field Name:$field_name
      Default Value:$default_value
      Kind of Information:[ec_pretty_column_type $column_type]
      - -

      - -Please note that you can never remove a custom field, although you can deactivate it. Furthermore, the Unique -Identifier cannot be changed and, in most cases, neither can Kind of Information. - -

      - -

      -[export_form_vars field_identifier field_name default_value column_type] -
      - -
      -
      - -[ad_admin_footer] -" \ No newline at end of file + + + + + + + + + + + + + + + + + +
      Unique Identifier:$field_identifier
      Field Name:$field_name
      Default Value:$default_value
      Kind of Information:[ec_pretty_column_type $column_type]
      + +

      Please note that you can never remove a custom field, although + you can deactivate it. Furthermore, the Unique Identifier cannot + be changed and, in most cases, neither can Kind of Information.

      + +
      + [export_form_vars field_identifier field_name default_value column_type] +
      + +
      +
      + [ad_admin_footer]" Index: openacs-4/packages/ecommerce/www/admin/products/custom-field-add-3-oracle.xql =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/ecommerce/www/admin/products/custom-field-add-3-oracle.xql,v diff -u -r1.1 -r1.2 --- openacs-4/packages/ecommerce/www/admin/products/custom-field-add-3-oracle.xql 25 Aug 2001 05:34:13 -0000 1.1 +++ openacs-4/packages/ecommerce/www/admin/products/custom-field-add-3-oracle.xql 26 May 2002 04:36:50 -0000 1.2 @@ -1,41 +1,39 @@ - oracle8.1.6 + + oracle + 8.1.6 + - - - sysdate, :user_id, :peeraddr - - + + + insert into ec_custom_product_fields + (field_identifier, field_name, default_value, column_type, last_modified, last_modifying_user, modified_ip_address) + values + (:field_identifier, :field_name, :default_value, :column_type, sysdate, :user_id, :peeraddr) + + - - - + + alter table ec_custom_product_field_values add ( $field_identifier $column_type $end_of_alter) + + - - - - - - - + + alter table ec_custom_p_field_values_audit add ( $field_identifier $column_type) + + - - - - - - - alter table ec_custom_product_field_values drop column $field_identifier - - - - - - + + + alter table ec_custom_product_field_values + drop column $field_identifier + + + Index: openacs-4/packages/ecommerce/www/admin/products/custom-field-add-3-postgresql.xql =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/ecommerce/www/admin/products/custom-field-add-3-postgresql.xql,v diff -u -r1.1 -r1.2 --- openacs-4/packages/ecommerce/www/admin/products/custom-field-add-3-postgresql.xql 25 Aug 2001 05:34:13 -0000 1.1 +++ openacs-4/packages/ecommerce/www/admin/products/custom-field-add-3-postgresql.xql 26 May 2002 04:36:50 -0000 1.2 @@ -1,41 +1,60 @@ - postgresql7.1 + + postgresql + 7.1 + - - - current_timestamp, :user_id, :peeraddr - - + + + insert into ec_custom_product_fields + (field_identifier, field_name, default_value, column_type, last_modified, last_modifying_user, modified_ip_address) + values + (:field_identifier, :field_name, :default_value, :column_type, current_timestamp, :user_id, :peeraddr) + + + + + alter table ec_custom_product_field_values + add column $field_identifier $column_type $end_of_alter + + - - - alter table ec_custom_product_field_values add column - $field_identifier $column_type $end_of_alter - - + + + alter table ec_custom_p_field_values_audit + add column $field_identifier $column_type + + + + + -- PostgreSQL 7.1.3 can't drop columns and will fail on this query -- + alter table ec_custom_product_field_values + drop column $field_identifier + + - - + + + drop function ec_custom_p_f_values_audit_tr () + + - alter table ec_custom_p_field_values_audit add column - $field_identifier $column_type + + + drop trigger ec_custom_p_f_values_audit_tr on ec_custom_product_field_values + + - - + + + create trigger ec_custom_p_f_values_audit_tr + before update or delete on ec_custom_product_field_values + for each row execute procedure ec_custom_p_f_values_audit_tr () + + - - - - - alter table ec_custom_product_field_values drop column $field_identifier - - - - - - Index: openacs-4/packages/ecommerce/www/admin/products/custom-field-add-3.tcl =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/ecommerce/www/admin/products/custom-field-add-3.tcl,v diff -u -r1.2 -r1.3 --- openacs-4/packages/ecommerce/www/admin/products/custom-field-add-3.tcl 25 Aug 2001 05:33:37 -0000 1.2 +++ openacs-4/packages/ecommerce/www/admin/products/custom-field-add-3.tcl 26 May 2002 04:36:50 -0000 1.3 @@ -1,121 +1,175 @@ -# www/[ec_url_concat [ec_url] /admin]/products/custom-field-add-3.tcl ad_page_contract { - Add a custom product field. - @author Eve Andersson (eveander@arsdigita.com) - @creation-date Summer 1999 - @cvs-id custom-field-add-3.tcl,v 3.2.2.3 2000/08/20 11:20:43 seb Exp - @author ported by Jerry Asher (jerry@theashergroup.com) + Add a custom product field. + + @author Eve Andersson (eveander@arsdigita.com) + @creation-date Summer 1999 + @author ported by Jerry Asher (jerry@theashergroup.com) + @author revised by Bart Teeuwisse + @revision-date April 2002 + } { - field_identifier:sql_identifier - field_name - default_value - column_type + field_identifier:sql_identifier + field_name + default_value + column_type } ad_require_permission [ad_conn package_id] admin -# we need them to be logged in +# We need them to be logged in + set user_id [ad_get_user_id] +set peeraddr [ns_conn peeraddr] -# if the column type is boolean, we want to add a (named) check constraint at the end +# If the column type is boolean, we want to add a (named) check +# constraint at the end + if { $column_type == "char(1)" } { set end_of_alter ",\nconstraint ${field_identifier}_constraint check ($field_identifier in ('t', 'f'))" } else { set end_of_alter "" } +if { [db_string doubleclick_select " + select count(*) + from ec_custom_product_fields + where field_identifier=:field_identifier"] > 0 } { + # Then they probably just hit submit twice, so send them to + # custom-fields.tcl -if { [db_string doubleclick_select "select count(*) from ec_custom_product_fields where field_identifier=:field_identifier"] > 0 } { - # then they probably just hit submit twice, so send them to custom-fields.tcl ad_returnredirect "custom-fields" } -set peeraddr [ns_conn peeraddr] +if { [catch { db_dml custom_field_insert " + insert into ec_custom_product_fields + (field_identifier, field_name, default_value, column_type, last_modified, last_modifying_user, modified_ip_address) + values + (:field_identifier, :field_name, :default_value, :column_type, sysdate, :user_id, :peeraddr)"} errmsg]} { + ad_return_error "Unable to Add Field" " +

      Sorry, we were unable to add the field you requested.

      +

      Here's the error message:

      $errmsg

      " + return +} -set audit_fields "last_modified, last_modifying_user, modified_ip_address" -#set audit_info "sysdate, :user_id, :peeraddr" -set audit_info [db_map audit_info_sql] +# Have to alter ec_custom_product_field_values, the corresponding +# audit table, and the corresponding trigger -set insert_statement "insert into ec_custom_product_fields -(field_identifier, field_name, default_value, column_type, $audit_fields) -values -(:field_identifier, :field_name, :default_value, :column_type, $audit_info)" +if {[catch { db_dml alter_ec_custom_field_values_table " + alter table ec_custom_product_field_values + add ($field_identifier $column_type $end_of_alter)"} errmsg]} { -if [catch { db_dml custom_product_field_insert $insert_statement } errmsg] { - ad_return_error "Unable to Add Field" "Sorry, we were unable to add the field you requested. Here's the error message:
      $errmsg
      " + # This means we were unable to add the column to + # ec_custom_product_field_values, so undo the insert into + # ec_custom_product_fields + + db_dml custom_field_delete " + delete from ec_custom_product_fields + where field_identifier = :field_identifier" + ad_return_error "Unable to Add Field" " +

      Sorry, we were unable to add the field you requested.

      +

      The error occurred when adding the column $field_identifier to ec_custom_product_field_values, + so we've deleted the row containing $field_identifier from ec_custom_product_fields as well (for consistency).

      +

      Here's the error message:

      $errmsg

      " return } -# have to alter ec_custom_product_field_values, the corresponding audit -# table, and the corresponding trigger +if {[catch {db_dml alter_ec_custom_field_values_audit_table " + alter table ec_custom_p_field_values_audit + add ($field_identifier $column_type)"} errmsg]} { -#set alter_statement "alter table ec_custom_product_field_values add ( -# $field_identifier $column_type$end_of_alter -##)" -set alter_statement [db_map alter_statement_sql] + # This means we were unable to add the column to + # ec_custom_p_field_values_audit, so undo the insert into + # ec_custom_product_fields and the alteration to + # ec_custom_product_field_values -if [catch { db_dml alter_table $alter_statement } errmsg] { - # this means we were unable to add the column to ec_custom_product_field_values, so undo the insert into ec_custom_product_fields - db_dml custom_field_delete "delete from ec_custom_product_fields where field_identifier=:field_identifier" - ad_return_error "Unable to Add Field" "Sorry, we were unable to add the field you requested. The error occurred when adding the column $field_identifier to ec_custom_product_field_values, so we've deleted the row containing $field_identifier from ec_custom_product_fields as well (for consistency). Here's the error message:

      $errmsg
      " + db_dml custom_field_delete " + delete from ec_custom_product_fields + where field_identifier = :field_identifier" + db_dml custom_field_drop " + alter table ec_custom_product_field_values + drop column $field_identifier" + ad_return_error "Unable to Add Field" " +

      Sorry, we were unable to add the field you requested.

      +

      The error occurred when adding the column $field_identifier to ec_custom_p_field_values_audit, + so we've dropped that column from ec_custom_product_field_values and we've deleted the row containing $field_identifier + from ec_custom_product_fields as well (for consistency).

      +

      Here's the error message:

      $errmsg

      " return } -# 1999-08-10: took out $end_of_alter because the constraints don't -# belong in the audit table +# Determine what the new trigger should be -#set alter_statement_2 "alter table ec_custom_p_field_values_audit add ( -# $field_identifier $column_type -#)" -set alter_statement_2 [db_map alter_statement_2_sql] +set database_type [db_type] +switch -exact $database_type { -if [catch {db_dml alter_table_2 $alter_statement_2} errmsg] { - # this means we were unable to add the column to ec_custom_p_field_values_audit, so undo the insert into ec_custom_product_fields and the alteration to ec_custom_product_field_values - db_dml custom_field_delete "delete from ec_custom_product_fields where field_identifier=:field_identifier" - db_dml custom_field_drop "alter table ec_custom_product_field_values drop column $field_identifier" - ad_return_error "Unable to Add Field" "Sorry, we were unable to add the field you requested. The error occurred when adding the column $field_identifier to ec_custom_p_field_values_audit, so we've dropped that column from ec_custom_product_field_values and we've deleted the row containing $field_identifier from ec_custom_product_fields as well (for consistency). Here's the error message:
      $errmsg
      " - return -} + "oracle" { + set new_trigger " + create or replace trigger ec_custom_p_f_values_audit_tr + before update or delete on ec_custom_product_field_values + for each row + begin + insert into ec_custom_p_field_values_audit (" -# determine what the new trigger should be -set new_trigger_beginning "create or replace trigger ec_custom_p_f_values_audit_tr -before update or delete on ec_custom_product_field_values -for each row -begin - insert into ec_custom_p_field_values_audit (" + db_with_handle db { + set trigger_column_list [list] + for {set i 0} {$i < [ns_column count $db ec_custom_product_field_values]} {incr i} { + lappend trigger_column_list [ns_column name $db ec_custom_product_field_values $i] + } + } -db_with_handle db { - set trigger_column_list [list] - for {set i 0} {$i < [ns_column count $db ec_custom_product_field_values]} {incr i} { - lappend trigger_column_list [ns_column name $db ec_custom_product_field_values $i] - } -} + append new_trigger "[join $trigger_column_list ", "]) values (:old.[join $trigger_column_list ", :old."])" + append new_trigger "; + end;" -set new_trigger_columns [join $trigger_column_list ", "] + # (2000-08-20 Seb) I don't know how to escape bind variables + # (':old' in text of PL/SQL code will force Oracle driver to + # look for Tcl var named 'old', and that's Not What We Want. + # For the time being, I will resort to plainb ns_db call: -set new_trigger_middle ") values (" + db_with_handle db { + ns_db dml $db $new_trigger + } + } + + "postgresql" { + set new_trigger_function " + create function ec_custom_p_f_values_audit_tr () + returns opaque as ' + begin + insert into ec_custom_p_field_values_audit (" -set new_trigger_values ":old.[join $trigger_column_list ", :old."]" + db_with_handle db { + set trigger_column_list [list] + for {set i 0} {$i < [ns_column count $db ec_custom_product_field_values]} {incr i} { + lappend trigger_column_list [ns_column name $db ec_custom_product_field_values $i] + } + } -set new_trigger_end "); -end; -" + append new_trigger_function "[join $trigger_column_list ", "]) values (old.[join $trigger_column_list ", old."]);" + append new_trigger_function " + return new; + end;' language 'plpgsql'" -set new_trigger "$new_trigger_beginning -$new_trigger_columns -$new_trigger_middle -$new_trigger_values -$new_trigger_end" + db_transaction { + db_dml drop_trigger_function "drop function ec_custom_p_f_values_audit_tr ()" -# (2000-08-20 Seb) I don't know how to escape bind variables (':old' in -# text of PL/SQL code will force Oracle driver to look for Tcl var named -# 'old', and that's Not What We Want. For the time being, I will resort -# to plainb ns_db call: + # There is no XQL definition for create_trigger_function + # as the DML has been constructed on the fly. -db_with_handle db { - ns_db dml $db $new_trigger -} + db_dml create_trigger_function $new_trigger_function + db_dml drop_trigger "drop trigger ec_custom_p_f_values_audit_tr on ec_custom_product_field_values" + db_dml create_trigger " + create trigger ec_custom_p_f_values_audit_tr + before update or delete on ec_custom_product_field_values + for each row execute procedure ec_custom_p_f_values_audit_tr ();" + } + } + default { + + # Unknown database. + } +} ad_returnredirect "custom-fields" Index: openacs-4/packages/ecommerce/www/admin/products/custom-field-add-3.xql =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/ecommerce/www/admin/products/custom-field-add-3.xql,v diff -u -r1.1 -r1.2 --- openacs-4/packages/ecommerce/www/admin/products/custom-field-add-3.xql 10 Jul 2001 20:33:53 -0000 1.1 +++ openacs-4/packages/ecommerce/www/admin/products/custom-field-add-3.xql 26 May 2002 04:36:50 -0000 1.2 @@ -1,32 +1,19 @@ - - - select count(*) from ec_custom_product_fields where field_identifier=:field_identifier - - + + + select count(*) + from ec_custom_product_fields + where field_identifier = :field_identifier + + + + + + delete from ec_custom_product_fields + where field_identifier = :field_identifier + + - - - - delete from ec_custom_product_fields where field_identifier=:field_identifier - - - - - - - delete from ec_custom_product_fields where field_identifier=:field_identifier - - - - - - - alter table ec_custom_product_field_values drop column $field_identifier - - - - Index: openacs-4/packages/ecommerce/www/admin/products/custom-field-add.tcl =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/ecommerce/www/admin/products/custom-field-add.tcl,v diff -u -r1.1 -r1.2 --- openacs-4/packages/ecommerce/www/admin/products/custom-field-add.tcl 20 Apr 2001 20:51:14 -0000 1.1 +++ openacs-4/packages/ecommerce/www/admin/products/custom-field-add.tcl 26 May 2002 04:36:50 -0000 1.2 @@ -1,62 +1,56 @@ -# www/[ec_url_concat [ec_url] /admin]/products/custom-field-add.tcl ad_page_contract { - Add a custom product field. - @author Eve Andersson (eveander@arsdigita.com) - @creation-date Summer 1999 - @cvs-id custom-field-add.tcl,v 3.1.6.1 2000/07/22 07:57:37 ron Exp - @author ported by Jerry Asher (jerry@theashergroup.com) + Add a custom product field. + + @author Eve Andersson (eveander@arsdigita.com) + @creation-date Summer 1999 + @author ported by Jerry Asher (jerry@theashergroup.com) + @author revised by Bart Teeuwisse + @revision-date May 2002 + } { } ad_require_permission [ad_conn package_id] admin -doc_body_append "[ad_admin_header "Add a Custom Field"] +doc_body_append " + [ad_admin_header "Add a Custom Field"] -

      Add a Custom Field

      +

      Add a Custom Field

      -[ad_admin_context_bar [list "../" "Ecommerce([ec_system_name])"] [list "index.tcl" "Products"] [list "custom-fields.tcl" "Custom Fields"] "Add a Custom Field"] + [ad_admin_context_bar [list "../" "Ecommerce([ec_system_name])"] [list "index.tcl" "Products"] [list "custom-fields.tcl" "Custom Fields"] "Add a Custom Field"] -
      +
      -
      - - - - - - - - - - - - - - - - - - - - - - - - -
      Unique IdentifierNo spaces or special characters (just lowercase letters). The customers won't see this, but the site -administrator might, so make it indicative of what the field is.
      Field NameThis is the name that the customers will see (if you choose to display this field on the site) and -the name you'll see when adding/updating products.
      Default Value (if any)
      What kind of information will this field hold? -[ec_column_type_widget] -
      - -

      - -

      - -
      - -
      - -[ad_admin_footer] -" \ No newline at end of file +
      + + + + + + + + + + + + + + + + + + + + + + +
      Unique IdentifierNo spaces or special characters (just lowercase letters). The customers won't see this, but the site + administrator might, so make it indicative of what the field is.
      Field NameThis is the name that the customers will see (if you choose to display this field on the site) and + the name you'll see when adding/updating products.
      Default Value (if any)
      What kind of information will this field hold?[ec_column_type_widget]
      + +
      + +
      +
      + [ad_admin_footer]" Index: openacs-4/packages/ecommerce/www/admin/products/custom-field-edit-2-oracle.xql =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/ecommerce/www/admin/products/custom-field-edit-2-oracle.xql,v diff -u -r1.1 -r1.2 --- openacs-4/packages/ecommerce/www/admin/products/custom-field-edit-2-oracle.xql 10 Jul 2001 20:33:53 -0000 1.1 +++ openacs-4/packages/ecommerce/www/admin/products/custom-field-edit-2-oracle.xql 26 May 2002 04:36:50 -0000 1.2 @@ -1,22 +1,16 @@ - oracle8.1.6 + + oracle + 8.1.6 + - - - - update ec_custom_product_fields - set field_name = :field_name, - default_value = :default_value, - column_type = :column_type, - last_modified = sysdate, - last_modifying_user = :user_id, - modified_ip_address = :peeraddr - where field_identifier = :field_identifier - - - - - + + + update ec_custom_product_fields set field_name = :field_name, default_value = :default_value, column_type = :column_type, + last_modified = sysdate, last_modifying_user = :user_id, modified_ip_address = :peeraddr where field_identifier = :field_identifier + + + Index: openacs-4/packages/ecommerce/www/admin/products/custom-field-edit-2-postgresql.xql =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/ecommerce/www/admin/products/custom-field-edit-2-postgresql.xql,v diff -u -r1.1 -r1.2 --- openacs-4/packages/ecommerce/www/admin/products/custom-field-edit-2-postgresql.xql 10 Jul 2001 20:33:53 -0000 1.1 +++ openacs-4/packages/ecommerce/www/admin/products/custom-field-edit-2-postgresql.xql 26 May 2002 04:36:50 -0000 1.2 @@ -1,22 +1,17 @@ - postgresql7.1 + + postgresql + 7.1 + - - - - update ec_custom_product_fields - set field_name = :field_name, - default_value = :default_value, - column_type = :column_type, - last_modified = current_timestamp, - last_modifying_user = :user_id, - modified_ip_address = :peeraddr - where field_identifier = :field_identifier - - - - - + + + update ec_custom_product_fields set field_name = :field_name, default_value = :default_value, column_type = :column_type, last_modified = current_timestamp, + last_modifying_user = :user_id, modified_ip_address = :peeraddr + where field_identifier = :field_identifier + + + Index: openacs-4/packages/ecommerce/www/admin/products/custom-field-edit-2.tcl =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/ecommerce/www/admin/products/custom-field-edit-2.tcl,v diff -u -r1.1 -r1.2 --- openacs-4/packages/ecommerce/www/admin/products/custom-field-edit-2.tcl 20 Apr 2001 20:51:14 -0000 1.1 +++ openacs-4/packages/ecommerce/www/admin/products/custom-field-edit-2.tcl 26 May 2002 04:36:50 -0000 1.2 @@ -1,68 +1,66 @@ -# www/[ec_url_concat [ec_url] /admin]/products/custom-field-edit-2.tcl ad_page_contract { - @author Eve Andersson (eveander@arsdigita.com) - @creation-date Summer 1999 - @cvs-id custom-field-edit-2.tcl,v 3.1.6.3 2000/08/20 22:34:23 seb Exp - @author ported by Jerry Asher (jerry@theashergroup.com) + @author Eve Andersson (eveander@arsdigita.com) + @creation-date Summer 1999 + @author ported by Jerry Asher (jerry@theashergroup.com) + @author revised by Bart Teeuwisse + @revision-date April 2002 + } { - field_identifier:sql_identifier,notnull - field_name:notnull - default_value - column_type:notnull - old_column_type:notnull + field_identifier:sql_identifier,notnull + field_name:notnull + default_value + column_type:notnull + old_column_type:notnull } ad_require_permission [ad_conn package_id] admin -# we need them to be logged in +# We need them to be logged in set user_id [ad_get_user_id] -# I'm not going to let them change from a non-boolean column type to a boolean -# one because it's too complicated adding the constraint (because first you -# change the column type and then you try to add the constraint, but if you -# fail when you add the constraint, you've still changed the column type (there's no -# rollback when you're altering tables), and in theory I could then change the -# column type back to the original one if the constraint addition fails, but -# what if that fails, so I'm just not going to allow it). +# I'm not going to let them change from a non-boolean column type to a +# boolean one because it's too complicated adding the constraint +# (because first you change the column type and then you try to add +# the constraint, but if you fail when you add the constraint, you've +# still changed the column type (there's no rollback when you're +# altering tables), and in theory I could then change the column type +# back to the original one if the constraint addition fails, but what +# if that fails, so I'm just not going to allow it). if { $old_column_type != "char(1)" && $column_type == "char(1)"} { - ad_return_complaint 1 "
    • The Kind of Information cannot be changed from non-boolean to boolean." + ad_return_complaint 1 "
    • The Kind of Information cannot be changed from non-boolean to boolean.
    • " return } - if {[catch { - if { $column_type != $old_column_type } { + if { $column_type != $old_column_type } { - # if the old column_type is a boolean, then let's drop the old constraint - if { $old_column_type == "char(1)" } { - db_dml alter_table_drop "alter table ec_custom_product_field_values drop constraint ${field_identifier}_constraint" - } + # If the old column_type is a boolean, then let's drop the old + # constraint - db_dml alter_table_modify " - alter table ec_custom_product_field_values - modify ($field_identifier $column_type)" - db_dml alter_table_modify_audit " - alter table ec_custom_p_field_values_audit - modify ($field_identifier $column_type)" - } + if { $old_column_type == "char(1)" } { + db_dml alter_table_drop " + alter table ec_custom_product_field_values + drop constraint ${field_identifier}_constraint" + } + + db_dml alter_table_modify " + alter table ec_custom_product_field_values + modify ($field_identifier $column_type)" + db_dml alter_table_modify_audit " + alter table ec_custom_p_field_values_audit + modify ($field_identifier $column_type)" + } } errmsg]} { - ad_return_complaint 1 "
    • The modification of Kind of Information failed. Here is the error message that Oracle gave us:
      $errmsg
      " + ad_return_complaint 1 "
    • The modification of Kind of Information failed. Here is the error message that the database gave us:
      $errmsg
    • " return } set peeraddr [ns_conn peeraddr] +db_dml custom_fields_update " + update ec_custom_product_fields set field_name = :field_name, default_value = :default_value, column_type = :column_type, + last_modified = sysdate, last_modifying_user = :user_id, modified_ip_address = :peeraddr + where field_identifier = :field_identifier" -db_dml custom_fields_update { - update ec_custom_product_fields - set field_name = :field_name, - default_value = :default_value, - column_type = :column_type, - last_modified = sysdate, - last_modifying_user = :user_id, - modified_ip_address = :peeraddr - where field_identifier = :field_identifier -} - ad_returnredirect "custom-fields" Index: openacs-4/packages/ecommerce/www/admin/products/custom-field-edit-2.xql =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/ecommerce/www/admin/products/custom-field-edit-2.xql,v diff -u -r1.1 -r1.2 --- openacs-4/packages/ecommerce/www/admin/products/custom-field-edit-2.xql 10 Jul 2001 20:33:53 -0000 1.1 +++ openacs-4/packages/ecommerce/www/admin/products/custom-field-edit-2.xql 26 May 2002 04:36:50 -0000 1.2 @@ -1,29 +1,28 @@ - - - alter table ec_custom_product_field_values drop constraint ${field_identifier}_constraint - - - - - - - + + + -- PostgrSQL 7.1.2 will fail on this query as it doesn't support dropping of constraints -- + alter table ec_custom_product_field_values + drop constraint ${field_identifier}_constraint + + + + + + -- PostgrSQL 7.1.2 will fail on this query as it can't modify columns -- alter table ec_custom_product_field_values - modify ($field_identifier $column_type) - - - - - - - + modify ($field_identifier $column_type) + + + + + + -- PostgrSQL 7.1.2 will fail on this query as it can't modify columns -- alter table ec_custom_p_field_values_audit - modify ($field_identifier $column_type) - - - - + modify ($field_identifier $column_type) + + + Index: openacs-4/packages/ecommerce/www/admin/products/custom-field-edit.tcl =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/ecommerce/www/admin/products/custom-field-edit.tcl,v diff -u -r1.1 -r1.2 --- openacs-4/packages/ecommerce/www/admin/products/custom-field-edit.tcl 20 Apr 2001 20:51:14 -0000 1.1 +++ openacs-4/packages/ecommerce/www/admin/products/custom-field-edit.tcl 26 May 2002 04:36:50 -0000 1.2 @@ -1,64 +1,66 @@ -# www/[ec_url_concat [ec_url] /admin]/products/custom-field-edit.tcl ad_page_contract { - Edit a custom product field. - @author Eve Andersson (eveander@arsdigita.com) - @creation-date Summer 1999 - @cvs-id custom-field-edit.tcl,v 3.1.6.3 2000/08/20 22:35:01 seb Exp - @author ported by Jerry Asher (jerry@theashergroup.com) + Edit a custom product field. + + @author Eve Andersson (eveander@arsdigita.com) + @creation-date Summer 1999 + @author ported by Jerry Asher (jerry@theashergroup.com) + @author revised by Bart Teeuwisse + @revision-date May 2002 + } { - field_identifier:sql_identifier + field_identifier:sql_identifier } ad_require_permission [ad_conn package_id] admin db_1row custom_field_select " -select field_name, default_value, column_type, active_p -from ec_custom_product_fields -where field_identifier=:field_identifier -" + select field_name, default_value, column_type, active_p + from ec_custom_product_fields + where field_identifier=:field_identifier" set old_column_type $column_type -doc_body_append "[ad_admin_header "Edit $field_name"] +doc_body_append " + [ad_admin_header "Edit $field_name"] -

      Edit $field_name

      +

      Edit $field_name

      -[ad_admin_context_bar [list "../" "Ecommerce([ec_system_name])"] [list "index" "Products"] [list "custom-fields" "Custom Fields"] "Edit Custom Field"] + [ad_admin_context_bar [list "../" "Ecommerce([ec_system_name])"] [list "index" "Products"] [list "custom-fields" "Custom Fields"] "Edit Custom Field"] -
      +
      -
      -[export_form_vars old_column_type field_identifier] - - - - - - - - - - - - - - - - - - - - - - -
      Unique Identifier:$field_identifierThis can't be changed.
      Field Name:
      Default Value:
      Kind of Information:[ec_column_type_widget $column_type]We might not be able to change this, depending on what it is, what you're trying to change it to, and what values are already in the database for this field (you can always try it & find out).
      - -

      - -

      - -
      - -[ad_admin_footer] -" + + [export_form_vars old_column_type field_identifier] + + + + + + + + + + + + + + + + + + + + + + +
      Unique Identifier:$field_identifierThis can't be changed.
      Field Name:
      Default Value:
      Kind of Information:[ec_column_type_widget $column_type]We might not be able to change this, depending on what it + is, what you're trying to change it to, and what values are + already in the database for this field (you can always try it + & find out).
      + +
      + +
      +
      + [ad_admin_footer]" Index: openacs-4/packages/ecommerce/www/admin/products/link-add.tcl =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/ecommerce/www/admin/products/link-add.tcl,v diff -u -r1.1 -r1.2 --- openacs-4/packages/ecommerce/www/admin/products/link-add.tcl 20 Apr 2001 20:51:14 -0000 1.1 +++ openacs-4/packages/ecommerce/www/admin/products/link-add.tcl 26 May 2002 04:36:50 -0000 1.2 @@ -8,7 +8,7 @@ } { product_id:integer,notnull link_product_name:optional - link_product_id:integer,notnull,optional + link_product_sku:integer,notnull,optional } ad_require_permission [ad_conn package_id] admin @@ -26,8 +26,8 @@
        " -if { [info exists link_product_id] } { - set additional_query_part "product_id=:link_product_id" +if { [info exists link_product_sku] } { + set additional_query_part "sku=:link_product_sku" } else { set additional_query_part "upper(product_name) like '%' || upper(:link_product_name) || '%'" } Index: openacs-4/packages/ecommerce/www/admin/products/link.tcl =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/ecommerce/www/admin/products/link.tcl,v diff -u -r1.1 -r1.2 --- openacs-4/packages/ecommerce/www/admin/products/link.tcl 20 Apr 2001 20:51:14 -0000 1.1 +++ openacs-4/packages/ecommerce/www/admin/products/link.tcl 26 May 2002 04:36:50 -0000 1.2 @@ -1,108 +1,97 @@ -# www/[ec_url_concat [ec_url] /admin]/products/link.tcl ad_page_contract { - Lets admin maintain links among products (e.g., "you should also think - about buying X if you're buying Y") - @author Eve Andersson (eveander@arsdigita.com) - @creation-date June 1999 - @cvs-id link.tcl,v 3.1.6.3 2000/08/18 21:46:58 stevenp Exp - @author ported by Jerry Asher (jerry@theashergroup.com) + Lets admin maintain links among products (e.g., "you should also + think about buying X if you're buying Y") + + @author Eve Andersson (eveander@arsdigita.com) + @creation-date June 1999 + @author ported by Jerry Asher (jerry@theashergroup.com) + @author revised by Bart Teeuwisse + @revision-date April 2002 + } { - product_id + product_id } ad_require_permission [ad_conn package_id] admin set product_name [ec_product_name $product_id] -doc_body_append "[ad_admin_header "Links between $product_name and other products"] +doc_body_append " + [ad_admin_header "Links between $product_name and other products"] -

        Links

        +

        Links

        -[ad_admin_context_bar [list "../" "Ecommerce([ec_system_name])"] [list "index.tcl" "Products"] [list "one.tcl?[export_url_vars product_id]" "One"] "Links"] + [ad_admin_context_bar [list "../" "Ecommerce([ec_system_name])"] [list "index.tcl" "Products"] [list "one.tcl?[export_url_vars product_id]" "One"] "Links"] -
        +
        -Links from the page for $product_name to other products' display pages: +

        Links from the page for $product_name to other products' display pages:

        +
          " -

          - -

            -" - - set product_counter 0 db_foreach linked_products_select " -select product_b, product_name as product_b_name -from ec_product_links, ec_products -where product_a=:product_id -and product_b=ec_products.product_id -" { - incr product_counter - doc_body_append "
          • $product_b_name \[delete link\]\n" + select product_b, product_name as product_b_name + from ec_product_links, ec_products + where product_a=:product_id + and product_b=ec_products.product_id" { + + incr product_counter + doc_body_append " +
          • + $product_b_name + \[delete link\] +
          • " } if { $product_counter == 0 } { - doc_body_append "None\n" + doc_body_append "None" } -doc_body_append "
          +doc_body_append " +
        +

        Links to $product_name from other products' display pages:

        +
          " -

          - -Links to $product_name from other products' display pages: - -

          - -

            -" - set product_counter 0 db_foreach more_links_select " -select product_a, product_name as product_a_name -from ec_product_links, ec_products -where product_b=:product_id -and ec_product_links.product_a=ec_products.product_id -" { + select product_a, product_name as product_a_name + from ec_product_links, ec_products + where product_b=:product_id + and ec_product_links.product_a=ec_products.product_id" { + incr product_counter - doc_body_append "
          • $product_a_name \[delete link\]\n" + doc_body_append " +
          • + $product_a_name + \[delete link\] +
          • " } if { $product_counter == 0 } { doc_body_append "None\n" } -doc_body_append "
          +doc_body_append " +
        +

        Search for a product to add a link to/from:

        +
        +
        + [export_form_vars product_id] + Name: +
        +
        + [export_form_vars product_id] + SKU: + +
        +
        " -

        +# Set audit variables audit_name, audit_id, audit_id_column, +# return_url, audit_tables, main_tables -Search for a product to add a link to/from: - -

        - -

        - -
        -[export_form_vars product_id] -Name: - -
        - -

        - -

        -[export_form_vars product_id] -ID: - -
        - -
        -" - -# Set audit variables -# audit_name, audit_id, audit_id_column, return_url, audit_tables, main_tables set audit_name "Links from $product_name" set audit_id $product_id set audit_id_column "product_a" @@ -111,21 +100,20 @@ set main_tables [list ec_product_links] doc_body_append " -

        Audit Trail

        +

        Audit Trail

        + + [ad_admin_footer]" Index: openacs-4/packages/ecommerce/www/admin/products/one.tcl =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/ecommerce/www/admin/products/one.tcl,v diff -u -r1.2 -r1.3 --- openacs-4/packages/ecommerce/www/admin/products/one.tcl 31 Jan 2002 22:43:54 -0000 1.2 +++ openacs-4/packages/ecommerce/www/admin/products/one.tcl 26 May 2002 04:36:50 -0000 1.3 @@ -1,74 +1,101 @@ -# www/[ec_url_concat [ec_url] /admin]/products/one.tcl ad_page_contract { - Main admin page for a single product. - @author Eve Andersson (eveander@arsdigita.com) - @creation-date June 1999 - @cvs-id one.tcl,v 3.4.2.5 2000/08/18 21:46:59 stevenp Exp - @author ported by Jerry Asher (jerry@theashergroup.com) + Main admin page for a single product. + + @author Eve Andersson (eveander@arsdigita.com) + @creation-date June 1999 + @author ported by Jerry Asher (jerry@theashergroup.com) + @author revised by Bart Teeuwisse + @revision-date May 2002 + } { - product_id:integer,notnull + product_id:integer,notnull } ad_require_permission [ad_conn package_id] admin -# Have to get everything about this product from ec_products, -# ec_custom_product_field_values (along with the info about the fields from -# ec_custom_product_fields), ec_category_product_map, ec_subcategory_product_map, ec_subsubcategory_product_map +# Have to get everything about this product from ec_products, +# ec_custom_product_field_values (along with the info about the fields +# from ec_custom_product_fields), ec_category_product_map, +# ec_subcategory_product_map, ec_subsubcategory_product_map -db_0or1row product_select "select * from ec_products where product_id=:product_id" +db_0or1row product_select " + select * + from ec_products + where product_id = :product_id" -# we know these won't conflict with the ec_products columns because of the constraint -# in custom-field-add-2.tcl -db_0or1row custom_fields_select "select * from ec_custom_product_field_values where product_id=:product_id" +# We know these won't conflict with the ec_products columns because of +# the constraint in custom-field-add-2.tcl -set category_list [db_list categories_select "select category_id from ec_category_product_map where product_id=:product_id"] - -set subcategory_list [db_list subcategories_select "select subcategory_id from ec_subcategory_product_map where product_id=:product_id"] - -set subsubcategory_list [db_list subsubcategories_select "select subsubcategory_id from ec_subsubcategory_product_map where product_id=:product_id"] - +db_0or1row custom_fields_select " + select * + from ec_custom_product_field_values + where product_id = :product_id" +set category_list [db_list categories_select " + select category_id + from ec_category_product_map + where product_id = :product_id"] +set subcategory_list [db_list subcategories_select " + select subcategory_id + from ec_subcategory_product_map + where product_id = :product_id"] +set subsubcategory_list [db_list subsubcategories_select " + select subsubcategory_id + from ec_subsubcategory_product_map + where product_id = :product_id"] set multiple_retailers_p [ad_parameter -package_id [ec_id] MultipleRetailersPerProductP ecommerce] set currency [ad_parameter -package_id [ec_id] Currency ecommerce] +set n_professional_reviews [db_string n_professional_reviews_select " + select count(*) + from ec_product_reviews + where product_id = :product_id"] -set n_professional_reviews [db_string n_professional_reviews_select "select count(*) from ec_product_reviews where product_id = :product_id"] - if { $n_professional_reviews == 0 } { set product_review_anchor "none yet; click to add" } else { set product_review_anchor $n_professional_reviews } -set n_customer_reviews [db_string n_customer_reviews_select "select count(*) from ec_product_comments where product_id = :product_id"] +set n_customer_reviews [db_string n_customer_reviews_select " + select count(*) + from ec_product_comments + where product_id = :product_id"] if { $n_customer_reviews == 0 } { set customer_reviews_link "none yet" } else { set customer_reviews_link "$n_customer_reviews" } -set n_links_to [db_string n_links_to_select "select count(*) from ec_product_links where product_b = :product_id"] +set n_links_to [db_string n_links_to_select " + select count(*) + from ec_product_links + where product_b = :product_id"] -set n_links_from [db_string n_links_from_select "select count(*) from ec_product_links where product_a = :product_id"] +set n_links_from [db_string n_links_from_select " + select count(*) + from ec_product_links + where product_a = :product_id"] if { $multiple_retailers_p } { set price_row "" } else { - if { [db_string sale_select "select count(*) from ec_sale_prices_current where product_id=:product_id"] > 0 } { + if { [db_string sale_select " + select count(*) + from ec_sale_prices_current + where product_id = :product_id"] > 0 } { set sale_prices_anchor "on sale; view price" } else { set sale_prices_anchor "put on sale" } - set price_row " - - Regular Price: - - - [ec_message_if_null [ec_pretty_price $price $currency]] - ($sale_prices_anchor) - - - " + set price_row " + + Regular Price: + + [ec_message_if_null [ec_pretty_price $price $currency]] + ($sale_prices_anchor) + + " } if { $no_shipping_avail_p == "f" } { @@ -78,16 +105,13 @@ } set no_shipping_avail_p_row " - - -Shipping Avail/No Shipping Avail: - - -$no_shipping_avail_p_for_display -(toggle) - - -" + + Shipping Avail/No Shipping Avail: + + $no_shipping_avail_p_for_display + (toggle) + + " if { $active_p == "t" } { set active_p_for_display "Active" @@ -96,309 +120,297 @@ } set active_p_row " - - -Active/Discontinued: - - -$active_p_for_display -(toggle) - - -" + + Active/Discontinued: + + $active_p_for_display + (toggle) + + " if [empty_string_p $dirname] { set dirname_cell "something is wrong with this product; there is no place to put files!" } else { set dirname_cell "$dirname (Supporting Files)" } -doc_body_append "[ad_admin_header "$product_name"] +doc_body_append " + [ad_admin_header "$product_name"] -

        $product_name

        +

        $product_name

        + + [ad_admin_context_bar [list "../" "Ecommerce([ec_system_name])"] [list "index.tcl" "Products"] "One Product"] -[ad_admin_context_bar [list "../" "Ecommerce([ec_system_name])"] [list "index.tcl" "Products"] "One Product"] +
        -
        + - - -

        Complete Record

        - -
        - -" - if { $active_p == "f" } { - doc_body_append "This product is discontinued.

        \n" + doc_body_append "

        This product is discontinued.

        " } -doc_body_append "[ec_linked_thumbnail_if_it_exists $dirname] - - - - - - - - - - - - - -$price_row -$no_shipping_avail_p_row -$active_p_row - - - - -" +doc_body_append " + [ec_linked_thumbnail_if_it_exists $dirname] +
        -Product ID: - -$product_id -
        -Product Name: - -$product_name -
        -SKU: - -[ec_message_if_null $sku] -
        -Categorization: - -[ec_category_subcategory_and_subsubcategory_display $category_list $subcategory_list $subsubcategory_list] -
        + + + + + + + + + + + + + $price_row + $no_shipping_avail_p_row + $active_p_row + + + + " + if { !$multiple_retailers_p } { - doc_body_append " - - + + - - " + doc_body_append " + + " } -doc_body_append " - - + +doc_body_append " + + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - - -" + + +" + if { !$multiple_retailers_p } { - doc_body_append " - - - - - - - - " + doc_body_append " + + + + + + + + " } -doc_body_append " - - - -" + +doc_body_append " + + + + " + if { !$multiple_retailers_p } { - db_foreach user_class_select "select user_class_id, user_class_name from ec_user_classes order by user_class_name" { - set temp_price [db_string temp_price_select "select price from ec_product_user_class_prices where product_id=:product_id and user_class_id=:user_class_id" -default ""] + db_foreach user_class_select " + select user_class_id, user_class_name + from ec_user_classes + order by user_class_name" { + + set temp_price [db_string temp_price_select " + select price + from ec_product_user_class_prices + where product_id = :product_id + and user_class_id = :user_class_id" -default ""] - doc_body_append " - - - - - " + doc_body_append " + + + + " } } -db_foreach custom_fields_select "select field_identifier, field_name, column_type from ec_custom_product_fields where active_p = 't'" { +db_foreach custom_fields_iteration " + select field_identifier, field_name, column_type + from ec_custom_product_fields + where active_p = 't'" { + if { [info exists $field_identifier] } { doc_body_append " - - - + + - - " + doc_body_append " + + " } } -doc_body_append " - - +doc_body_append " + + + - - + + - - + + - - + +
        + Product ID: + + $product_id +
        + Product Name: + + $product_name +
        + SKU: + + [ec_message_if_null $sku] +
        + Categorization: + + [ec_category_subcategory_and_subsubcategory_display $category_list $subcategory_list $subsubcategory_list] +
        - Stock Status: - - " + doc_body_append " +
        Stock Status:" if { ![empty_string_p $stock_status] } { doc_body_append [util_memoize "ad_parameter -package_id [ec_id] \"StockMessage[string toupper $stock_status]\"" [ec_cache_refresh]] } else { doc_body_append [ec_message_if_null $stock_status] } - doc_body_append "
        -One-Line Description: - -[ec_message_if_null $one_line_description] -
        + One-Line Description: + + [ec_message_if_null $one_line_description] +
        -Additional Descriptive Text: - -[ec_display_as_html [ec_message_if_null $detailed_description]] - + Additional Descriptive Text: + + [ec_display_as_html [ec_message_if_null $detailed_description]] +
        -Search Keywords: - -[ec_message_if_null $search_keywords] - + Search Keywords: + + [ec_message_if_null $search_keywords] +
        -Color Choices: - -[ec_message_if_null $color_list] - + Color Choices: + + [ec_message_if_null $color_list] +
        -Size Choices: - -[ec_message_if_null $size_list] - + Size Choices: + + [ec_message_if_null $size_list] +
        -Style Choices: - -[ec_message_if_null $style_list] - + Style Choices: + + [ec_message_if_null $style_list] +
        -Email on Purchase: - -[ec_message_if_null $email_on_purchase_list] - + Email on Purchase: + + [ec_message_if_null $email_on_purchase_list] +
        -URL: - -[ec_message_if_null $url] - + URL: + + [ec_message_if_null $url] +
        -Display this product when user does a search? - -[ec_message_if_null [ec_PrettyBoolean $present_p]] -
        + Display this product when user does a search? + + [ec_message_if_null [ec_PrettyBoolean $present_p]] +
        - Shipping Price: - - [ec_message_if_null [ec_pretty_price $shipping $currency]] -
        - Shipping - Additional: - - [ec_message_if_null [ec_pretty_price $shipping_additional $currency]] -
        Shipping Price:[ec_message_if_null [ec_pretty_price $shipping $currency]]
        Shipping - Additional:[ec_message_if_null [ec_pretty_price $shipping_additional $currency]]
        -Weight: - -[ec_message_if_null $weight] [ec_decode $weight "" "" [ad_parameter -package_id [ec_id] WeightUnits ecommerce]] -
        Weight:[ec_message_if_null $weight] [ec_decode $weight "" "" [ad_parameter -package_id [ec_id] WeightUnits ecommerce]]
        - $user_class_name Price: - - [ec_message_if_null [ec_pretty_price $temp_price $currency]] -
        $user_class_name Price:[ec_message_if_null [ec_pretty_price $temp_price $currency]]
        - $field_name: - - " +
        $field_name:" + if { $column_type == "char(1)" } { doc_body_append "[ec_message_if_null [ec_PrettyBoolean [set $field_identifier]]]\n" } elseif { $column_type == "date" } { doc_body_append "[ec_message_if_null [util_AnsiDatetoPrettyDate [set $field_identifier]]]\n" } else { doc_body_append "[ec_display_as_html [ec_message_if_null [set $field_identifier]]]\n" } - doc_body_append "
        -Template: - -[ec_message_if_null [db_string template_name_select "select template_name from ec_templates where template_id=:template_id" -default "" ]] -
        + Template: + + [ec_message_if_null [db_string template_name_select "select template_name from ec_templates where template_id=:template_id" -default "" ]] +
        -Date Added: - -[util_AnsiDatetoPrettyDate $creation_date] - + Date Added: + + [util_AnsiDatetoPrettyDate $creation_date] +
        -Date Available: - -[util_AnsiDatetoPrettyDate $available_date] - + Date Available: + + [util_AnsiDatetoPrettyDate $available_date] +
        -Directory Name (where image & other product info is kept): - -$dirname_cell - + Directory Name (where image & other product info is kept): + + $dirname_cell +
        (Edit)
        -

        -

        Miscellaneous

        -
          -" +
            " + if { $multiple_retailers_p } { - doc_body_append "
          • Retailer Offers - " + doc_body_append "
          • Retailer Offers
          • " } doc_body_append " -

            -

          • Delete -

            -" -# Set audit variables -# audit_name, audit_id, audit_id_column, return_url, audit_tables, main_tables +

            +
          • Delete
          • +

            " + +# Set audit variables audit_name, audit_id, audit_id_column, +# return_url, audit_tables, main_tables + set audit_name $product_name set audit_id $product_id set audit_id_column "product_id" set return_url "[ad_conn url]?[export_url_vars product_id]" set audit_tables [list ec_products_audit ec_custom_p_field_values_audit ec_category_product_map_audit ec_subcat_prod_map_audit ec_subsubcat_prod_map_audit] set main_tables [list ec_products ec_custom_product_field_values ec_category_product_map ec_subcategory_product_map ec_subsubcategory_product_map] -doc_body_append "
          • Audit Trail +doc_body_append " +
          • Audit Trail
          • -
          -[ad_admin_footer] -" +
        + [ad_admin_footer]" Index: openacs-4/packages/ecommerce/www/admin/products/one.xql =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/ecommerce/www/admin/products/one.xql,v diff -u -r1.1 -r1.2 --- openacs-4/packages/ecommerce/www/admin/products/one.xql 10 Jul 2001 20:33:53 -0000 1.1 +++ openacs-4/packages/ecommerce/www/admin/products/one.xql 26 May 2002 04:36:50 -0000 1.2 @@ -1,102 +1,117 @@ - - - select * from ec_products where product_id=:product_id - - - - - - - select * from ec_custom_product_field_values where product_id=:product_id - - - - - - - select category_id from ec_category_product_map where product_id=:product_id - - - - - - - select subcategory_id from ec_subcategory_product_map where product_id=:product_id - - - - - - - select subsubcategory_id from ec_subsubcategory_product_map where product_id=:product_id - - - - - - - select count(*) from ec_product_reviews where product_id = :product_id - - - - - - - select count(*) from ec_product_comments where product_id = :product_id - - - - - - - select count(*) from ec_product_links where product_b = :product_id - - - - - - - select count(*) from ec_product_links where product_a = :product_id - - - - - - - select count(*) from ec_sale_prices_current where product_id=:product_id - - - - - - - select user_class_id, user_class_name from ec_user_classes order by user_class_name - - - - - - - select price from ec_product_user_class_prices where product_id=:product_id and user_class_id=:user_class_id - - - - - - - select field_identifier, field_name, column_type from ec_custom_product_fields where active_p = 't' - - - - - - - select template_name from ec_templates where template_id=:template_id - - - - + + + select * + from ec_products + where product_id = :product_id + + + + + + select * + from ec_custom_product_field_values + where product_id = :product_id + + + + + + select category_id + from ec_category_product_map + where product_id = :product_id + + + + + + select subcategory_id + from ec_subcategory_product_map + where product_id = :product_id + + + + + + select subsubcategory_id + from ec_subsubcategory_product_map + where product_id = :product_id + + + + + + select count(*) + from ec_product_reviews + where product_id = :product_id + + + + + + select count(*) + from ec_product_comments + where product_id = :product_id + + + + + + select count(*) + from ec_product_links + where product_b = :product_id + + + + + + select count(*) + from ec_product_links + where product_a = :product_id + + + + + + select count(*) + from ec_sale_prices_current + where product_id = :product_id + + + + + + select user_class_id, user_class_name + from ec_user_classes + order by user_class_name + + + + + + select price + from ec_product_user_class_prices + where product_id = :product_id + and user_class_id = :user_class_id + + + + + + select field_identifier, field_name, column_type + from ec_custom_product_fields + where active_p = 't' + + + + + + select template_name + from ec_templates + where template_id = :template_id + + + Index: openacs-4/packages/ecommerce/www/admin/products/recommendations.xql =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/ecommerce/www/admin/products/Attic/recommendations.xql,v diff -u -r1.1 -r1.2 --- openacs-4/packages/ecommerce/www/admin/products/recommendations.xql 10 Jul 2001 20:33:53 -0000 1.1 +++ openacs-4/packages/ecommerce/www/admin/products/recommendations.xql 26 May 2002 04:36:50 -0000 1.2 @@ -1,21 +1,15 @@ - - + + + select r.recommendation_id, r.the_category_name, r.the_subcategory_name, r.the_subsubcategory_name, p.product_name, c.user_class_name + from ec_recommendations_cats_view r + join ec_products p using (product_id) + left join ec_user_classes c on (r.user_class_id = c.user_class_id) + where r.active_p='t' + order by case when the_category_name is null then 0 else 1 end, upper(the_category_name), upper(the_subcategory_name), upper(the_subsubcategory_name) + + -select - r.recommendation_id, r.the_category_name, r.the_subcategory_name, r.the_subsubcategory_name, - p.product_name, - c.user_class_name -from ec_recommendations_cats_view r - JOIN ec_products p using (product_id) - LEFT JOIN ec_user_classes c on (r.user_class_id = c.user_class_id) -where r.active_p='t' -order by case when the_category_name = NULL then 0 else 1 end, upper(the_category_name), upper(the_subcategory_name), upper(the_subsubcategory_name) - - - - - Index: openacs-4/packages/ecommerce/www/admin/products/review.tcl =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/ecommerce/www/admin/products/review.tcl,v diff -u -r1.1 -r1.2 --- openacs-4/packages/ecommerce/www/admin/products/review.tcl 20 Apr 2001 20:51:14 -0000 1.1 +++ openacs-4/packages/ecommerce/www/admin/products/review.tcl 26 May 2002 04:36:50 -0000 1.2 @@ -1,4 +1,3 @@ -# www/[ec_url_concat [ec_url] /admin]/products/review.tcl ad_page_contract { @author Eve Andersson (eveander@arsdigita.com) @@ -12,6 +11,7 @@ ad_require_permission [ad_conn package_id] admin db_1row review_select "select * from ec_product_reviews where review_id=:review_id" +set review_date [clock format [clock scan $review_date] -format "%Y-%m-%d" -gmt true] set product_name [ec_product_name $product_id] Index: openacs-4/packages/ecommerce/www/admin/products/sale-price-add-2.tcl =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/ecommerce/www/admin/products/sale-price-add-2.tcl,v diff -u -r1.1 -r1.2 --- openacs-4/packages/ecommerce/www/admin/products/sale-price-add-2.tcl 20 Apr 2001 20:51:14 -0000 1.1 +++ openacs-4/packages/ecommerce/www/admin/products/sale-price-add-2.tcl 26 May 2002 04:36:50 -0000 1.2 @@ -1,38 +1,43 @@ -# www/[ec_url_concat [ec_url] /admin]/products/sale-price-add-2.tcl ad_page_contract { - @author Eve Andersson (eveander@arsdigita.com) - @creation-date Summer 1999 - @cvs-id sale-price-add-2.tcl,v 3.1.6.3 2000/08/18 20:23:47 stevenp Exp - @author ported by Jerry Asher (jerry@theashergroup.com) + @author Eve Andersson (eveander@arsdigita.com) + @creation-date Summer 1999 + @author ported by Jerry Asher (jerry@theashergroup.com) + @author revised by Bart Teeuwisse + @revision-date April 2002 + } { - sale_price_id:integer,notnull - product_id:integer,notnull - sale_price:notnull - sale_name - sale_begins - sale_ends - offer_code + sale_price_id:integer,notnull + product_id:integer,notnull + sale_price:notnull + sale_name:html + sale_begins + sale_ends + offer_code } ad_require_permission [ad_conn package_id] admin -# we need them to be logged in +# We need them to be logged in + set user_id [ad_get_user_id] -# see if a sale price with this sale_price_id exists, meaning they pushed -# submit twice +# See if a sale price with this sale_price_id exists, meaning they +# pushed submit twice -if { [db_string doubleclick_select "select count(*) from ec_sale_prices where sale_price_id=:sale_price_id"] > 0 } { +if { [db_string doubleclick_select " + select count(*) + from ec_sale_prices + where sale_price_id = :sale_price_id"] > 0 } { ad_returnredirect "sale-prices.tcl?[export_url_vars product_id product_name]" } - set peeraddr [ns_conn peeraddr] -db_dml sale_insert "insert into ec_sale_prices -(sale_price_id, product_id, sale_price, sale_begins, sale_ends, sale_name, offer_code, last_modified, last_modifying_user, modified_ip_address) -values -(:sale_price_id, :product_id, :sale_price, to_date(:sale_begins,'YYYY-MM-DD HH24:MI:SS'), to_date(:sale_ends,'YYYY-MM-DD HH24:MI:SS'), :sale_name, :offer_code, sysdate, :user_id, :peeraddr)" +db_dml sale_insert " + insert into ec_sale_prices + (sale_price_id, product_id, sale_price, sale_begins, sale_ends, sale_name, offer_code, last_modified, last_modifying_user, modified_ip_address) + values + (:sale_price_id, :product_id, :sale_price, to_date(:sale_begins,'YYYY-MM-DD HH24:MI:SS'), to_date(:sale_ends,'YYYY-MM-DD HH24:MI:SS'), :sale_name, :offer_code, sysdate, :user_id, :peeraddr)" ad_returnredirect "sale-prices.tcl?[export_url_vars product_id product_name]" Index: openacs-4/packages/ecommerce/www/admin/products/sale-price-add.tcl =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/ecommerce/www/admin/products/sale-price-add.tcl,v diff -u -r1.3 -r1.4 --- openacs-4/packages/ecommerce/www/admin/products/sale-price-add.tcl 31 Jan 2002 22:43:54 -0000 1.3 +++ openacs-4/packages/ecommerce/www/admin/products/sale-price-add.tcl 26 May 2002 04:36:50 -0000 1.4 @@ -1,20 +1,22 @@ -# www/[ec_url_concat [ec_url] /admin]/products/sale-price-add.tcl ad_page_contract { - Add a sale price. - @author Eve Andersson (eveander@arsdigita.com) - @creation-date Summer 1999 - @cvs-id sale-price-add.tcl,v 3.1.6.3 2000/08/18 20:23:47 stevenp Exp - @author ported by Jerry Asher (jerry@theashergroup.com) + Add a sale price. + + @author Eve Andersson (eveander@arsdigita.com) + @creation-date Summer 1999 + @author ported by Jerry Asher (jerry@theashergroup.com) + @author revised by Bart Teeuwisse + @revision-date April 2002 + } { - product_id:integer,notnull + product_id:integer,notnull {price:optional ""} - sale_price:notnull - {sale_name "Sale Price"} - sale_begins:array,date - sale_ends:array,date - offer_code_needed - offer_code:optional + sale_price:notnull + {sale_name:html "Sale Price"} + sale_begins:array,date + sale_ends:array,date + offer_code_needed + offer_code:optional } ad_require_permission [ad_conn package_id] admin @@ -28,6 +30,7 @@ ad_return_complaint 1 "
      • Please enter a number for price." return } + # If a regular price exists, compare it with sale price if {![empty_string_p $price]} { @@ -38,26 +41,27 @@ } page_validation { -# ec_date_widget_validate sale_begins + # ec_date_widget_validate sale_begins } { - ec_time_widget_validate sale_begins + ec_time_widget_validate sale_begins } { -# ec_date_widget_validate sale_ends + # ec_date_widget_validate sale_ends } { - ec_time_widget_validate sale_ends + ec_time_widget_validate sale_ends } if { [empty_string_p [ec_datetime_text sale_begins]] } { - ad_return_complaint 1 "You forgot to enter the time that the sale begins." - return + ad_return_complaint 1 "You forgot to enter the time that the sale begins." + return } if { [empty_string_p [ec_datetime_text sale_ends]] } { - ad_return_complaint 1 "You forgot to enter the time that the sale begins." - return + ad_return_complaint 1 "You forgot to enter the time that the sale begins." + return } -# Not compare the time (assuming usually the time boxes are left blank) +# Not compare the time (assuming usually the time boxes are left +# blank) if {![empty_string_p $sale_begins(date)] && ![empty_string_p $sale_ends(date)]} { if {[db_0or1row select_one "select 1 from dual where to_date('$sale_begins(date)','YYYY-MM-DD HH24:MI:SS') >to_date('$sale_ends(date)', 'YYYY-MM-DD HH24:MI:SS')"] ==1} { @@ -66,14 +70,17 @@ } } -# error checking done +# Error checking done -# if offer_code_needed is yes_generate, I need to generate a offer_code +# If offer_code_needed is yes_generate, I need to generate a +# offer_code + if { $offer_code_needed == "yes_generate" } { set offer_code [ec_generate_random_string 8] } -# for the case where no offer code is required to get the sale price +# For the case where no offer code is required to get the sale price + if { ![info exists offer_code] } { set offer_code "" } @@ -126,4 +133,4 @@ [ad_admin_footer] -" \ No newline at end of file +" Index: openacs-4/packages/ecommerce/www/admin/products/sale-price-edit-2.tcl =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/ecommerce/www/admin/products/sale-price-edit-2.tcl,v diff -u -r1.2 -r1.3 --- openacs-4/packages/ecommerce/www/admin/products/sale-price-edit-2.tcl 31 Jan 2002 22:43:54 -0000 1.2 +++ openacs-4/packages/ecommerce/www/admin/products/sale-price-edit-2.tcl 26 May 2002 04:36:50 -0000 1.3 @@ -1,20 +1,22 @@ -# www/[ec_url_concat [ec_url] /admin]/products/sale-price-edit-2.tcl ad_page_contract { - Update a sale price. - @author Eve Andersson (eveander@arsdigita.com) - @creation-date Summer 1999 - @cvs-id sale-price-edit-2.tcl,v 3.1.6.3 2000/08/18 20:23:47 stevenp Exp - @author ported by Jerry Asher (jerry@theashergroup.com) + Update a sale price. + + @author Eve Andersson (eveander@arsdigita.com) + @creation-date Summer 1999 + @author ported by Jerry Asher (jerry@theashergroup.com) + @author revised by Bart Teeuwisse + @revision-date April 2002 + } { - sale_price_id:integer,notnull - product_id:integer,notnull - sale_price:notnull - sale_name:optional - sale_begins:array,date - sale_ends:array,date - offer_code_needed - offer_code:optional + sale_price_id:integer,notnull + product_id:integer,notnull + sale_price:notnull + sale_name:html,optional + sale_begins:array,date + sale_ends:array,date + offer_code_needed + offer_code:optional } ad_require_permission [ad_conn package_id] admin @@ -25,13 +27,13 @@ } page_validation { -# ec_date_widget_validate sale_begins + # ec_date_widget_validate sale_begins } { - ec_time_widget_validate sale_begins + ec_time_widget_validate sale_begins } { -# ec_date_widget_validate sale_ends + # ec_date_widget_validate sale_ends } { - ec_time_widget_validate sale_ends + ec_time_widget_validate sale_ends } set exception_count 0 @@ -47,64 +49,64 @@ return } -# error checking done +# Error checking done set product_name [ec_product_name $product_id] -# if offer_code_needed is yes_generate, I need to generate a offer_code +# If offer_code_needed is yes_generate, I need to generate a +# offer_code + if { $offer_code_needed == "yes_generate" } { set offer_code [ec_generate_random_string 8] } -# for the case where no offer code is required to get the sale price +# For the case where no offer code is required to get the sale price + if { ![info exists offer_code] } { set offer_code "" } -doc_body_append "[ad_admin_header "Confirm Sale Price for $product_name"] +doc_body_append " + [ad_admin_header "Confirm Sale Price for $product_name"] -

        Confirm Sale Price for $product_name

        +

        Confirm Sale Price for $product_name

        -[ad_admin_context_bar [list "../" "Ecommerce([ec_system_name])"] [list "index.tcl" "Products"] [list "one.tcl?[export_url_vars product_id]" $product_name] "Confirm Sale Price"] + [ad_admin_context_bar [list "../" "Ecommerce([ec_system_name])"] [list "index.tcl" "Products"] [list "one.tcl?[export_url_vars product_id]" $product_name] "Confirm Sale Price"] -
        -" +
        " set currency [ad_parameter -package_id [ec_id] Currency ecommerce] +doc_body_append " + + + + + + + + + + + + + + + + + + + + + +
        Sale Price[ec_pretty_price $sale_price $currency]
        Name$sale_name
        Sale Begins[util_AnsiDatetoPrettyDate [ec_date_text sale_begins]] [ec_time_text sale_begins]
        Sale Ends[util_AnsiDatetoPrettyDate [ec_date_text sale_ends]] [ec_time_text sale_ends]
        Offer Code[ec_decode $offer_code "" "None Needed" $offer_code]
        - -doc_body_append " - - - - - - - - - - - - - - - - - - - - -
        Sale Price[ec_pretty_price $sale_price $currency]
        Name$sale_name
        Sale Begins[util_AnsiDatetoPrettyDate [ec_date_text sale_begins]] [ec_time_text sale_begins]
        Sale Ends[util_AnsiDatetoPrettyDate [ec_date_text sale_ends]] [ec_time_text sale_ends]
        Offer Code[ec_decode $offer_code "" "None Needed" $offer_code]
        - -
        -[export_form_vars sale_price_id product_id product_name sale_price sale_name offer_code] - - -
        - -
        - -
        -[ad_admin_footer] -" \ No newline at end of file +
        + [export_form_vars sale_price_id product_id product_name sale_price sale_name offer_code] + + +
        + +
        +
        + [ad_admin_footer]" Index: openacs-4/packages/ecommerce/www/admin/products/sale-price-edit-3-postgresql.xql =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/ecommerce/www/admin/products/sale-price-edit-3-postgresql.xql,v diff -u -r1.1 -r1.2 --- openacs-4/packages/ecommerce/www/admin/products/sale-price-edit-3-postgresql.xql 10 Jul 2001 20:33:53 -0000 1.1 +++ openacs-4/packages/ecommerce/www/admin/products/sale-price-edit-3-postgresql.xql 26 May 2002 04:36:50 -0000 1.2 @@ -1,24 +1,25 @@ - postgresql7.1 + + postgresql + 7.1 + - - - -update ec_sale_prices -set sale_price=:sale_price, - sale_begins=to_date(:sale_begins,'YYYY-MM-DD HH24:MI:SS'), - sale_ends=to_date(:sale_ends,'YYYY-MM-DD HH24:MI:SS'), - sale_name=:sale_name, - offer_code=:offer_code, - last_modified=current_timestamp, - last_modifying_user=:user_id, - modified_ip_address=:peeraddr -where sale_price_id=:sale_price_id + + + update ec_sale_prices + set sale_price=:sale_price, + sale_begins = to_date(:sale_begins,'YYYY-MM-DD HH24:MI:SS'), + sale_ends = to_date(:sale_ends,'YYYY-MM-DD HH24:MI:SS'), + sale_name=:sale_name, + offer_code=:offer_code, + last_modified = current_timestamp, + last_modifying_user = :user_id, + modified_ip_address = :peeraddr + where sale_price_id = :sale_price_id + + - - - - + Index: openacs-4/packages/ecommerce/www/admin/products/sale-price-edit-3.tcl =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/ecommerce/www/admin/products/sale-price-edit-3.tcl,v diff -u -r1.1 -r1.2 --- openacs-4/packages/ecommerce/www/admin/products/sale-price-edit-3.tcl 20 Apr 2001 20:51:14 -0000 1.1 +++ openacs-4/packages/ecommerce/www/admin/products/sale-price-edit-3.tcl 26 May 2002 04:36:50 -0000 1.2 @@ -1,49 +1,52 @@ -# www/[ec_url_concat [ec_url] /admin]/products/sale-price-edit-3.tcl ad_page_contract { - Update a sale price. - @author Eve Andersson (eveander@arsdigita.com) - @creation-date Summer 1999 - @cvs-id sale-price-edit-3.tcl,v 3.2.2.3 2000/08/18 20:23:47 stevenp Exp - @author ported by Jerry Asher (jerry@theashergroup.com) + Update a sale price. + + @author Eve Andersson (eveander@arsdigita.com) + @creation-date Summer 1999 + @author ported by Jerry Asher (jerry@theashergroup.com) + @author revised by Bart Teeuwisse + @revision-date April 2002 + } { - sale_price_id:integer,notnull - product_id:integer,notnull - sale_price:notnull - sale_name - sale_begins - sale_ends - offer_code + sale_price_id:integer,notnull + product_id:integer,notnull + sale_price:notnull + sale_name:html + sale_begins + sale_ends + offer_code } -# check the validity of sale price + +# Check the validity of sale price + ad_require_permission [ad_conn package_id] admin if {![regexp {^[0-9|.]+$} $sale_price match ] } { - ad_return_complaint 1 "
      • Please enter a number for sale price." + ad_return_complaint 1 "
      • Please enter a number for sale price.
      • " return } if {[regexp {^[.]$} $sale_price match ]} { - ad_return_complaint 1 "
      • Please enter a number for the sale price." + ad_return_complaint 1 "
      • Please enter a number for the sale price.
      • " return } -# we need them to be logged in +# We need them to be logged in + ad_maybe_redirect_for_registration set user_id [ad_get_user_id] - set peeraddr [ns_conn peeraddr] db_dml sale_price_update " -update ec_sale_prices -set sale_price=:sale_price, - sale_begins=to_date(:sale_begins,'YYYY-MM-DD HH24:MI:SS'), - sale_ends=to_date(:sale_ends,'YYYY-MM-DD HH24:MI:SS'), - sale_name=:sale_name, - offer_code=:offer_code, - last_modified=sysdate, - last_modifying_user=:user_id, - modified_ip_address=:peeraddr -where sale_price_id=:sale_price_id -" + update ec_sale_prices + set sale_price = :sale_price, + sale_begins = to_date(:sale_begins,'YYYY-MM-DD HH24:MI:SS'), + sale_ends = to_date(:sale_ends,'YYYY-MM-DD HH24:MI:SS'), + sale_name = :sale_name, + offer_code = :offer_code, + last_modified = sysdate, + last_modifying_user = :user_id, + modified_ip_address = :peeraddr + where sale_price_id = :sale_price_id" ad_returnredirect "sale-prices.tcl?[export_url_vars product_id]" Index: openacs-4/packages/ecommerce/www/admin/products/sale-price-edit.tcl =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/ecommerce/www/admin/products/sale-price-edit.tcl,v diff -u -r1.2 -r1.3 --- openacs-4/packages/ecommerce/www/admin/products/sale-price-edit.tcl 31 Jan 2002 22:43:54 -0000 1.2 +++ openacs-4/packages/ecommerce/www/admin/products/sale-price-edit.tcl 26 May 2002 04:36:50 -0000 1.3 @@ -1,69 +1,71 @@ -# www/[ec_url_concat [ec_url] /admin]/products/sale-price-edit.tcl ad_page_contract { - Edit a sale price. - @author Eve Andersson (eveander@arsdigita.com) - @creation-date Summer 1999 - @cvs-id sale-price-edit.tcl,v 3.1.6.3 2000/08/18 20:23:47 stevenp Exp - @author ported by Jerry Asher (jerry@theashergroup.com) + Edit a sale price. + + @author Eve Andersson (eveander@arsdigita.com) + @creation-date Summer 1999 + @author ported by Jerry Asher (jerry@theashergroup.com) + @author revised by Bart Teeuwisse + @revision-date April 2002 + } { - product_id:integer,notnull - sale_price_id:integer,notnull + product_id:integer,notnull + sale_price_id:integer,notnull } ad_require_permission [ad_conn package_id] admin set product_name [ec_product_name $product_id] -doc_body_append "[ad_admin_header "Edit Sale Price for $product_name"] +doc_body_append " + [ad_admin_header "Edit Sale Price for $product_name"] -

        Edit Sale Price for $product_name

        +

        Edit Sale Price for $product_name

        -[ad_admin_context_bar [list "../" "Ecommerce([ec_system_name])"] [list "index.tcl" "Products"] [list "one.tcl?[export_url_vars product_id]" $product_name] "Edit Sale Price"] + [ad_admin_context_bar [list "../" "Ecommerce([ec_system_name])"] [list "index.tcl" "Products"] [list "one.tcl?[export_url_vars product_id]" $product_name] "Edit Sale Price"] -
        -
        +
        + + + [export_form_vars product_id product_name sale_price_id]" -[export_form_vars product_id product_name sale_price_id] -" +db_1row sale_price_select " + select sale_price, to_char(sale_begins,'YYYY-MM-DD HH24:MI:SS') as sale_begins, to_char(sale_ends,'YYYY-MM-DD HH24:MI:SS') as sale_ends, sale_name, offer_code + from ec_sale_prices + where sale_price_id = :sale_price_id" +doc_body_append " + + + + + + + + + + + + + + + + + + + + + +
        Sale Price (in [ad_parameter -package_id [ec_id] Currency ecommerce])
        Name (like Special Offer or Introductory Price or Sale Price)
        Sale Begins[ad_dateentrywidget sale_begins [ec_date_with_time_stripped $sale_begins]] [ec_time_widget sale_begins [lindex [split $sale_begins " "] 1]]
        Sale Ends[ad_dateentrywidget sale_ends [ec_date_with_time_stripped $sale_ends]] [ec_time_widget sale_ends [lindex [split $sale_ends " "] 1]]
        Offer Code None needed
        + Require this code: +
        + Please generate a [ec_decode $offer_code "" "" "new "]code +
        -db_1row sale_price_select "select sale_price, to_char(sale_begins,'YYYY-MM-DD HH24:MI:SS') as sale_begins, to_char(sale_ends,'YYYY-MM-DD HH24:MI:SS') as sale_ends, sale_name, offer_code from ec_sale_prices where sale_price_id=:sale_price_id" +
        + +
        -doc_body_append " - - - - - - - - - - - - - - - - - - - - -
        Sale Price (in [ad_parameter -package_id [ec_id] Currency ecommerce])
        Name (like Special Offer or Introductory Price or Sale Price)
        Sale Begins[ad_dateentrywidget sale_begins [ec_date_with_time_stripped $sale_begins]] [ec_time_widget sale_begins [lindex [split $sale_begins " "] 1]]
        Sale Ends[ad_dateentrywidget sale_ends [ec_date_with_time_stripped $sale_ends]] [ec_time_widget sale_ends [lindex [split $sale_ends " "] 1]]
        Offer Code None needed
        - Require this code: -
        - Please generate a [ec_decode $offer_code "" "" "new "]code -
        +
        -

        - -

        - -
        - - - -[ad_admin_footer] -" \ No newline at end of file + [ad_admin_footer] " Index: openacs-4/packages/ecommerce/www/admin/products/sale-prices.tcl =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/ecommerce/www/admin/products/sale-prices.tcl,v diff -u -r1.2 -r1.3 --- openacs-4/packages/ecommerce/www/admin/products/sale-prices.tcl 31 Jan 2002 22:43:54 -0000 1.2 +++ openacs-4/packages/ecommerce/www/admin/products/sale-prices.tcl 26 May 2002 04:36:50 -0000 1.3 @@ -1,11 +1,10 @@ -# www/[ec_url_concat [ec_url] /admin]/products/sale-prices.tcl ad_page_contract { - Let's site admin define a special time-limited price for an item. + Let's site admin define a special time-limited price for an item. - @author Eve Andersson (eveander@arsdigita.com) - @creation-date June 1999 - @cvs-id sale-prices.tcl,v 3.1.6.3 2000/08/18 20:23:47 stevenp Exp - @author ported by Jerry Asher (jerry@theashergroup.com) + @author Eve Andersson (eveander@arsdigita.com) + @creation-date June 1999 + @author ported by Jerry Asher (jerry@theashergroup.com) + @author revised by Bart Teeuwisse } { product_id:integer,notnull price:optional @@ -46,19 +45,28 @@ } } +set currency [ad_parameter -package_id [ec_id] Currency ecommerce] + doc_body_append "[ad_admin_header "Sale Prices for $product_name"]

        Sale Price for $product_name

        [ad_admin_context_bar [list "../" "Ecommerce([ec_system_name])"] [list "index.tcl" "Products"] [list "one.tcl?[export_url_vars product_id]" "One"] "Sale Prices"]
        +" +if {[info exists price]} { + doc_body_append " +

        Regular Price

        +
        + Regular: [ec_pretty_price $price $currency] +
        " +} +doc_body_append "

        Current Sale Prices

          " -set currency [ad_parameter -package_id [ec_id] Currency ecommerce] - set sale_price_counter 0 db_foreach current_sales_select "select sale_price_id, sale_name, sale_price, offer_code, to_char(sale_begins,'YYYY-MM-DD HH24:MI:SS') as sale_begins, to_char(sale_ends,'YYYY-MM-DD HH24:MI:SS') as sale_ends, decode(sign(sysdate-sale_begins),1,1,0) as sale_begun_p, decode(sign(sysdate-sale_ends),1,1,0) as sale_expired_p from ec_sale_prices_current Index: openacs-4/packages/ecommerce/www/admin/products/upload-2.tcl =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/ecommerce/www/admin/products/upload-2.tcl,v diff -u -r1.2 -r1.3 --- openacs-4/packages/ecommerce/www/admin/products/upload-2.tcl 24 Nov 2001 03:36:39 -0000 1.2 +++ openacs-4/packages/ecommerce/www/admin/products/upload-2.tcl 26 May 2002 04:36:50 -0000 1.3 @@ -11,11 +11,13 @@ } # We need them to be logged in + ad_require_permission [ad_conn package_id] admin set user_id [ad_get_user_id] set peeraddr [ns_conn peeraddr] # Grab package_id as context_id + set context_id [ad_conn package_id] doc_body_append "[ad_admin_header "Uploading Products"] @@ -30,44 +32,57 @@ " # Get the name of the transfered CSV file + set unix_file_name ${csv_file.tmpfile} # Check that the file is readable. + if { ![file readable $unix_file_name] } { doc_body_append "Cannot read file $unix_file_name" return } -# Accept only field names that exist in the ec_product table and -# are not set automatically like creation_date. -set legal_field_names {sku product_name one_line_description detailed_description search_keywords price no_shipping_avail_p shipping shipping_additional weight present_p active_p url template_id stock_status color_list size_list style_list email_on_purchase_list} +# Accept only field names that exist in the ec_product table and are +# not set automatically like creation_date. +set legal_field_names {sku product_name one_line_description detailed_description search_keywords price no_shipping_avail_p \ + shipping shipping_additional weight present_p active_p url template_id stock_status color_list \ + size_list style_list email_on_purchase_list} + # Check each entry in the CSV for the following required fields. # These fields are required so that we can check if a product already # in the products table and should be update rather than created. + set required_field_names {sku product_name} # Initialize each legal field name as the CSV file might not mention # each and every one of them. + foreach legal_field_name $legal_field_names { set $legal_field_name "" } # Start reading. + set csvfp [open $unix_file_name] set count 0 set errors 0 set success_count 0 -# Continue reading the file till the end but stop when an error occured. + +# Continue reading the file till the end but stop when an error +# occured. + while { [ns_getcsv $csvfp elements] != -1 && !$errors} { incr count if { $count == 1 } { - # First row, grab the field names and their number + # First row, grab the field names and their number. + set field_names $elements set number_of_fields [llength $elements] # Check the field names against the list of legal names + foreach field_name $field_names { if {[lsearch -exact $legal_field_names $field_name] == -1} { incr errors @@ -78,35 +93,42 @@ # Subsequent rows, thus a product - # Reset the required fields to NULL so that we can later check if - # the CSV file gave them a value. + # Reset the required fields to NULL so that we can later check + # if the CSV file gave them a value. + foreach required_field_name $required_field_names { set $required_field_name "" } # Assign the values in the CSV to the field names. + for { set i 0 } { $i < $number_of_fields } { incr i } { set [lindex $field_names $i] [lindex $elements $i] } # Check if all the required fields have been given a value + foreach required_field_name $required_field_names { if {[set $required_field_name] == ""} { incr errors } } - # Create or update the product if all the required fields - # were given values. + # Create or update the product if all the required fields were + # given values. + if {!$errors} { # Check if there is already product with the give sku. - # Set product_id to NULL so that ACS picks a unique id if there no - # product with the gicen sku. + # Set product_id to NULL so that ACS picks a unique id if + # there no product with the gicen sku. + set product_id [db_string product_check {select product_id from ec_products where sku = :sku;} -default ""] if { $product_id != ""} { - # We found a product_id for the given sku, let's update the product. + # We found a product_id for the given sku, let's + # update the product. + if { [catch {db_dml product_update " update ec_products set user_id = :user_id, @@ -138,11 +160,12 @@ } else { # Generate a product_id + set product_id [db_nextval acs_object_id_seq] - # Dirname will be the first four letters - # (lowercase) of the product_name followed by the product_id - # (for uniqueness) + # Dirname will be the first four letters (lowercase) + # of the product_name followed by the product_id (for + # uniqueness) regsub -all {[^a-zA-Z]} $product_name "" letters_in_product_name set letters_in_product_name [string tolower $letters_in_product_name] @@ -158,7 +181,9 @@ set full_dirname "$subdirectory/$dirname" ec_assert_directory $full_dirname - # There is no product with sku :sku so create a new product. + # There is no product with sku :sku so create a new + # product. + if { [catch {db_exec_plsql product_insert " select ec_product__new( :product_id, @@ -199,84 +224,14 @@ doc_body_append "FAILURE! Product update of new product $product_name failed with error:<\p>

          $errmsg

          " } } + # Product line is completed, increase counter + incr success_count } } } -# while { [ns_getcsv $csvfp elements] != -1 } { -# incr count -# if { $count == 1 } { -# # first time through, we grab the number of columns and their names -# set number_of_columns [llength $elements] -# set columns $elements - -# # These 2 lines added 1999-08-08 -# set product_id_column [lsearch -exact $columns "product_id"] -# set product_name_column [lsearch -exact $columns "product_name"] - -# # Grap all column names -# set column_names $elements - -# } else { -# # this line is a product - -# # All this directory stuff added 1999-08-08 -# # To be consistent with directory-creation that occurs when a -# # product is added, dirname will be the first four letters -# # (lowercase) of the product_name followed by the product_id -# # (for uniqueness) -# regsub -all {[^a-zA-Z]} [lindex $elements $product_name_column] "" letters_in_product_name -# set letters_in_product_name [string tolower $letters_in_product_name] -# if [catch {set dirname "[string range $letters_in_product_name 0 3][lindex $elements $product_id_column]"}] { -# #maybe there aren't 4 letters in the product name -# set dirname "$letters_in_product_name[lindex $elements $product_id_column]" -# } - -# set columns_sql "insert into ec_products (creation_date, available_date, dirname, last_modified, last_modifying_user, modified_ip_address " -# set values_sql " values (now(), now(), :dirname, now(), :user_id, :ip " -# for { set i 0 } { $i < $number_of_columns } { incr i } { -# append columns_sql ", [lindex $columns $i]" -# set var_name [lindex $column_names $i] -# set $var_name [lindex $elements $i] -# append values_sql ", :$var_name" -# } -# set sql "$columns_sql ) $values_sql )" - -# # we have to also write a row into ec_custom_product_field_values -# # for consistency with add*.tcl (added 1999-08-08) -# db_transaction { - -# # Insert the first 16 fields. A limitation of Postgres prevends us from inserting -# # all fields in one swoop. -# if { [catch {db_dml product_insert $sql} errmsg] } { -# doc_body_append "FAILURE! SQL: $sql
          $number_of_columns
          $product_id_column
          $product_name_column
          \n" -# } else { - -# # Successfully created a new product, time to add the missing fields. -# if { [catch {db_dml product_update $sql} errmsg] } { -# doc_body_append "FAILURE! SQL: produt_update
          \n" -# } else { - -# # New product is complete, increase counter and add customer product field. -# incr success_count -# if { [catch {db_dml custom_product_field_insert "insert into ec_custom_product_field_values (product_id, last_modified, last_modifying_user, modified_ip_address) values (:val_$product_id_column, now(), :user_id, :peeraddr)" } errmsg] } { -# doc_body_append "FAILURE! Insert into ec_custom_product_field_values failed for product_id=[set val_$product_id_column]
          \n" -# } -# } -# } - -# # Get the directory where dirname is stored -# set subdirectory "[ec_data_directory][ec_product_directory][ec_product_file_directory [lindex $elements $product_id_column]]" -# ec_assert_directory $subdirectory - -# set full_dirname "$subdirectory/$dirname" -# ec_assert_directory $full_dirname -# } -# } -# } - if { $success_count == 1 } { set product_string "product" } else { Index: openacs-4/packages/ecommerce/www/admin/sales-tax/index.tcl =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/ecommerce/www/admin/sales-tax/index.tcl,v diff -u -r1.2 -r1.3 --- openacs-4/packages/ecommerce/www/admin/sales-tax/index.tcl 22 Oct 2001 07:11:55 -0000 1.2 +++ openacs-4/packages/ecommerce/www/admin/sales-tax/index.tcl 26 May 2002 04:36:50 -0000 1.3 @@ -99,7 +99,7 @@ nexus in 50 states, you'll probably have to add in a fair amount of complexity to collect tax more precisely or at least remit sales tax more precisely. See -the ecommerce chapter +the ecommerce chapter of Philip and Alex's Guide to Web Publishing for more on this mournful topic. Index: openacs-4/packages/ecommerce/www/doc/audit.adp =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/ecommerce/www/doc/audit.adp,v diff -u -r1.1 -r1.2 --- openacs-4/packages/ecommerce/www/doc/audit.adp 20 Apr 2001 20:51:14 -0000 1.1 +++ openacs-4/packages/ecommerce/www/doc/audit.adp 26 May 2002 04:36:50 -0000 1.2 @@ -1,215 +1,290 @@ - -Audit Trail Package + - +

          The Big Picture

          -

          The Big Picture

          +

          When you have more than one person updating information in a + table, you want to record all the values of a row over time. This + package gives you (1) a standard way of naming tables and triggers + in Oracle, (2) two Tcl procedures (ec_audit_trail and + ec_audit_trail_for_table) that helps you display the + old values of a row, including highlighting particular changed + columns, (3) a Tcl procedure (ec_audit_delete_row) + that simplifies the logging of a deleted row, and (4) an example + user interface ( audit-tables, + audit-table, audit) to retrieve and + display audit histories.

          -When you have more than one person updating information in a table, you -want to record all the values of a row over time. This package gives -you (1) a standard way of naming tables and triggers in Oracle, (2) two -Tcl procedures (ec_audit_trail and -ec_audit_trail_for_table) that helps you display the old -values of a row, including highlighting particular changed columns, (3) -a Tcl procedure (ec_audit_delete_row) that simplifies the -logging of a deleted row, and (4) an example user interface ( -audit-tables, audit-table, audit) to retrieve and display audit histories. +

          Steps for Auditing a Table

          -

          Steps for Auditing a Table

          +

          We record old information in a separate audit table (see the triggers + chapter of SQL for Web Nerds for more + explanation of this idea).

          -We record old information in a separate audit table (see -the triggers chapter of -SQL for Web Nerds for more explanation of this idea). +

          We distinguish between the on-line transaction processing (OLTP) + tables that are used in the minute-by-minute operation of the + server and the audit tables.

          -

          +

          Here are the steps to add audit trails:

          -We distinguish between the on-line transaction processing (OLTP) tables -that are used in the minute-by-minute operation of the server and the -audit tables. +
            + +
          • +

            Decide which OLTP tables need auditing. Three fields must be + added to each OLTP table to save information about who was + making changes, what IP address they were using, and the date + they made the changes.

            -

            +

            +
            +	  create table ec_products (
            +	  product_id              integer not null primary key,
            +	  product_name            varchar(200),
            +	  one_line_description    varchar(400),
             
            -Here are the steps to add audit trails:
            +	  ...
             
            -
              + -- the user ID and IP address of the last modifier of the product + last_modified date not null, + last_modifying_user not null references users, + modified_ip_address varchar(20) not null + ); +
            +
            +
          • -
          • Decide which OLTP tables need auditing. Three fields must be added to -each OLTP table to save information about who was making changes, what -IP address they were using, and the date they made the changes. +
          • +

            Create one audit table for each OLTP table that is being + audited. By convention, this table should be named by adding + an "_audit" suffix to the OLTP table name. The audit table + has all the columns of the main table, with the same data + types but no integrity constraints. Also add a flag to + indicate that an audit entry is for a deleted row in the OLTP + table.

            -
            -
            -create table ec_products (
            -        product_id              integer not null primary key,
            -        product_name            varchar(200),
            -        one_line_description    varchar(400),
            +      
            +
            +	  create table ec_products_audit as
            +	  select * from ec_products where 1 = 0;
             
            -        ...
            +	  alter table ec_products_audit add (
            +	  delete_p    char(1) default('f') check (delete_p in ('t','f'))
            +	  );
            +	
            +
            +
          • - -- the user ID and IP address of the last modifier of the product - last_modified date not null, - last_modifying_user not null references users, - modified_ip_address varchar(20) not null -); -
  • - +
  • +

    Add one update trigger for each OLTP table.

    +
    +
    +	  create or replace trigger ec_products_audit_tr
    +	  before update or delete on ec_products
    +	  for each row
    +	  begin
    +	  insert into ec_products_audit (
    +	  product_id, product_name, 
    +	  one_line_description, 
     
    -
  • Create one audit table for each OLTP table that is being audited. -By convention, this table should be named by adding an "_audit" suffix -to the OLTP table name. -The audit table has all the columns of the main table, with the same -data types but no integrity constraints. Also add a flag to indicate -that an audit entry is for a deleted row in the OLTP table. + ... -
    -
    -create table ec_products_audit as
    -   select * from ec_products where 1 = 0;
    +	  last_modified,
    +	  last_modifying_user, modified_ip_address
    +	  ) values (
    +	  :old.product_id, :old.product_name, 
    +	  :old.one_line_description, 
     
    -alter table ec_products_audit add (
    -        delete_p    char(1) default('f') check (delete_p in ('t','f'))
    -);
    -
    -
    + ... -
  • Add one update trigger for each OLTP table. -
    -
    -create or replace trigger ec_products_audit_tr
    -before update or delete on ec_products
    -for each row
    -begin
    -        insert into ec_products_audit (
    -        product_id, product_name, 
    -        one_line_description, 
    +	  :old.last_modified,
    +	  :old.last_modifying_user, :old.modified_ip_address
    +	  );
    +	  end;
    +	  /
    +	  show errors
    +	
    +
    - ... +

    Note that it is not possible to automatically populate the + audit table on deletion because we need the IP address of the + deleting user.

    +
  • - last_modified, - last_modifying_user, modified_ip_address - ) values ( - :old.product_id, :old.product_name, - :old.one_line_description, +
  • +

    Change any script that deletes rows from an audited table. + It should call ec_audit_delete_row with args key + list, column name list, and audit_table_name. This procedure + calls ad_get_user_id and ns_conn + peeraddr and records the user_id and IP address of the + user deleting the row.

    - ... +
    +
    +	  
    +	    db_transaction {
    +	    db_dml unused "delete from ec_products where product_id=$product_id"
    +	    ec_audit_delete_row [list $product_id] [list product_id] ec_products_audit
    +	    }
    +	  
    +	
    +
    +
  • - :old.last_modified, - :old.last_modifying_user, :old.modified_ip_address - ); -end; -/ -show errors -
    -
    +
  • +

    Insert a call to ec_audit_trail in an admin page + to show the changes made to a key. Insert a call to + ec_audit_trail_for_table to show the changes made + to an entire table over a specified period of time.

    +
  • -Note that it is not possible to automatically populate the audit table on -deletion because we need the IP address of the deleting user. +
  • +

    optionally define two views to provide "user + friendly" audits. Look at the ticket + tracker data model tables ticket_pretty and + ticket_pretty_audit for an example. This has the + benefit of decoding the meaningless integer ID's and + highlighting potential data integrity violations.

    +
  • + -
  • Change any script that deletes rows from an audited table. It -should call ec_audit_delete_row with args key list, column -name list, and audit_table_name. This procedure calls -ad_get_user_id and ns_conn peeraddr and records -the user_id and IP address of the user deleting the row. +

    Reference

    -
    -
    
    -db_transaction {
    -db_dml unused "delete from ec_products where product_id=$product_id"
    -ec_audit_delete_row [list $product_id] [list product_id] ec_products_audit
    -}
    -
    -
    +

    Audit columns:

    -
  • Insert a call to ec_audit_trail in an admin page to -show the changes made to a key. Insert a call to ec_audit_trail_for_table to show the changes made to an entire table over a specified period of time. +
      +
    • last_modified The date the row was last changed.
    • +
    • last_modifying_user The ID of the user who last changed the row.
    • +
    • modified_ip_address The IP Address the change request came from.
    • +
    • delete_p The true/false tag that indicates the audit table entry is recording information on the user who deleted a row.
    • +
    -
  • optionally define two views to provide "user friendly" -audits. Look at the -ticket -tracker data model tables ticket_pretty and -ticket_pretty_audit for an example. This has the -benefit of decoding the meaningless integer ID's and highlighting potential data -integrity violations. - +

    ec_audit_trail_for_table

    -

    Reference

    +
    +

    Returns an audit trail across an entire table, (multiple + keys).

    -Audit columns: +
      -
        -
      • last_modified The date the row was last changed. -
      • last_modifying_user The ID of the user who last changed the row. -
      • modified_ip_address The IP Address the change request came from. -
      • delete_p The true/false tag that indicates the audit table entry is recording information on the user who deleted a row. -
      +
    • db Database handle.
    • -Arguments for -ec_audit_trail_for_table +
    • main_table_name Table that holds the main record. If + sent an empty string as main_table_name, ec_audit_trail assumes + that the audit_table_name has all current records.
    • -
        +
      • audit_table_name Table that holds the audit + records.
      • -Returns an audit trail across an entire table, (multiple keys). -

        +

      • id_column Column name of the primary key in + audit_table_name and main_table_name.
      • -
      • db Database handle. -
      • main_table_name Table that holds the main record. If sent an empty string as main_table_name, ec_audit_trail assumes that the audit_table_name has all current records. -
      • audit_table_name Table that holds the audit records. -
      • id_column Column name of the primary key in audit_table_name and main_table_name. -
      • start_date (optional) ANSI standard time to begin viewing records. -
      • end_date (optional) ANSI standard time to stop viewing records. -
      • audit_url (optional) URL of a tcl page that would display the full audit history of an record. Form variables for that page: id id_column main_table_name and audit_table_name. -
      • restore_url (optional) (future improvement) URL of a tcl page that would restore a given record to the main table. Form variables for the page: id id_column main_table_name audit_table_name and rowid. +
      • start_date (optional) ANSI standard time to begin + viewing records.
      • -
      +
    • end_date (optional) ANSI standard time to stop viewing + records.
    • -Arguments for -ec_audit_trail +
    • audit_url (optional) URL of a tcl page that would + display the full audit history of an record. Form variables for + that page: id id_column main_table_name and + audit_table_name.
    • -
        +
      • restore_url (optional) (future improvement) URL of a + tcl page that would restore a given record to the main + table. Form variables for the page: id id_column main_table_name + audit_table_name and rowid. -Returns an audit trail of a single key in a table. -

        +

      -
    • db Database handle. -
    • id_list List of ids representing the unique record you are processing. -
    • audit_table_name Table that holds the audit records. -
    • main_table_name Table that holds the main record. If sent an empty string as main_table_name, ec_audit_trail assumes that the audit_table_name has all current records. -
    • id_column_list Column names of the unique key in audit_table_name and main_table_name. -
    • columns_not_reported (optional) -Tcl list of column names in audit_table_name and main_table - that you don't want displayed. -
    • start_date (optional) ANSI standard time to begin viewing records. -
    • end_date (optional) ANSI standard time to stop viewing records. -
    • restore_url (optional) (future improvement)URL of a tcl page that would restore a given record to the main table. Form variables for the page: id id_column main_table_name audit_table_name and rowid. +
    - +

    ec_audit_trail

    -Arguments for ec_audit_delete_row +
    -
      +

      Returns an audit trail of a single key in a table.

      + +
        -Creates a row in the audit table to log when, who, and from what IP address a row was deleted. -

        +

      • db Database handle.
      • -
      • db Database handle. -
      • id_list Tcl list of the ids specifying the unique record you are processing. (Or the list of ID's in the case of a map table.) -
      • id_column_list Tcl list of the column names of the unique key in audit_table_name. -
      • audit_table_name Table that holds the audit records. +
      • id_list List of ids representing the unique record you + are processing.
      • +
      • audit_table_name Table that holds the audit + records.
      • -
      +
    • main_table_name Table that holds the main record. If + sent an empty string as main_table_name, ec_audit_trail assumes + that the audit_table_name has all current records.
    • -

      Future Improvements

      +
    • id_column_list Column names of the unique key in + audit_table_name and main_table_name.
    • -The ec_audit_trail and ec_audit_trail_for_table procedures could be extended to restore previous values. The restore_url would be a pointer to a script that could restore an old row to the main table. The script would need to query the data dictionary for the columns of the audit and main tables. It might also require the user to confirm if a current record would be overwritten by the restore option. +
    • columns_not_reported (optional) Tcl list of column + names in audit_table_name and main_table that you don't want + displayed.
    • + +
    • start_date (optional) ANSI standard time to begin + viewing records.
    • + +
    • end_date (optional) ANSI standard time to stop viewing + records.
    • + +
    • restore_url (optional) (future improvement)URL of a + tcl page that would restore a given record to the main + table. Form variables for the page: id id_column main_table_name + audit_table_name and rowid. + +
    + +
    + +

    ec_audit_delete_row

    + +
    + +

    Creates a row in the audit table to log when, who, and from what + IP address a row was deleted.

    + +
      + +
    • db Database handle.
    • + +
    • id_list Tcl list of the ids specifying the unique + record you are processing. (Or the list of ID's in the case of a + map table.)
    • + +
    • id_column_list Tcl list of the column names of the + unique key in audit_table_name.
    • + +
    • audit_table_name Table that holds the audit + records.
    • + +
    + +
    + +

    Future Improvements

    + +

    The ec_audit_trail and ec_audit_trail_for_table procedures could + be extended to restore previous values. The restore_url would be a + pointer to a script that could restore an old row to the main + table. The script would need to query the data dictionary for the + columns of the audit and main tables. It might also require the + user to confirm if a current record would be overwritten by the + restore option.

    Index: openacs-4/packages/ecommerce/www/doc/ecommerce-customer-service.adp =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/ecommerce/www/doc/ecommerce-customer-service.adp,v diff -u -r1.1 -r1.2 --- openacs-4/packages/ecommerce/www/doc/ecommerce-customer-service.adp 20 Apr 2001 20:51:14 -0000 1.1 +++ openacs-4/packages/ecommerce/www/doc/ecommerce-customer-service.adp 26 May 2002 04:36:50 -0000 1.2 @@ -1,107 +1,118 @@ - -The Customer Service Submodule of the Ecommerce Module + -The Customer Service Submodule can be found at -@ec_url@admin/customer-service/ -(it is also linked to from the main Ecommerce Administration page). + + @title@ + @signatory@ -

    +

    @title@

    + + + + + + +
    @context_bar@
    +
    -

    Issues and Interactions

    +

    The Customer Service Module can be found at @package_url@admin/customer-service/ + (it is also linked to from the main Ecommerce Administration + page).

    -There are two main concepts underlying the customer service submodule: customer service -interactions and customer service issues. +

    Issues and Interactions

    -

    +

    There are two main concepts underlying the customer service + submodule: customer service interactions and customer service + issues.

    -There is a many-to-many relationship between issues and interactions. During the course -of one interaction, a customer may bring up any number of issues ("My credit card shows -a charge for $7.99, but I thought this ant farm was only supposed to cost $6.99 AND, -while I have you on the phone, I'd like to mention that delivery took three days instead -of the promised two."). Furthermore, if an issue is not resolved the first time it is -brought up, it might span any number of interactions until it is finally closed. +

    There is a many-to-many relationship between issues and + interactions. During the course of one interaction, a customer + may bring up any number of issues ("My credit card shows a charge + for $7.99, but I thought this ant farm was only supposed to cost + $6.99 AND, while I have you on the phone, I'd like to mention that + delivery took three days instead of the promised two."). + Furthermore, if an issue is not resolved the first time it is + brought up, it might span any number of interactions until it is + finally closed.

    -

    -Issues can be categorized either for reporting purposes or so -that different departments of your company can handle the issues. Open issues -are linked to from the front page of the customer service submodule to attract -attention. Whenever email is sent to the customer (either automatically or -by a customer service rep), an issue is created (or added to, if it is based -on a previous issue). This is so that a complete interaction history containing -all correspondence to and from the customer can be maintained. All issues created -due to automatic emails are closed immediately so that they don't get in the way of -other issues. +

    Issues can be categorized either for reporting purposes or so + that different departments of your company can handle the issues. + Open issues are linked to from the front page of the customer + service submodule to attract attention. Whenever email is sent to + the customer (either automatically or by a customer service rep), + an issue is created (or added to, if it is based on a previous + issue). This is so that a complete interaction history containing + all correspondence to and from the customer can be maintained. + All issues created due to automatic emails are closed immediately + so that they don't get in the way of other issues.

    -

    -Small note: the intersection between an issue and an interaction is called an "action" -(i.e., the part of a specific interaction that deals with a specific issue). This rarely -comes up. -

    +

    Small note: the intersection between an issue and an interaction + is called an "action" (i.e., the part of a specific interaction + that deals with a specific issue). This rarely comes up.

    -

    Registered Users and Unregistered Users

    +

    Registered Users and Unregistered Users

    -As a customer service rep, much of your interaction may be with people who -have used the site but are not registered users (people don't become registered -users unless they log in when they order, when they submit product reviews, etc.), -yet you still want to capture the details of the interaction with as much -identifying information about them as you can. +

    As a customer service rep, much of your interaction may be with + people who have used the site but are not registered users (people + don't become registered users unless they log in when they order, + when they submit product reviews, etc.), yet you still want to + capture the details of the interaction with as much identifying + information about them as you can.

    -

    +

    Whenever you record a new interaction, you are asked to enter as + much information as you can gather (or feel comfortable gathering) + about the user. The system then tries to match this person up + with either registered users or unregistered people who have had + interacted previously with customer service. If no match can be + made, a new "user identification record" is created.

    -Whenever you record a new interaction, you are asked to enter as much information -as you can gather (or feel comfortable gathering) about the user. The system then -tries to match this person up with either registered users or unregistered people -who have had interacted previously with customer service. If no match can be -made, a new "user identification record" is created. +

    Each time you view a user identification record, the system sees + if it can match that person up with a registered user of the + system (in case they have registered in the meantime).

    -

    +

    Sending Email to Customers

    -Each time you view a user identification record, the system sees if it can -match that person up with a registered user of the system (in case they -have registered in the meantime). +

    When you're viewing a customer service issue, you can send the + customer email regarding that issue by clicking "send email" at + the top of the page. The contents of your email will + automatically be added to the customer's interaction history and + will become part of the record for that customer service issue.

    -

    +

    If you find yourself using the same phrases over and over again + when you respond to customers' emails, the Canned + Response System will be useful to you. You can enter your + commonly used phrases once, and then whenever you send email + you'll be able to automatically insert any number of these + phrases.

    -

    Sending Email to Customers

    +

    If you want to send email to customers in bulk, then use the Spam System. + You can spam users based on what products they've bought, what + products they've even looked at, by when they've last visited, by + how much they've spent at your site, by which mailing lists + they're signed up for. If you're spamming customers that you + like, you can issue them all gift certificates at the same time.

    -When you're viewing a customer service issue, you can send the customer -email regarding that issue by clicking "send email" at the top of the page. -The contents of your email will automatically be added to the customer's -interaction history and will become part of the record for that customer -service issue. -

    -If you find yourself using the same phrases over and over again when you -respond to customers' emails, the Canned Response System will be useful -to you. You can enter your commonly used phrases once, -and then whenever you send email you'll -be able to automatically insert any number of these phrases. -

    -If you want to send email to customers in bulk, then use the -Spam System. -You can spam users based on what products they've bought, what products -they've even looked at, by when they've last visited, by how much they've -spent at your site, by which mailing lists they're signed up for. -If you're spamming customers that you like, you can -issue them all gift certificates at the same time. -

    -Your email text is also sent through a spell checker before it is sent -to the customer. +

    Your email text is also sent through a spell checker before it is + sent to the customer.

    -

    -

    Picklist Management

    +

    Picklist Management

    -When your customer service data entry people are recording customer -interactions, you want it to take as little effort as possible. One -way to help is to predefine picklists that they can choose from when -entering data. With the Picklist Management tool, -you can specify what goes in what picklist in what order. +

    When your customer service data entry people are recording + customer interactions, you want it to take as little effort as + possible. One way to help is to predefine picklists that they can + choose from when entering data. With the Picklist + Management tool, you can specify what goes in what picklist in + what order.

    -

    Reports

    +

    Reports

    -Reports and statistics are generated so that you can tell what types -of issues are occurring most frequently, which customer service reps -are handing the most interactions, what resources the reps need to use -most often, etc. Each report can be filtered and -sorted in a variety of ways to give you a clear picture of what's -happening and what can be done to improve efficiency. +

    Reports and statistics are generated so that you can tell what + types of issues are occurring most frequently, which customer + service reps are handing the most interactions, what resources the + reps need to use most often, etc. Each report can be filtered and + sorted in a variety of ways to give you a clear picture of what's + happening and what can be done to improve efficiency.

    Index: openacs-4/packages/ecommerce/www/doc/ecommerce-customer-service.tcl =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/ecommerce/www/doc/ecommerce-customer-service.tcl,v diff -u -r1.1 -r1.2 --- openacs-4/packages/ecommerce/www/doc/ecommerce-customer-service.tcl 20 Apr 2001 20:51:14 -0000 1.1 +++ openacs-4/packages/ecommerce/www/doc/ecommerce-customer-service.tcl 26 May 2002 04:36:50 -0000 1.2 @@ -1 +1,37 @@ -set ec_url [ec_url] +ad_page_contract { + + The customer service module documentation. The customer service + module is part of the ecommerce package, a package to implement + business-to-consumer web services. + + @author Bart Teeuwisse + @creation-date May 2002 + +} { +} -properties { + title:onevalue + context_bar:onevalue +} + +# Authenticate the user + +set user_id [ad_maybe_redirect_for_registration] + +# Check for read privileges + +set package_id [ad_conn package_id] +set admin_p [ad_permission_p $package_id read] + +set package_name "Ecommerce" +set title "$package_name Documentation: Customer Service Module" +set package_url [apm_package_url_from_key "ecommerce"] + +set shipping_gateway_installed [apm_package_installed_p "shipping-gateway"] + +# Set the context bar. + +set context_bar [ad_context_bar [list "." "$package_name Documentation"] "Customer Service Module"] + +# Set signatory for at the bottom of the page + +set signatory "bart.teeuwisse@7-sisters.com" Index: openacs-4/packages/ecommerce/www/doc/ecommerce-features.adp =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/ecommerce/www/doc/ecommerce-features.adp,v diff -u -r1.1 -r1.2 --- openacs-4/packages/ecommerce/www/doc/ecommerce-features.adp 20 Apr 2001 20:51:14 -0000 1.1 +++ openacs-4/packages/ecommerce/www/doc/ecommerce-features.adp 26 May 2002 04:36:50 -0000 1.2 @@ -1,235 +1,232 @@ - -Features of the Ecommerce Module + -Some of the high-level features of the Ecommerce Module: + + @title@ + @signatory@ -

    +

    @title@

    + + + + + + +
    @context_bar@
    -Products +
    -
      +

      Some of the high-level features of the @package_name@:

      -
    • Products are divided into categories (like books, journals, ...), -subcategories (computer, fiction, ...), and -subsubcategories (operating systems, web publishing, ...) which are set -by the site adminstrator (if desired). Products -can belong to as many categories/subcategories/subsubcategories -as needed. Users can search by category/subcategory/subsubcategory and the site -administrator can make product recommendations by category/subcategory/subsubcategory. +

      Products

      -

      +

        -
      • Via simple forms, the site administrator can upload any desired -information about products either into the Oracle database or into the -file system. -Standard product information such as product name, regular price, etc., -and admin-defined custom fields are collected in the database. Pictures -of the product and other formatted info like sample chapters, for instance, are uploaded into the file system. -

        +

      • Products are divided into categories (like books, journals, + ...), subcategories (computer, fiction, ...), and + subsubcategories (operating systems, web publishing, ...) which + are set by the site adminstrator (if desired). Products can + belong to as many categories / subcategories / subsubcategories + as needed. Users can search by category / subcategory / + subsubcategory and the site administrator can make product + recommendations by category / subcategory / subsubcategory.
      • -
      • Users can input comments and ratings of products. The site administrator -can choose to: a) allow all comments, b) allow comments after administrator approval, or c) disallow all comments. +
      • Via simple forms, the site administrator can upload any + desired information about products either into the database or + into the file system. Standard product information such as + product name, regular price, etc., and admin-defined custom + fields are collected in the database. Pictures of the product + and other formatted info like sample chapters, for instance, are + uploaded into the file system.
      • -

        -

      • The site administrator can input professional reviews of the products. +
      • Users can input comments and ratings of products. The site + administrator can choose to:
      • -

        +

          +
        1. allow all comments,
        2. +
        3. allow comments after administrator approval, or
        4. +
        5. disallow allow comments.
        6. +
        -
      • The site administrator can specify whether the product should be -displayed -when the user does a search. For example, they might not want the product -to display if the product is part of a series or if the product is the hardcover version of a book that also exists in paperback +
      • The site administrator can input professional reviews of the + products.
      • -

        +

      • The site administrator can specify whether the product should + be displayed when the user does a search. For example, they + might not want the product to display if the product is part of + a series or if the product is the hardcover version of a book + that also exists in paperback.
      • -
      • Links between products: the site administrator can specify that one -product always links to other product(s) on the product-display page. +
      • Links between products: the site administrator can specify + that one product always links to other product(s) on the + product-display page.
      • -

        +

      • Products can be listed before they are available for sale. + The site administrator decides whether customers are allowed to + preorder items or if they are not allowed to order until the + date that the products become available.
      • + +
      • A product can have a lower, introductory price. It can also + have a limited-time sale price, and a limited-time special offer + price which is given only to those who have the special offer + code in their URL.
      • -
      • Products can be listed before they are available for sale. The site administrator -decides whether customers are allowed to preorder items or if they are not allowed -to order until the date that the products become available. +
      • The site administrator determines the geographical regions in + which tax should be charged.
      • -

        +

      • Shipping costs are determined by the site administrator as a + base cost + a certain amount per additional item, or the cost + can be based on weight. Additional amounts are charged for + express shipping, if allowed. Alternatively, the shipping costs + can be obtained from an implementation of the Shipping Service Contract.
      • -
      • A product can have a lower, introductory price. It can also have -a limited-time sale price, and a limited-time special offer price which is given only to those who have the special -offer code in their URL. +
      -

      +

      Personalization

      -
    • The site administrator determines the geographical regions in which -tax should be charged. +
        -

        +

      • Users are recognized, if possible, when they enter the site.
      • -
      • Shipping costs are determined by the site administrator as a base cost -+ a certain amount per additional item, or the cost can be -based on weight. Additional amounts are charged for express shipping, if -allowed. +
      • Users can be placed into user classes (student, publisher, + ...) either by themselves (with site administrator approval) or + by the site administrator.
      • -
      +
    • Members of user classes can be given different views of the + site, different prices for each product, and different product + recommendations.
    • -

      +

    • A user's purchasing history as well as browsing history is + stored. Product recommendations can be made based on both + histories.
    • +
    • Frequent buyers can be recognized and rewarded.
    • -Personalization +
    • The site will automatically calculate what other products were + most popular among people who bought a given product.
    • -
        +
      -
    • Users are recognized, if possible, when they enter the site +

      Ordering

      -

      +

        -
      • Users can be placed into user classes (student, publisher, ...) -either by themselves (with site administrator approval) or by the -site administrator. +
      • Shopping cart interface: users select items to put into their + shopping cart and then go to their cart when they want to "check + out". The shopping cart is editable (similar to Amazon.com).
      • -

        +

      • If a user is not ready to order yet, they can store their + order and come back to it later (similar to Dell.com).
      • -
      • Members of user classes can be given different views of the -site, different prices for each product, and different product -recommendations. +
      • User receives an acknowledgment web page and email when their + order is confirmed.
      • -

        +

      • The user can reuse an address for billing or shipping that + they previously entered on the site and, if the site + administrator has chosen to store credit card data, they can + reuse previous credit cards.
      • -
      • A user's purchasing history as well as browsing history is -stored. Product recommendations can be made based on both -histories. +
      • The user's credit card is authorized at the time that they + confirm their order. The card is billed automatically only + after the site administrator marks that the order has been + shipped. With the exception of items that do not require + shipping (so called 'soft goods'). Soft goods are billed + immediately after the card has been authorized for the soft good + total amount.
      • -

        +

      • The site administrator can issue electronic gift certificates + to users.
      • + +
      • The site administrator is able to give refunds to a user if + the user returns all or part of their order.
      • -
      • Frequent buyers can be recognized and rewarded +
      • Customers can view their order history and track their + packages.
      • -

        +

      • Customers can purchase gift certificates for other people. A + random claim check is generated at the time of purchase and + emailed to the recipient. The recipient is then able to use + their gift certificate when they make purchases on the site + (until the certificate expires).
      • -
      • The site will automatically calculate what other products were -most popular among people who bought a given product +
      -
    +

    Community

    -

    +

      -Ordering +
    • Users can sign up for mailing lists based on the product + categories they are interested in.
    • -
        -
      • Shopping cart interface: users select items to put into their shopping cart and then go to their cart when they want to "check out". The shopping cart is editable (similar to Amazon.com) +
      • Most importantly, since the @package_name@ is tied in with the + rest of the Open Architecture Community System, a more complete + picture of the customer (Q & A forum postings, Classified + Ads, etc.) is known than in a stand-alone ecommerce + system.
      • -

        +

      -
    • If a user is not ready to order yet, they can store their order and -come back to it later (similar to Dell.com) +

      Customer Service

      -

      +

        -
      • User receives an acknowledgment web page and email when their order -is confirmed. +
      • A complete customer service submodule which allows customer + service reps to:
      • + +
          +
        • Receive and respond to customer inquiries via email (includes + a spell-checker!).
        • -

          +

        • Record all customer interactions and issues (whether by + phone/fax/email/etc.).
        • -
        • The user can reuse an address for billing or shipping that they -previously entered on the site and, if the site administrator has -chosen to store credit card data, they can reuse previous credit cards. +
        • Categorize issues.
        • -

          +

        • View complete customer interaction and purchase + histories.
        • -
        • The user's credit card is authorized at the time that they confirm -their order. The card is billed automatically only after the site administrator -marks that the order has been shipped. +
        • Send email using the "canned text" system which allows them to + automatically insert commonly-used paragraphs into their + emails.
        • -

          +

        • "Spam" groups of users based on various criteria (date of last + visit, number of purchases, pages they've visited, mailing lists + they've signed up for, etc.)
        • -
        • The site administrator can issue electronic gift certificates to users. +
        • Edit email templates that the system uses when sending + automatic email to users (e.g. "Dear <insert name>, thank + you for your order. We received your order on <insert + date>, etc.").
        • + +
        • View statistics and reports on issues/interactions + (e.g. interactions by customer service rep, issues by issue + type).
        • -

          +

        +
      -
    • The site administrator is able to give refunds to a user if the user returns all or -part of their order. +

      Other

      -

      +

        +
      • Data entered or modified by site administrators is audited, so + you can see:
      • -
      • Customers can view their order history and track their packages. - -

        - -

      • Customers can purchase gift certificates for other people. A random claim check is generated at the time of purchase and emailed to the recipient. The recipient is then able to use their gift certificate when they make purchases on the site (until the certificate expires). - -
      - - -Community - -
        - -
      • Users can sign up for mailing lists based on the product categories they -are interested in. - -

        - -

      • Most importantly, since the Ecommerce Module is tied in with the rest -of the ArsDigita Community System, a more complete picture of the customer (Q & -A forum postings, Classified Ads, etc.) is known than in a stand-alone -ecommerce system - -
      - -Customer Service - -
        - -
      • A complete customer service submodule which allows customer service reps to: - -
          -
        • receive and respond to customer inquiries via email (includes a spell-checker!) -
        • record all customer interactions and issues (whether by phone/fax/email/etc.) -
        • categorize issues -
        • view complete customer interaction and purchase histories -
        • send email using the "canned text" system which allows them to automatically insert commonly-used paragraphs into their emails -
        • "spam" groups of users based on various criteria (date of last visit, number of purchases, pages they've visited, mailing lists they've signed up for, etc.) -
        • edit email templates that the system uses when sending automatic email to users (e.g. "Dear <insert name>, thank you for your order. We received your order on <insert date>, etc.") -
        • view statistics and reports on issues/interactions (e.g. interactions by customer service rep, issues by issue type) -
        - - -
      - -Other - -
        -
      • Data entered or modified by site administrators is audited, -so you can see: -
          -
        • who made the changes -
        • when the changes were made -
        • what changed -
        • the history of all states the data have been in (so your data are never lost) +
        • who made the changes
        • +
        • when the changes were made
        • +
        • what changed
        • +
        • the history of all states the data have been in (so your data are never lost)
        -

        +

      • All of the user display pages are templated. This allows + designers to change the look and feel of the site without + mucking around in Tcl or SQL code.
      • -
      • All of the user display pages are templated, with templates stored -in a separate directory from the rest of the site. This allows -designers to change the look and feel of the site without -mucking around in Tcl or SQL code. +
      • The system logs potential problems it encounters (e.g. failed + credit card transactions) and allows site administrators to view + the problems and mark them "resolved".
      • -

        - -

      • The system logs potential problems it encounters (e.g. failed credit card -transactions) and allows site administrators to view the problems and mark them "resolved". - -
      - -What's Coming in the Next Version - -
        -
      • Support for multiple retailers. (Includes an extranet for approved retailers -to upload price and stock information about products they have for sale.) -

        -

      • Integration with the ACS Graphing Package to show colorful sales reports. -

        -

      • An online Help system. -
      - +
    Index: openacs-4/packages/ecommerce/www/doc/ecommerce-for-mbas.adp =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/ecommerce/www/doc/ecommerce-for-mbas.adp,v diff -u -r1.1 -r1.2 --- openacs-4/packages/ecommerce/www/doc/ecommerce-for-mbas.adp 20 Apr 2001 20:51:14 -0000 1.1 +++ openacs-4/packages/ecommerce/www/doc/ecommerce-for-mbas.adp 26 May 2002 04:36:50 -0000 1.2 @@ -1,147 +1,181 @@ - -Ecommerce Module (explained for MBAs) + -The big decision: + + @title@ + @signatory@ -
      +

      @title@

      + + + + + + +
      @context_bar@
      +
      -
    1. you are the retailer +

      The big decision:

      -
    2. you send all orders to one retailer +
        +
      1. you are the retailer
      2. +
      3. you send all orders to one retailer
      4. +
      5. you offer products and send orders to multiple retailers
      6. +
      7. you let an arbitrary number of retailers come to your site and + build shops (Yahoo! Store; Amazon Z Shops)
      8. +
      -
    3. you offer products and send orders to multiple retailers +

      OpenaACS supports the first three ways of doing business and will + eventually support the last one (clone of Yahoo! Store).

      -
    4. you let an arbitrary number of retailers come to your site and build -shops (Yahoo! Store; Amazon Z Shops) +

      High-level features

      -
    +

    If your imagination is limited, you can think of this as + "Amazon.com in a box". Is is it impressive to do everything that + Amazon does? Not really. Ecommerce is a fast-moving field. + Packaged software always embodies last year's business ideas. The + interesting thing is how quickly one can extend an open-source + software system to accomodate the latest business ideas.

    -ACS supports the first three ways of doing business and will eventually -support the last one (clone of Yahoo! Store). +

    Feature List

    +
    + + + + + + + + + + + + -

    High-level features

    + -If your imagination is limited, you can think of this as "Amazon.com in -a box". Is is it impressive to do everything that Amazon does? Not -really. Ecommerce is a fast-moving field. Packaged software always -embodies last year's business ideas. The interesting thing is how -quickly one can extend an open-source software system to accomodate the -latest business ideas. + + + -

    Feature List

    + -
    -
    in MBA-speaktranslation for programmers
    catalog engineDatabase table (ec_products) + plus extra tables for mapping to categories, + subcategories, and subsubcategories; bulk upload from + structured data
    e-recommendation engineDatbase table + (ec_product_recommendations) mapping products + to categories, subcategories, for everyone or only a + particular class of user
    e-review technologyDatabase tables for professional reviews + and customer-contributed reviews
    - - - - - - - - + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + -
    in MBA-speak -translation for programmers -
    catalog engine -Oracle table (ec_products) plus -extra tables for mapping to categories, subcategories, and -subsubcategories; bulk upload from structured data -
    e-recommendation engine -Oracle table (ec_product_recommendations) - mapping products to categories, subcategories, for everyone or only a -particular class of user -
    e-review technology -Oracle tables for professional reviews and customer-contributed -reviews -
    shopping cart
    shopping cart -Oracle tables (ec_user_sessions, ec_orders, ec_items) -
    real-time credit card billing -CyberCash and CyberSource interfaces -
    user tracking -log every page view and search -
    integrated customer service (telephone, fax, email, and Web) -all interactions logged into same Oracle table; inbound -ACS 3.4.8 email handler (Perl script); call -center staff sit at Web browsers and use the <%= [ec_url] %>admin/ pages -
    CRM -write custom rules for standard ACS 3.4.8 CRM module (to be ported...) -
    intelligent agent -Oracle query for "users who bought X also bought Y" -
    content management with visual interface -Web forms plus auditing of all changes -
    discounts for different classes of user -Example: MIT Press wants to sell journals -at different rates for individual, institutional, and student subscriptions -
    cross-sales platform -Oracle table of "if you're interested in X, you probably -also should buy Y"; links are unidirectional -
    object-oriented design -per-publisher custom fields table to add arbitrary -attributes to products -
    intelligent parametric and free-text search engine -pseudo_contains if you want to have an easy -Oracle dbadmin life; Contains (Intermedia text) if you -don't; -limit to category at user's option -
    gift certificates -auditing and mandatory expiration -
    enterprise-scale e-business solution -add more processors to your Oracle server -
    highly scalable transaction engine -orders are inserted into Oracle table -
    XML-enabled -download free Java XML libraries from Oracle -
    Database tables (ec_user_sessions, + ec_orders, ec_items)
    -
    + + + real-time credit card billing + Payment gateway interfaces + + + user tracking + Log every page view and search + + + integrated customer service (telephone, + fax, email, and Web) -

    Bottom line

    + All interactions logged into same Database + table; inbound ACS 3.4.8 + email handler (Perl script); call center staff sit at + Web browsers and use the @package_name@ admin pages -If a closed-source ecommerce package doesn't do exactly what you want, -you're out of business. If the company behind a closed-source ecommerce -package goes out of business, so will you. If the company behind a -closed-source ecommerce adopts a different "business model", you're -screwed. + + + CRM -

    + Write custom rules for standard ACS 3.4.8 + CRM module (to be ported...) -If you're even tempted to adopt a commercial ecommerce system from a -company other than IBM, Oracle or SAP (three enterprise software vendors -that seem likely to be around for awhile), read the iCat story towards -the end of http://photo.net/wtr/using-the-acs + + + intelligent agent + Database query for "users who bought X also bought Y" + + + content management with visual interface + Web forms plus auditing of all changes + + + discounts for different classes of user + Example: MIT Press wants to sell journals + at different rates for individual, institutional, and + student subscriptions + + + cross-sales platform + + Database table of "if you're interested in + X, you probably also should buy Y"; links are + unidirectional + + + + object-oriented design + + Per-publisher custom fields table to add + arbitrary attributes to products + + + + intelligent parametric and free-text search engine + + pseudo_contains if you want to + have an easy Database dbadmin life; Contains + (Intermedia text) if you don't; limit to category at + user's option + + + + gift certificates + Auditing and mandatory expiration + + + enterprise-scale e-business solution + Add more processors to your Database server + + + highly scalable transaction engine + Orders are inserted into a database table + + + XML-enabled + Use the nsxml module for AOLServer + + + + + +

    Bottom line

    + +

    If a closed-source ecommerce package doesn't do exactly what you + want, you're out of business. If the company behind a closed-source + ecommerce package goes out of business, so will you. If the company + behind a closed-source ecommerce adopts a different "business + model", you're screwed.

    + +

    If you're even tempted to adopt a commercial ecommerce system + from a company other than IBM, Oracle or SAP (three enterprise + software vendors that seem likely to be around for awhile), read the + iCat story towards the end of Using the + ArsDigita Community System + + Index: openacs-4/packages/ecommerce/www/doc/ecommerce-operation.adp =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/ecommerce/www/doc/ecommerce-operation.adp,v diff -u -r1.1 -r1.2 --- openacs-4/packages/ecommerce/www/doc/ecommerce-operation.adp 20 Apr 2001 20:51:14 -0000 1.1 +++ openacs-4/packages/ecommerce/www/doc/ecommerce-operation.adp 26 May 2002 04:36:50 -0000 1.2 @@ -1,75 +1,92 @@ - -Operation of the Ecommerce Module + -Before reading this, make sure that you have read about setting up your ecommerce module. This document takes up where that one leaves off and covers all the components of operating your on-line shop with the exception of -customer service, which is a submodule -in itself. -

    -

    Orders

    -These are the states that an order can go through: -
    -
    +
    +  Operation of the Ecommerce Module
    +  @signatory@
    +
    +  

    @title@

    + + + + + + +
    @context_bar@
    +
    + +

    Before reading this, make sure that you have read about setting up your ecommerce module. This + document takes up where that one leaves off and covers all the + components of operating your on-line shop with the exception of customer service, which is a + module in itself.

    + +

    Orders

    + +

    These are the states that an order can go through:

    + +
    +
        +-------- IN_BASKET <----------------+ (if authorization fails --
        |            |                       | it might also temporarily go
        |            |                       | into FAILED_AUTHORIZATION
     EXPIRED      CONFIRMED------------------+ before returning to IN_BASKET)
                     |
    -          +-----+------------+
    -          |                  |    
    - AUTHORIZED_MINUS_AVS   AUTHORIZED_PLUS_AVS
    -          |                  |
    -          +----+--------+----+
    -               |        |
    -PARTIALLY_FULFILLED--->FULFILLED
    -                          |
    -                       RETURNED
    +                |
    +            AUTHORIZED
    +                |
    +                |
    +                +-----------------+
    +                |                 |
    +                |                 |
    +       PARTIALLY_FULFILLED--->FULFILLED
    +                                  |
    +                                  |
    +                               RETURNED
    +    
    +
    -
    -
    -An order can also be put into the VOID state at any time by the site -administrator. (Note: these states are actually stored in all lowercase -in the database, but it's clearer to use uppercase letters in the -documentation.) -

    -An order is IN_BASKET when the customer has put items into their shopping -cart on the site but has not indicated an intent to buy (if they stay -there too long they go into the EXPIRED state; "too long" is defined in -the parameters/yourservername.ini file; default is 30 days). When the customer -submits their order, the state becomes CONFIRMED. Only then do we try -to authorize their credit card. If the authorization succeeds, the order -state will be updated to AUTHORIZED_PLUS_AVS or AUTHORIZED_MINUS_AVS. -AVS stands for Address Verification System (for more information on AVS, -read the ecommerce -chapter of Philip & Alex's Guide to Web Publishing. Because AVS -is flaky and unreliable, we treat AUTHORIZED_PLUS_AVS orders the same as -AUTHORIZED_MINUS_AVS orders. If an order fails, it goes back into the -IN_BASKET state and the customer is given another chance to enter their -credit card information. -

    -Problems occur if we don't hear back from CyberCash or if they give us -a result that is inconclusive. In cases like this, the order state -remains in the CONFIRMED state. A scheduled procedure sweeps the -database every once in a while looking for CONFIRMED orders that are -over 15 minutes old and tries to authorize them. If the authorization -succeeds, the order is put into the AUTHORIZED_PLUS_AVS or -AUTHORIZED_MINUS_AVS state. If it fails, it is temporarily put into -the FAILED_AUTHORIZATION state so that it can be taken care of by -a scheduled procedure which sends out email to the customer saying -that we couldn't authorize their order and then saves the order for -them (a saved order is one in the IN_BASKET state with saved_p='t'; it -can be retrieved easily by the customer later). -

    -Once an order is authorized they are ready to be shipped. An order -which has some of its items shipped is PARTIALLY_FULFILLED and orders -for which a full shipment is made are FULFILLED. It remains in the -fulfilled state unless all of the items in the order are returned, -at which time it becomes financially uninteresting and goes into the -RETURNED state. -

    -Individual items in an order also go through a series of states: +

    An order can also be put into the VOID state at any time by the + site administrator. (Note: these states are actually stored in + all lowercase in the database, but it's clearer to use uppercase + letters in the documentation.)

    + +

    An order is IN_BASKET when the customer has put items into their + shopping cart on the site but has not indicated an intent to buy + (if they stay there too long they go into the EXPIRED state; "too + long" is defined in the parameters/yourservername.ini file; + default is 30 days). When the customer submits their order, the + state becomes CONFIRMED. Only then do we try to authorize their + credit card. If the authorization succeeds, the order state will + be updated to AUTHORIZED. If an order fails, it goes back into the + IN_BASKET state and the customer is given another chance to enter + their credit card information.

    -
    -
    +  

    Problems occur if we don't hear back from the payment gateway or + if they give us a result that is inconclusive. In cases like + this, the order state remains in the CONFIRMED state. A scheduled + procedure sweeps the database every once in a while looking for + CONFIRMED orders that are over 15 minutes old and tries to + authorize them. If the authorization succeeds, the order is put + into the AUTHORIZED state. If it fails, it is temporarily put + into the FAILED_AUTHORIZATION state so that it can be taken care + of by a scheduled procedure which sends out email to the customer + saying that we couldn't authorize their order and then saves the + order for them (a saved order is one in the IN_BASKET state with + saved_p='t'; it can be retrieved easily by the customer + later).

    + +

    Once an order is authorized they are ready to be shipped. An + order which has some of its items shipped is PARTIALLY_FULFILLED + and orders for which a full shipment is made are FULFILLED. It + remains in the fulfilled state unless all of the items in + the order are returned, at which time it becomes financially + uninteresting and goes into the RETURNED state.

    + +

    Individual items in an order also go through a series of states:

    + +
    +
     IN_BASKET -----------+
        |                 |
     TO_BE_SHIPPED     EXPIRED
    @@ -79,106 +96,121 @@
     ARRIVED
        |
     RECEIVED_BACK
    -
    -
    +
    +
    -An item starts out in the IN_BASKET state. When the order it's in becomes authorized, the item becomes TO_BE_SHIPPED. Because partial shipments can be made on orders, SHIPPED is a state of the individual items, not of the order. There is currently no mechanism for -putting an item into the ARRIVED state but it could be used if you were to set up a -method of data exchange with FedEx's database to get the actual arrival date and arrival -detail for each of the packages you ship. If the customer returns an item to you, it is -put into the RECEIVED_BACK state. Like orders, individual items can also be put into the VOID state (e.g. if the customer changes their mind or if you run out of stock before you can ship it). +

    An item starts out in the IN_BASKET state. When the order it's + in becomes authorized, the item becomes TO_BE_SHIPPED. Because + partial shipments can be made on orders, SHIPPED is a state of + the individual items, not of the order. There is currently no + mechanism for putting an item into the ARRIVED state but it + could be used if you were to set up a method of data exchange + with FedEx's database to get the actual arrival date and arrival + detail for each of the packages you ship. If the customer + returns an item to you, it is put into the RECEIVED_BACK state. + Like orders, individual items can also be put into the VOID + state (e.g. if the customer changes their mind or if you run out + of stock before you can ship it).

    -

    +

    OK, so what can you actually do with orders? You can:

    -OK, so what can you actually do with orders? You can: - -On an individual order, you can: -
      -
    • add comments to it -
    • record a shipment -
    • process a refund -
    • add items (only if it hasn't shipped yet and if it was paid for using a credit card instead of using a gift certificate) -
    • change the shipping address -
    • change the credit card information -
    • void it -
    + + +

    On an individual order, you can:

    -

    Gift Certificates

    +
      +
    • add comments to it
    • +
    • record a shipment
    • +
    • process a refund
    • +
    • add items (only if it hasn't shipped yet and if it was paid + for using a credit card instead of using a gift + certificate)
    • +
    • change the shipping address
    • +
    • change the credit card information
    • +
    • void it
    • +
    -As you know from setting up your ecommerce module, -you can configure whether to allow customers to purchase gift certificates for others. -These are the states that a purchased gift certificate goes through: +

    Gift Certificates

    -
    -                        CONFIRMED
    -                            |
    -        +-------------------+---------------------+
    -        |                   |                     |
    -AUTHORIZED_PLUS_AVS   AUTHORIZED_MINUS_AVS   FAILED_AUTHORIZATION
    -
    +

    As you know from setting up your + ecommerce module, you can configure whether to allow customers + to purchase gift certificates for others. These are the states + that a purchased gift certificate goes through:

    -Regardless of whether you allow customers to purchase gift certificates, you -can always issue gift certificates to your customers. Gift certificates -that you issue automatically go into the AUTHORIZED state. +
    +
    +           CONFIRMED
    +               |
    +        +------+------+
    +        |             |
    +AUTHORIZED   FAILED_AUTHORIZATION
    +    
    +
    -

    +

    Regardless of whether you allow customers to purchase gift + certificates, you can always issue gift certificates to your + customers. Gift certificates that you issue automatically go into + the AUTHORIZED state.

    -There are a few fundamental ways in which purchased gift certificates -differ from assigned gift certificates. Purchased gift certificates are -sent to some recipient who may or may not be a registered user of the -system, along with a claim check. These gift certificates must be claimed -upon order checkout in order to be used. Issued gift certificates, on the -other hand, are given to registered users of the system and are put -directly into their gift certificate balance. There is no need for them -to be claimed because there is no ambiguity about who the gift certificates -belong to. +

    There are a few fundamental ways in which purchased gift + certificates differ from assigned gift certificates. Purchased + gift certificates are sent to some recipient who may or may not be + a registered user of the system, along with a claim check. These + gift certificates must be claimed upon order checkout in order to + be used. Issued gift certificates, on the other hand, are given + to registered users of the system and are put directly into their + gift certificate balance. There is no need for them to be claimed + because there is no ambiguity about who the gift certificates + belong to.

    -

    +

    All gift certificates have an expiration date (this is necessary + so that your liability has a definite ending point). A customer's + gift certificate balance is equal to the sum of all the unused + portions of each non-expired gift certificate they own. When + their gift certificate balance is applied toward a new order, the + gift certificates that expire soonest are the first to be + applied.

    -All gift certificates have an expiration date (this is necessary so that your -liability has a definite ending point). A customer's gift certificate -balance is equal to the sum of all the unused portions of each non-expired -gift certificate they own. When their gift certificate balance is applied -toward a new order, the gift certificates that expire soonest are the first -to be applied. +

    Things you can do with gift certificates:

    -

    -Things you can do with gift certificates: -

    -

    -

    Site Upkeep

    + -Besides the most important task of filling orders, there are some other things -that need to be done once in a while. -

    +

    Site Upkeep

    -Naturally, you'll want to rotate your product recommendations every so often to keep your site looking fresh, even -if your product database doesn't change. You will also need to periodically -approve/disapprove customer reviews -(if you've set reviews to require approval) and perhaps view -some reports to make sure everything is -going as you expected. +

    Besides the most important task of filling orders, there are some + other things that need to be done once in a while.

    -

    Dealing with Problems

    +

    Naturally, you'll want to rotate your product + recommendations every so often to keep your site looking + fresh, even if your product database doesn't change. You will + also need to periodically approve/disapprove + customer reviews (if you've set reviews to require approval) + and perhaps view some reports + to make sure everything is going as you expected.

    -A log of potential problems is maintained -by the system when it comes across issues that it is unable to resolve. These -problems (hopefully infrequent) will need to be resolved by hand. +

    Dealing with Problems

    -

    -Continue on to the Customer Service Submodule. +

    A log of potential problems + is maintained by the system when it comes across issues that it is + unable to resolve. These problems (hopefully infrequent) will + need to be resolved by hand.

    +

    Continue on to the Customer + Service Module.

    Index: openacs-4/packages/ecommerce/www/doc/ecommerce-operation.tcl =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/ecommerce/www/doc/ecommerce-operation.tcl,v diff -u -r1.1 -r1.2 --- openacs-4/packages/ecommerce/www/doc/ecommerce-operation.tcl 20 Apr 2001 20:51:14 -0000 1.1 +++ openacs-4/packages/ecommerce/www/doc/ecommerce-operation.tcl 26 May 2002 04:36:50 -0000 1.2 @@ -1 +1,34 @@ -set ec_url [ec_url] +ad_page_contract { + + The operation guide to the ecommerce package, a package to implement + business-to-consumer web services. + + @author Bart Teeuwisse + @creation-date May 2002 + +} { +} -properties { + title:onevalue + context_bar:onevalue +} + +# Authenticate the user + +set user_id [ad_maybe_redirect_for_registration] + +# Check for read privileges + +set package_id [ad_conn package_id] +set admin_p [ad_permission_p $package_id read] + +set package_name "Ecommerce" +set title "$package_name Documentation: Operation" +set package_url [apm_package_url_from_key "ecommerce"] + +# Set the context bar. + +set context_bar [ad_context_bar [list "." "$package_name Documentation"] "Operation"] + +# Set signatory for at the bottom of the page + +set signatory "bart.teeuwisse@7-sisters.com" Index: openacs-4/packages/ecommerce/www/doc/ecommerce-setup.adp =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/ecommerce/www/doc/ecommerce-setup.adp,v diff -u -r1.1 -r1.2 --- openacs-4/packages/ecommerce/www/doc/ecommerce-setup.adp 20 Apr 2001 20:51:14 -0000 1.1 +++ openacs-4/packages/ecommerce/www/doc/ecommerce-setup.adp 26 May 2002 04:36:50 -0000 1.2 @@ -1,297 +1,348 @@ - -Setup of the Ecommerce Module + - + + Setup of the Ecommerce Module + @signatory@ -This is intended to be a guide for the content administrators of the site. -Content administrators are not assumed to have any technical expertise -(although HTML knowledge is necessary if you want to edit product templates). -

    -These are the basic steps needed to get your ecommerce system up and running. -Most functions below can be performed using the -ecommerce administration pages in -@ec_url@admin/ (must be accessed using HTTPS). +

    @title@

    + + + + + + +
    @context_bar@
    +
    -
      -
    1. First make sure that the technical setup -has been taken care of. Although most of it can be done quickly, the -process of setting up a merchant account to accept credit cards can take weeks, -so don't procrastinate! -

      -You will need to answer the following questions for whomever will be -administring the ecommerce site parameters, and for those individuals adding products or services to your site. -

      -If you don't know what some of these -questions mean, read on. These should make sense after you've finished -reading this page. -

      -

        +

        This is intended to be a guide for the content administrators of + @package_name@. Content administrators are not assumed to have any + technical expertise (although HTML knowledge is necessary if you + want to edit product templates).

        -
      1. what units of currency and weight (e.g. USD and lbs) will be used -throughout the site +

        These are the basic steps needed to get @package_name@ up and + running. Most functions below can be performed using the + @package_name@ administration pages in @package_url@admin/ (must be + accessed using HTTPS).

        -
      2. whether you are selling products or services (items that are not -shipped) +
          +
        1. + +

          First make sure that the technical setup has been taken + care of. Although most of it can be done quickly, the process + of setting up a merchant account to accept credit cards can + take weeks, so don't procrastinate!

          -
        2. how many products to display per page when the customer is -browsing (default 10) +

          You will need to answer the following questions for whomever + will be administring @package_name@ site parameters, and for + those individuals adding products or services to your + site.

          -
        3. whether to allow users to write public comments of the products -and, if so, whether the comments need to be approved (by you) before -they appear on the site +

          If you don't know what some of these questions mean, read on. + These should make sense after you've finished reading this + page.

          -
        4. whether you want product relationships (e.g. "people who bought -product A also bought products B, C, and D") to be calculated and -displayed +
            +
          1. What units of currency and weight (e.g. USD and lbs) will be used + throughout the site.

          2. -
          3. regarding user classes (i.e., classes that you might place users -in like "publisher" or "student" for purposes of giving discounts or -different views of the site): (a) do you want them to know what -classes they're in? (b) can they request via the web site to be placed -into user classes, and (c) if so, do they automatically become a -member of any user class they request to be a part of, or do their -requests need to be approved by an administrator first? +
          4. Whether you are selling hard goods that require + shipping and/or soft goods and services that are not being + shipped.

          5. -
          6. what percentage of the shipping charges should be refunded if a -customer returns their purchases +
          7. How many products to display per page when the customer is + browsing (default 10).

          8. -
          9. whether express shipping is available +
          10. Whether to allow users to write public comments of the products + and, if so, whether the comments need to be approved (by you) before + they appear on the site.

          11. -
          12. whether you want to save credit card data (if so, customers can -reuse their credit card with one click; if not, the credit card number -is deleted after the order has shipped) +
          13. Whether you want product relationships (e.g. "people who bought + product A also bought products B, C, and D") to be calculated and + displayed

          14. -
          15. how large you want the automatically-generated thumbnail images of -the products to be (you can specify either the width or the height, in -pixels; the dimension you don't specify will vary based on the -original image's size) +
          16. Regarding user classes (i.e., classes that you might place users + in like "publisher" or "student" for purposes of giving discounts or + different views of the site):

            + +
              +
            1. Do you want them to know what classes they're + in?

            2. -
            3. what product stock messages you want to be able to choose from -when adding/editing products (e.g. "Out of Stock", "Usually Ships -Within 24 Hours", "Usually Ships Within 2-3 Days", etc.) +
            4. Can they request via the web site to be placed into + user classes, and

            5. -
            6. the number of days a user's shopping cart will stay valid before -it goes into the 'expired' state +
            7. if so, do they automatically become a member of + any user class they request to be a part of, or do their + requests need to be approved by an administrator + first?

            8. +
            +
          17. -
          18. whether to allow preorders for items that are not yet available +
          19. What percentage of the shipping charges should be refunded if a + customer returns their purchases.

          20. -
          21. the email address that will be used for all email sent from the -system to the customers +
          22. +

            Whether express shipping, and pickups at your location are available.

            +
          23. -
          24. whether people fulfilling the orders should be alerted if there's -a problem reauthorizing a credit card for payment (which happens when -orders are shipped) -- you'll want them to be alerted if they're in a -position to do anything about the problem (e.g. abort the shipment); -otherwise, there's no need to alert them because the problem will -still be logged so that someone else can take care of it +
          25. Whether you want to save credit card data (if so, customers can + reuse their credit card with one click; if not, the credit card number + is deleted after the order has shipped).

          26. -
          27. whether customers are allowed to purchase gift certificates for -others and, if so, the minimum and maximum amounts of money that the -gift certificates can be worth as well as the number of months until -the gift certificates expire +
          28. How large you want the automatically-generated thumbnail images of + the products to be (you can specify either the width or the height, in + pixels; the dimension you don't specify will vary based on the + original image's size).

          29. -
          +
        5. What product stock messages you want to be able to choose from + when adding/editing products (e.g. "Out of Stock", "Usually Ships + Within 24 Hours", "Usually Ships Within 2-3 Days", etc.).

        6. -

        7. Set up product categorization (@ec_url@admin/cat/): +
        8. The number of days a user's shopping cart will stay valid before + it goes into the 'expired' state.

        9. -

          +

        10. Whether to allow preorders for items that are not yet + available.

        11. -Product categories, subcategories and subsubcategories are optional, -but if you intend to offer many products for sale, it is best to think -about how they should be categorized before you enter any products into -the database. The categorization is used when displaying the products and when the -customer is searching for products. +
        12. The email address that will be used for all email sent from the + system to the customers.

        13. -

          +

        14. Whether people fulfilling the orders should be alerted if there's + a problem reauthorizing a credit card for payment (which happens when + orders are shipped) -- you'll want them to be alerted if they're in a + position to do anything about the problem (e.g. abort the shipment); + otherwise, there's no need to alert them because the problem will + still be logged so that someone else can take care of it.

        15. -Here is an example to help you decide how you want to categorize your -products. Say you are a publisher and you are selling a variety of -books and periodicals. You may wish to divide your goods into -two categories: books and periodicals. The subcategories of books -will be: fiction, biography, history, science, and so on. The -subcategories of periodicals will be: health & fitness, sports, -news, beauty, and so on. If you want to go a level deeper, you -can subdivide science, for instance, into physics, chemistry, biology, -geology, and so on. +
        16. Whether customers are allowed to purchase gift certificates for + others and, if so, the minimum and maximum amounts of money that the + gift certificates can be worth as well as the number of months until + the gift certificates expire.

        17. -

          +

        -Another example: say you sell CDs and nothing else. Then your -categories can be: classical, rock, jazz, international, etc. -You will probably not need to use subcategories. +
      3. -

        +

        Set up product categorization (@package_url@admin/cat/):

        -What if one of your products spans two categories? That's OK; you are allowed -to put a product into as many categories (and subcategories and subsubcategories) -as you like. So, if you're -selling the Girl From Ipanema CD, you can put it into both -the jazz and the international categories so that your customers -can find it in both places. +

        Product categories, subcategories and subsubcategories are + optional, but if you intend to offer many products for sale, + it is best to think about how they should be categorized + before you enter any products into the database. The + categorization is used when displaying the products and when + the customer is searching for products.

        -

        +

        Here is an example to help you decide how you want to + categorize your products. Say you are a publisher and you are + selling a variety of books and periodicals. You may wish to + divide your goods into two categories: books and periodicals. + The subcategories of books will be: fiction, biography, + history, science, and so on. The subcategories of periodicals + will be: health & fitness, sports, news, beauty, and so + on. If you want to go a level deeper, you can subdivide + science, for instance, into physics, chemistry, biology, + geology, and so on.

        -
      4. Set up your shipping cost rules (@ec_url@admin/shipping-costs/). -The ecommerce module is flexible regarding how you charge your -customers for shipping. The Shipping Costs page in the admin section -will lead you through it. Make sure you read the Shipping Cost Examples -page if you don't already know how you want to set it up. +

        Another example: say you sell CDs and nothing else. Then + your categories can be: classical, rock, jazz, international, + etc. You will probably not need to use subcategories.

        -

        +

        What if one of your products spans two categories? That's + OK; you are allowed to put a product into as many categories + (and subcategories and subsubcategories) as you like. So, if + you're selling the Girl From Ipanema CD, you can put it + into both the jazz and the international categories so that + your customers can find it in both places.

        +
      5. -
      6. Set up your sales tax rules (@ec_url@admin/sales-tax/). If your -company is located only in one or a few states, this will be easy. On -the other hand, if you're a Fortune 500 company and you have nexus -(i.e. have an office or factory or store) in many states, you might -want to buy tax tables from www.salestax.com. A fair bit of -programming would be needed to integrate this data with your ecommerce -system. Also if you're not based in the USA, you may need to have -some programming done to handle the tax for the regions in your -country. +
      7. -

        +

        Set up your shipping cost rules (@package_url@admin/shipping-costs/). + @package_name@ is flexible regarding how you charge your + customers for shipping. The Shipping Costs + page in the admin section will lead you through it. Make + sure you read the Shipping + Cost Examples page if you don't already know how you want + to set it up.

        +

        Check out the Shipping Service + Contract if the + default @package_name@ shipping cost rules don't allow you to + specify the rules you want. With the Shipping Service Contract + installed you can select an implementation of the contract + that fills your needs and it will supersede the @package_name@ + shipping rules. (Including the express shipping and pickup at + location options.)

        -
      8. Decide if you want to add any custom product fields. First look -at the current fields available (@ec_url@admin/products/add) to see if -they meet your needs. The current fields are probably sufficient for -many types of products. However, a bookseller may wish to add a -custom field to store the ISBN, or someone who sells clothing from -many manufacturers may wish to add a manufacturers field. Custom -fields are added at @ec_url@admin/products/custom-fields. +
      9. -

        +

      10. -
      11. Create new product display templates -(@ec_url@admin/templates/) -(unless you're happy with the somewhat minimalist default template). The -reason for having product display templates is that you might want to present -different types of products in different ways (e.g., spring dresses get a -yellow background page color; winter coats get a blue background page color). +

        Set up your sales tax rules (@package_url@admin/sales-tax/). If your company is + located only in one or a few states, this will be easy. On + the other hand, if you're a Fortune 500 company and you have + nexus (i.e. have an office or factory or store) in many + states, you might want to buy tax tables from www.salestax.com. A fair + bit of programming would be needed to integrate this data with + @package_name@. Also if you're not based in the USA, you may + need to have some programming done to handle the tax for the + regions in your country.

        -

        +

      12. -You can modify the default template that the ecommerce module comes with -to incorporate your custom product fields, to exclude fields you -don't use, or just change -the way it looks to fit whatever design scheme you want to use. The -template is written in AOLserver's ADP language, which is just HTML -with Tcl variables (or commands) inside <% and %> tags. It is -extremely easy. It you can write HTML, you can write ADP. If you can't, -you can hire someone cheaply to do it for you. +
      13. -

        +

        Decide if you want to add any custom product fields. First + look at the current fields available (@package_url@admin/products/add) to see if they meet your + needs. The current fields are probably sufficient for many + types of products. However, a bookseller may wish to add a + custom field to store the ISBN, or someone who sells clothing + from many manufacturers may wish to add a manufacturers field. + Custom fields are added at @package_url@admin/products/custom-fields.

        -You can create as many additional templates as you like. -You can associate templates with product categories so that every -product in the "book" category is automatically assigned the -"book" template by default, although you can always assign any -template you want to any product you want (so if you have an -unusual product, you can give it an unusual template). +
      14. -

        +

      15. -
      16. Set up user classes (@ec_url@admin/user-classes/). User -classes are groupings of the users, such as "student", "retired", -"institution", "publisher", etc. They may get special prices, -different views of the site, or different product recommendations. +

        Create new product display templates (@package_url@admin/templates/) + (unless you're happy with the somewhat minimalist default + template). The reason for having product display templates is + that you might want to present different types of products in + different ways (e.g., spring dresses get a yellow background + page color; winter coats get a blue background page color).

        -

        +

        You can modify the default template that @package_name@ comes + with to incorporate your custom product fields, to exclude + fields you don't use, or just change the way it looks to fit + whatever design scheme you want to use. The template is + written in AOLserver's ADP language, which is just HTML with + Tcl variables (or commands) inside <% and %> tags. It + is extremely easy. It you can write HTML, you can write ADP. + If you can't, you can hire someone cheaply to do it for + you.

        -Depending on your settings in the ini file, users may or may not be -able to see which user classes they're a member of (so be careful -of what you call them!). +

        You can create as many additional templates as you like. + You can associate templates with product categories so that + every product in the "book" category is automatically assigned + the "book" template by default, although you can always assign + any template you want to any product you want (so if you have + an unusual product, you can give it an unusual template).

        -

        +

      17. -If a user is a member of more than one class and there are special -prices on the same product for both classes, the user will receive -whichever price is lowest. +
      18. -

        +

        Set up user classes (@package_url@admin/user-classes/). User classes are + groupings of the users, such as "student", "retired", + "institution", "publisher", etc. They may get special prices, + different views of the site, or different product + recommendations.

        -
      19. Enter your products into the database. This can be done using the -simple form at @ec_url@admin/products/add. +

        Depending on your settings in the ini file, users may or may + not be able to see which user classes they're a member of (so + be careful of what you call them!).

        -

        +

        If a user is a member of more than one class and there are + special prices on the same product for both classes, the user + will receive whichever price is lowest.

        -However, if you have many products already stored in another database, -you will not want to enter them one by one. Instead, export them into -a CSV file (or a series of CSV files), and manipulate them into the -formats documented at @ec_url@admin/products/upload-utilities so that they can be uploaded in -bulk. +
      20. -

        +

      21. -
      22. After you've added a product, there are a variety of things you can -do to it, such as: -
          -
        • Add any number of professional reviews. -
        • Add "cross-selling links" so that the customer always sees a link - to another given product when they're viewing this product, or vice versa. -
        • Put the product on sale or create "special offers". -
        +

        Enter your products into the database. This can be done + using the simple form at @package_url@admin/products/add.

        -

        +

        However, if you have many products already stored in another + database, you will not want to enter them one by one. + Instead, export them into a CSV file (or a series of CSV + files), and manipulate them into the formats documented at @package_url@admin/products/upload-utilities so that they + can be uploaded in bulk.

        -
      23. Add product recommendations (<%= [ec_url] -%>admin/products/recommendations). If you have many products -subdivided into a number of categories/subcategories/subsubcategories, -it's good to include product recommendations in order to make the site -more browsable and interesting. +
      24. -

        +

      25. +

        After you've added a product, there are a variety of things + you can do to it, such as:

        +
          +
        • Add any number of professional reviews.
        • -Recommendations are displayed when the customer is browsing the site, either on the -home page (if a product is recommended at the top level), or when the -customer is browsing categories, subcategories, or subsubcategories. +
        • Add "cross-selling links" so that the customer always sees + a link to another given product when they're viewing this + product, or vice versa.
        • -

          +

        • Put the product on sale or create "special offers".
        • +
        +
      26. -You can also associate product recommendations with a user class. E.g., -you might only want the book "Improving your GRE Scores" to only be recommended -to Students. +
      27. -

        +

        Add product recommendations (@package_url@dmin/products/recommendations). + If you have many products subdivided into a number of + categories/subcategories/subsubcategories, it's good to + include product recommendations in order to make the site more + browsable and interesting.

        -
      28. Modify the email templates (@ec_url@admin/email-templates/), -which are used when the system sends out automatic email to customers. -There are seven predefined email templates for email sent out when a -customer's order is authorized, when a customer's order ships, when a -customer receives a gift certificate, etc. +

        Recommendations are displayed when the customer is browsing + the site, either on the home page (if a product is recommended + at the top level), or when the customer is browsing + categories, subcategories, or subsubcategories.

        -

        +

        You can also associate product recommendations with a user + class. E.g., you might only want the book "Improving your GRE + Scores" to only be recommended to Students.

        -The current templates are functional but should probably be edited to reflect -your company better. +
      29. -

        +

      30. -
      31. The layout for all the pages in your site is created using ADP templates -which are stored in the directory packages/ecommerce/www/templates/ -(with the exception of product which, as discussed above, uses a different -ADP templating system to allow for different templates for different products). -If you are unhappy with the look of any of the pages in your site, there's -a good chance that it can be changed simply by editing the corresponding ADP -template. +

        Modify the email templates (@package_url@admin/email-templates/), + which are used when the system sends out automatic email to + customers. There are seven predefined email templates for + email sent out when a customer's order is authorized, when a + customer's order ships, when a customer receives a gift + certificate, etc.

        -
      +

      The current templates are functional but should probably be + edited to reflect your company better.

      -

      +

    2. -That's it for setup! Of course, your customers won't be very happy -until you can do things like order fulfillment, so it's time to read about -operation of your ecommerce site. +
    3. The layout for all the pages in your site is created using ADP templates + which are stored in the directory packages/ecommerce/www/templates/ + (with the exception of product which, as discussed above, uses a different + ADP templating system to allow for different templates for different products). + If you are unhappy with the look of any of the pages in your site, there's + a good chance that it can be changed simply by editing the corresponding ADP + template.
    4. +
    +

    That's it for setup! Of course, your customers won't be very + happy until you can do things like order fulfillment, so it's time + to read about operation of + @package_name@.

    Index: openacs-4/packages/ecommerce/www/doc/ecommerce-setup.tcl =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/ecommerce/www/doc/ecommerce-setup.tcl,v diff -u -r1.1 -r1.2 --- openacs-4/packages/ecommerce/www/doc/ecommerce-setup.tcl 20 Apr 2001 20:51:14 -0000 1.1 +++ openacs-4/packages/ecommerce/www/doc/ecommerce-setup.tcl 26 May 2002 04:36:50 -0000 1.2 @@ -1,10 +1,36 @@ ad_page_contract { - @author Walter McGinnis (wtem@olywa.net) - @creation-date 03-10-2001 - @cvs_id $ID$ + + Setup documentation of the ecommerce package, a package to implement + business-to-consumer web services. + + @author Bart Teeuwisse + @creation-date May 2002 + +} { } -properties { - ec_url:onevalue + title:onevalue + context_bar:onevalue } -set ec_url [ec_url] +# Authenticate the user +set user_id [ad_maybe_redirect_for_registration] + +# Check for read privileges + +set package_id [ad_conn package_id] +set admin_p [ad_permission_p $package_id read] + +set package_name "Ecommerce" +set title "$package_name Documentation: Setup" +set package_url [apm_package_url_from_key "ecommerce"] + +set shipping_gateway_installed [apm_package_installed_p "shipping-gateway"] + +# Set the context bar. + +set context_bar [ad_context_bar [list "." "$package_name Documentation"] "Setup"] + +# Set signatory for at the bottom of the page + +set signatory "bart.teeuwisse@7-sisters.com" Index: openacs-4/packages/ecommerce/www/doc/ecommerce-technical.adp =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/ecommerce/www/doc/ecommerce-technical.adp,v diff -u -r1.1 -r1.2 --- openacs-4/packages/ecommerce/www/doc/ecommerce-technical.adp 20 Apr 2001 20:51:14 -0000 1.1 +++ openacs-4/packages/ecommerce/www/doc/ecommerce-technical.adp 26 May 2002 04:36:50 -0000 1.2 @@ -1,638 +1,771 @@ - -Technical Details of the Ecommerce Module + -

    Setup

    + + @title@ + @signatory@ -
      -
    • This module requires Oracle 8i. -

      -

    • Install CyberCash by following the instructions for the -ArsDigita Shoppe. -(Note: it can take a few weeks for your bank and CyberCash to get your -account ready, so get started on that right away!) -
      -

      You can start testing your system with the included CyberCash emulator by following these steps: -

      -

      -$ cd /web/your_service_name/packages/ecommerce/tcl/
      -$ mv cybercash-emulator-procs.tcl.for.testing cybercash-emulator-procs.tcl
      -
      -

      restart your server +

      @title@

      + + + + + + +
      @context_bar@
      +
      -

      The emulator is useful, but far from perfect. Currently, it works for authorizing, but it bombs when called from ec_unsettled_transactions. There is trouble with a bad table name (sh_orders) and a bad column (price_charged). It's clearly meant for ArsDigita Shoppe and hasn't been converted completely. This means that marked orders are never settled while using the emulator. If you fix the emulator, please send a patch to janine@furfly.net. +

      Setup

      -

      When you get a real CyberCash account, REMEMBER TO DISABLE THE EMULATOR! -

      +
        -

        +

      • +

        Install an implementation of the Payment Service Contract such as the Authorize.net Gateway or the VeriSign PayflowPro Gateway .

        -
      • These are the files in this E-commerce release that you need to have to run the package: -
          -
        • ACS Geotables Package for needed states and country code data -
        • data model in packages/ecommerce/sql/ecommerce*.sql -
        • documentation in packages/ecommerce/www/doc/* -
        • scripts in packages/ecommerce/www -
        • admin scripts in packages/ecommerce/www/admin/ -
        • ADP templates in packages/ecommerce/www/templates/ -
        • tcl procs in packages/ecommerce/tcl -
        • ecommerce parameters that can be reached from /admin/site-map/ (after mounting an instance of the E-commerce application) - -
        +

        (Note: it can take a few weeks for your bank and a payment + gateway to get your account ready, so get started on that + right away!)

        +
      • -

        This should be updated to outline the process of grabbing the package. +

        + +

        You can start testing @package_name@ with a VeriSign + test account and the PayflowPro Gateway . With the 30-day FREE + TRIAL, you'll see just how easy it is to begin accepting on-line + payments.

        -

        +

        -
      • Install the ACS Geotables package. +
      • + +

        These are the files in this @package_name@ release that you need to + have to run the package:

        - +
      • +

        A /web/yourserver/data/ecommerce/product directory is + needed to hold the products' supporting files (it's outside the + web root so that no uploaded supporting files can be executed). + The directory has to be write-able by nsadmin. (You can change + the directory by editing EcommerceDataDirectory and + ProductDataDirectory in your @package_name@ parameters.)

        +
      • -

        +

      • +

        Based on the site owner's publishing decisions, @package_name@ + parameters need to be edited via /admin/site-map/. Make sure to + do the following:

        + +
          +
        • +

          Enable @package_name@, EnabledP should equal 1 in the + ecommerce section.

          +
        • +
        • +

          Complete the SSL section fully.

          +
        • +
        • +

          Pay particular attention to the technical, payment and + shipping sections:

          +
            +
          • +

            CustomerServiceEmailAddress should be set to some real + email address

            +
          • +
          • +

            Make sure to replace yourservername in + EcommerceDataDirectory with the correct path! This + parameter should also have a trailing slash!

            +
          • +
          • +

            ProductDataDirectory should have a trailing slash.

            +
          • +
          • +

            ImageMagickPath could vary on your machine, hunt down + the convert command on your system and update + this path.

            +
          • +
          • +

            Set PaymentGateway to the package key of the Payment Service + Contract + implementation you like to use to handle the financial + transactions.

            +
          • +
          • +

            Set ShippingGateway to the package key of the Shipping Service + Contract + implementation if you like to use different shipping + rules than the standard @package_name@ shipping + rules.

            +
          • +
          +
        + +
      • +

        Qmail must be installed on your system (it may require special + setup if you're running your server + chrooted).

        +
      • -
      • Install the Ecommerce package. +
      • +

        Optional: @package_name@ includes a customized version of the + registration/login/logout pipeline which handles the transition + to secure logins a bit more gracefully than the ACS Subsites + Package. You may want to patch the ACS Subsites and ACS TCL + packages to match the behavior of @package_name@. See the directions for applying the patch.

        -

        +

      • +

        Optional: If you want to have products be "visible" to the Site + Wide Search package then you need to install the Site Wide Search + Package, including all of its requirements for installation. + During the installation of SWS or after run + packages/ecommerce/sql/ec-products-sws-setup.sql to add products + to your interMedia index.

        -
      • ImageMagick must be installed (either in /usr/local/bin/ or elsewhere -if you're running your server chrooted) -if you want thumbnails -to be automatically created. For information on ImageMagick (which is -free), see Chapter 6: -Adding Images to Your Site of Philip and Alex's Guide to Web -Publishing. +

        Note: At this time (Version 4.0a, April 6th, + 2001) the interface to SWS has a bug (quite possibly the bug is + actually in SWS) that prevents it from working. See the Release Notes for a bit more detail. If you + come up with a fix, send a patch to wtem@olywa.net.

        +
      • +
      -

      -

    • You'll want to setup a means of using SSL for secure transactions, check OpenNSD.org or AOLServer.com for modules for SSL and follow instructions for using them. +

      Under the Hood

      -

      -

    • Create instance of Ecommerce Package using the /admin/site-map/ on your server. -
        -
      • Create a new subfolder where you want to mount it. -

        Make sure you have a matching set of default templates. -

          -
        • $ cd /web/yourserver/packages/ecommerce/www/templates/
          -$ mkdir your_new_subfolder
          -$ cp store/* your_new_subfolder/
          -
          -
        • Create a new application for that mount point that is an E-commerce application. -
        • Set parameters for the instance (see below). -
        +

        This is provided just for your own information. You may never + need to know any of it, but it may prove useful if something goes + wrong or if you want to extend the module.

        -

        -

      • A /web/yourserver/data/ecommerce/product directory is needed to hold the products' -supporting files (it's outside the web root so that no uploaded supporting files -can be executed). The directory has to be writeable by nsadmin. (You can change the directory by editing EcommerceDataDirectory and ProductDataDirectory in your parameters .ini file.) -

        MAKE SURE THE CORRESPONDING PARAMETERS FOR THE PACKAGE ARE SET TO MATCH IN THE NEXT STEP! -

        +

        Financial Transactions

        +
        -
      • Based on the site owner's publishing decisions, the ecommerce parameters -need to be edited via /admin/site-map/. Make sure to do the following: -
          -
        • Make sure E-commerce is enabled, EnabledP should equal 1 in the ecommerce section. -
        • Complete the SSL section fully -
        • Pay particular attention to the technical section: -
            -
          • CustomerServiceEmailAddress should be set to some real email address -
          • Make sure to replace yourservername in EcommerceDataDirectory with the correct path! This parameter should also have a trailing slash! -
          • ProductDataDirectory should have a trailing slash. -
          • ImageMagickPath could vary on your machine, hunt down the convert command on your system and update this path. -
          -
        - -

        Note that you should hit set parameters for each section and then flush the cache of ecommerce parameters by restarting your server (this is something specific to parameters in ecommerce). +

        A financial transaction is inserted whenever a credit card + authorization to charge or refund is made. These transactions + may or may not be carried through to fulfillment. The + specifics:

        -

        +

        When an order is placed, an authorization is done for the full + cost of the order. @package_name@ creates one or two new + ec_financial_transactions. Two rows are created + when the order consists of some items that require shipping + while others don't, otherwise @package_name@ creates a single + row. The rows each have a unique transaction_id and + are tied to the order using the + order_id. @package_name@ immediately captures the + transaction for the items that do not require + shipping. @package_name@ doesn't captures the transaction for the + items that need shipping not until the items ship.

        -
      • May not be accurate anymore -

        The page templates display correctly only if you're using fancy ADP parsing. -To do this, make sure that this is in your server .ini file (replacing yourserver -with the name of your server): +

        When a shipment is made, if it's a full shipment of the order, + the financial transactions inserted when the order is first + placed are ready to be captured. (The field + to_be_captured_p of the financial transactions + become 't' and @package_name@ attempts to capture it.)

        -
        -[ns/server/acs/adp/parsers]
        -fancy=.adp
        -
        +

        However, if only a partial shipment is made, a new + authorization has to be made (therefore a new row is inserted + into ec_financial_transactions, + to_be_captured_p is set to 't' and the system + attempts to mark and capture it). -

        +

        When a refund is made, a row is also inserted into + ec_financial_transactions. A refund is only + inserted if it is definite that it needs to be captured, so + there is no need to set to_be_captured_p if + transaction_type='refund'.

        -
      • Either find a copy of the zip_codes table to import (ArsDigitans know where -to find it but unfortunately we can't redistribute it because it's licensed), -or delete the little bit of code that uses it. +

        Scheduled procs go around and do the follow-through (making + sure everything is marked/settled) for every transaction that + needs to be captured.

        -

        +

      • + +

        Gift Certificates

        -
      • Qmail must be installed on your system (it may require special setup -if you're running your server chrooted). +
        + +

        Each customer has a gift certificate balance (it may be $0.00), + which you can determine by calling the PL/SQL function + ec_gift_certificate_balance. Different chunks of a + customer's balance may expire at different times because every + gift certificate that is issued has an expiration date.

        -

        +

        When the system applies a customer's gift certificate balance + to an order, it begins by using the ones that are going to + expire the soonest and continues chronologically until either + the order is completely paid for or until the customer's gift + certificates run out. If only part of a gift certificate is + used, the remaining amount can be used later.

        -
      • Optional: The E-commerce Package includes a customized version of the registration/login/logout pipeline which handles the transition to secure logins a bit more gracefully than the ACS Subsites Package. You may want to patch the ACS Subsites and ACS TCL packages to match the behavior of the E-commerce Package. See the directions for applying the patch. +

        If a customer purchases a gift certificate for someone else, + the recipient (who may or may not be a registered user of the + site) is emailed a claim check that they can use to retrieve the + gift certificate and have it placed in their gift certificate + balance. Note: "retrieving" a gift certificate is equivalent to + inserting the user_id of the owner into + ec_gift_certificates. Retrieved gift certificates + always belong to registered users because gift certificates can + only be retrieved during the course of placing an order, at + which time an unregistered user becomes registered.

        -

        +

        Site administrators can issue gift certificates to customers at + will. In this case, no claim check is generated. The gift + certificate is automatically assigned to that + user_id.

        -
      • Optional: If you want to have products be "visible" to the Site Wide Search package then you need to install the Site Wide Search Package, including all of its requirements for installation. During the installation of SWS or after run packages/ecommerce/sql/ec-products-sws-setup.sql to add products to your interMedia index. Note: At this time (Version 4.0a, April 6th, 2001) the interface to SWS has a bug (quite possibly the bug is actually in SWS) that prevents it from working. See the Release Notes for a bit more detail. If you come up with a fix, send a patch to wtem@olywa.net. -
      + -

      Under the Hood

      +

      Order States

      -This is provided just for your own information. You may never need -to know any of it, but it may prove useful if something goes wrong or -if you want to extend the module. +
      -
        +

        Order states are discussed in detail in Operation of the Ecommerce Module. + That should be read to understand the concepts of order states + and item states and to see the finite state machines involved.

        -
      • Financial Transactions -

        -A financial transaction is inserted whenever a credit card -authorization to charge or refund is made. These transactions may -or may not be carried through to fulfillment. The specifics: -

        -When an order is placed, an authorization is done for the full -cost of the order, so a row is inserted into ec_financial_transactions. -This row has a unique transaction_id and it is tied to the order -using the order_id. This isn't captured yet (not until -the items ship). -

        -When a shipment is made, if it's a full shipment of the order, the -financial transaction inserted when the order is first placed -is ready to be captured (to_be_captured_p becomes 't' and the -system attempts to mark and capture it). -

        -However, if only a partial shipment is made, a new authorization has -to be made (therefore a new row is inserted into ec_financial_transactions, to_be_captured_p is set to 't' and the -system attempts to mark and capture it). +

        Below is a very boring diagram of what order state the order + should be in given the item state of the items in that order. + This diagram only covers the order states VOID, + PARTIALLY_FULFILLED, FULFILLED, and RETURNED. All other order + states are grouped under OTHER. In all other order states, the + items are of a uniform item state, so it is either quite obvious + what the order state will be or it is completely independent of + what the order state will be.

        -

        -When a refund is made, a row is also inserted into ec_financial_transactions. -A refund is only inserted if it is definite that it needs to be captured, -so there is no need to set to_be_captured_p if transaction_type='refund'. -

        -Scheduled procs go around and do the follow-through (making sure everything -is marked/settled) for every transaction that needs to be captured. -

        -

      • Gift Certificates -

        -Each customer has a gift certificate balance (it may be $0.00), which you -can determine by calling the PL/SQL function ec_gift_certificate_balance. Different chunks of a customer's balance may expire at different -times because every gift certificate that is issued has an expiration date. -

        -When the system applies a customer's gift certificate balance to an order, -it begins by using the ones that are going to expire the soonest and continues -chronologically until either the order is completely paid for or until the -customer's gift certificates run out. If only part of a gift certificate is -used, the remaining amount can be used later. -

        -If a customer purchases a gift certificate for someone else, the recipient -(who may or may not be a registered user of the site) is emailed a claim -check that they can use to retrieve the gift certificate and have it -placed in their gift certificate balance. Note: "retrieving" a gift -certificate is equivalent to inserting the user_id of the -owner into ec_gift_certificates. Retrieved gift certificates -always belong to registered users because gift certificates can -only be retrieved during the course of placing an order, at which time -an unregistered user becomes registered. -

        -Site administrators can issue gift certificates to customers at will. -In this case, no claim check is generated. The gift certificate is -automatically assigned to that user_id. -

        -

      • Order States -

        -Order states are discussed in detail in Operation of the Ecommerce Module. That should be read to understand the -concepts of order states and item states and to see the finite state machines -involved. -

        -Below is a very boring diagram of what order state the order should be in -given the item state of the items in that order. This diagram only -covers the order states VOID, PARTIALLY_FULFILLED, FULFILLED, and -RETURNED. All other order states are grouped under OTHER. In all other -order states, the items are of a uniform item state, -so it is either quite obvious what the order state will be or it is completely -independent of what the order state will be. -

        -An "X" in a column implies that there is at least one (possibly many) item -in that item state. -

        - - - - - - - - - +

        An "X" in a column implies that there is at least one (possibly + many) item in that item state.

        - - - - - - - +
        Item StateOrder State
        -VOID - -RECEIVED_BACK - -SHIPPED - -OTHER -
        -X - -X - -X - -X - -PARTIALLY_FULFILLED -
        + + + + + + + + - - - - - - - + + + + + + + - - - - - - - + + + + + + + - - - - - - - + + + + + + + - - - - - - - + + + + + + + - - - - - - - + + + + + + + - - - - - - - + + + + + + + + + + + + + + - - - - - - - - - - - - - - + + + + + + + - - - - - - - + + + + + + + - - - - - - - + + + + + + + - - - - - - - + + + + + + + - - - - - - - + + + + + + + -
        Item StateOrder State
        + VOID + + RECEIVED_BACK + + SHIPPED + + OTHER +
        -X - -X - -X - -0 - -FULFILLED -
        + X + + X + + X + + X + + PARTIALLY_FULFILLED +
        -X - -X - -0 - -X - -PARTIALLY_FULFILLED -
        + X + + X + + X + + 0 + + FULFILLED +
        -X - -X - -0 - -0 - -RETURNED -
        + X + + X + + 0 + + X + + PARTIALLY_FULFILLED +
        -X - -0 - -X - -X - -PARTIALLY_FULFILLED -
        + X + + X + + 0 + + 0 + + RETURNED +
        -X - -0 - -0 - -X - -OTHER -
        + X + + 0 + + X + + X + + PARTIALLY_FULFILLED +
        -X - -0 - -0 - -0 - -VOID -
        + X + + 0 + + 0 + + X + + OTHER +
        + X + + 0 + + 0 + + 0 + + VOID +
        -0 - -X - -X - -X - -PARTIALLY_FULFILLED -
        -0 - -X - -X - -0 - -FULFILLED -
        + 0 + + X + + X + + X + + PARTIALLY_FULFILLED +
        -0 - -X - -0 - -X - -PARTIALLY_FULFILLED -
        + 0 + + X + + X + + 0 + + FULFILLED +
        -0 - -X - -0 - -0 - -RETURNED -
        + 0 + + X + + 0 + + X + + PARTIALLY_FULFILLED +
        -0 - -0 - -X - -X - -PARTIALLY_FULFILLED -
        + 0 + + X + + 0 + + 0 + + RETURNED +
        -0 - -0 - -0 - -X - -OTHER -
        + 0 + + 0 + + X + + X + + PARTIALLY_FULFILLED +
        + + + 0 + + + 0 + + + 0 + + + X + + + OTHER + + + -

        +

      -
    • Shopping Cart Definitions -

      +

      Shopping Cart Definitions

      -
      -
      Shopping Cart
      -
      An IN_BASKET order with the same user_session_id as in the user's cookie.
      -
      Saved Cart
      -
      An IN_BASKET order with the user_id filled in, no user_session_id filled in, and saved_p='t'
      -
      Abandoned Cart
      -
      An IN_BASKET order with saved_p='f' and a user_session_id that doesn't correspond to the user_session_id in anyone's cookie (e.g. the user's cookie expired or they turned cookies off). There's no way of determining whether a shopping cart has been abandoned. These are different from expired orders which are automatically put into the order state EXPIRED if they're still IN_BASKET after N days, where N is set in the .ini file) -
      +
      +
      +
      Shopping Cart
      -

      -

    • Credit Card Pre-Checking -

      -Before credit card information is sent out to CyberCash for authorization, -some checking is done by the module to make sure that the credit card -number is well-formed (using the procedure ec_creditcard_precheck which can be found in /tcl/ecommerce-credit). The procedure checks the length of the credit card number, makes sure -it starts with the right digit for the card type, and does a LUHN-10 -check (that's a checksum which can't determine whether the number is a -valid credit card number but which determines whether it's even possible -for it to be a valid credit card number). -

      -This procedure only encompasses the three most common credit card types: -MasterCard, Visa, and American Express. It can quite easily be extended -to include other credit card types. -

      -

    • Automatic Emails -

      -When you install the system, there are 7 automatic emails included that -are sent to customers in common situations (e.g., "Thank you for your -order" or "Your order has shipped"). If a site administrator adds a -new email template using the admin pages, you will have to create a -new procedure that does all the variable substitution, the actual -sending out of the email, etc. This should be easy. Just copy any -one of the 7 autoemail procedures in /tcl/ecommerce-email (except -for ec_email_gift_certificate_recipient, which is unusual). -Then invoke your new procedure anywhere appropriate (e.g. the email that -says "Thank you for your order" is invoked by calling -ec_email_new_order $order_id after the order has been -successfully authorized). -

      -

    • Storage of Credit Card Numbers -

      -Credit card numbers are stored until an order is completely fulfilled. -This is done because a new charge might need to be authorized if a -partial shipment is made (we are forced to either capture the amount that -a charge was authorized for or to capture nothing at all - we can't capture any -amount in between; therefore, we are forced to do a new authorization -for each amount we are going to charge the user). A new charge also might -need to be authorized if a user has asked the site administrator to add -an item to their order. -

      -If you've decided not to allow customers to reuse their credit cards, -their credit card data is removed periodically (a few times a day) by -ec_remove_creditcard_data in -/tcl/ecommerce-scheduled-procs (it removes credit card numbers for -orders that are FULFILLED, RETURNED, VOID, or EXPIRED). -

      -If you've decided to allow customers to reuse their credit cards, their -credit card information is stored indefinitely. This is not recommended -unless you have top-notch, full-time, security-minded system administrators. -The credit card numbers are not encrypted in the database because there -isn't much point in doing so; our software would have to decrypt the -numbers anyway in order to pass them off to CyberCash, so it would be -completely trivial for anyone who breaks into the machine to grep for -the little bit of code that decrypts them. The ideal thing would be -if CyberCash were willing to develop a system that uses PGP so that we -could encrypt credit card numbers immediately, store them, and send them -to CyberCash at will. Philip and Alex's Guide to Web Publishing says: +

      An IN_BASKET order with the same user_session_id as in the + user's cookie.
      -
      -     What would plug this last hole is for CyberCash to give us a public key. We'd encrypt the consumer's card -number immediately upon receipt and stuff it into our Oracle database. Then if we needed to retry an -authorization, we'd simply send CyberCash a message with the encrypted card number. They would decrypt the -card number with their private key and process the transaction normally. If a cracker broke into our server, the -handful of credit card numbers in our database would be unreadable without Cybercash's private key. The same -sort of architecture would let us do reorders or returns six months after an order.
      -     CyberCash has "no plans" to do anything like this. -
      -Note 1: If you or the company you work for are very powerful or -influential, perhaps you can put a little fire under CyberCash's bum -to get them to make that change (Levi's couldn't convince CyberCash -when we were doing a project for them). It's not like it would be -that hard for CyberCash to implement it. -

      -Note 2: The above discussion does not mean that the credit -card numbers go over the network unencrypted. CyberCash's closed-source -software on your machine encrypts the numbers immediately before sending them out. -

      -Note 3: If you want to let your customers reuse their old credit cards, -you can reduce some of the risk by manually removing old credit card data -once in a while (at least then there will be fewer numbers in your database for -the crackers to steal). To clear out the unnecessary credit card data, just -run a procedure like ec_remove_creditcard_data (in -/tcl/ecommerce-scheduled-procs) but get rid of the if statement that -checks whether SaveCreditCardDataP is 0 or 1. -

      -

    • Price Calculation -

      -The site administrator can give the same product different prices for -different classes of users. They can also put products on sale over -arbitrary periods of time (sale prices may be available to all -customers or only to ones who have the appropriate offer_code -in their URL). -

      -The procedure ec_lowest_price_and_price_name_for_an_item in /tcl/ecommerce-money-computations determines the lowest price that a given user -is entitled to receive based on what user classes they're in and what -offer_codes they came to product with. Their offer_codes are stored, along with their user_session_id, in -ec_user_session_offer_codes (we decided to store this in -the database instead of in cookies because it was a slightly more efficient -method, although either implementation would have worked). One minor -complication to this is that if a user saves their shopping cart, we want -them to get their special offer price, even though they may be coming -back with a different user_session_id; therefore, upon retrieving saved -carts, the offer_codes are inserted again into -ec_user_session_offer_codes with the user's current -user_session_id (we had to associate offer_codes -with user_session_id as opposed to user_id -because someone with an offer_code shouldn't be prevented -from seeing the special offer price if they haven't logged in yet). -

    +
    Saved Cart
    -The above items are just things that I've found myself explaining to -others or things that I think will be useful for people extending -this module. Obviously the bulk of the module's code has not been -discussed here. If you have any questions, please email Eve at -eveander@arsdigita.com -or Janine at janine@furfly.net +
    An IN_BASKET order with the user_id filled in, no + user_session_id filled in, and saved_p='t'
    +
    Abandoned Cart
    +
    An IN_BASKET order with saved_p='f' and a user_session_id + that doesn't correspond to the user_session_id in anyone's + cookie (e.g. the user's cookie expired or they turned cookies + off). There's no way of determining whether a shopping cart + has been abandoned. These are different from expired orders + which are automatically put into the order state EXPIRED if + they're still IN_BASKET after N days, where N is set in the + @package_name@ parameters.) + + + +

    Credit Card Pre-Checking

    + +
    + +

    Before credit card information is sent out to the payment + gateway for authorization, some checking is done by the module + to make sure that the credit card number is well-formed (using + the procedure ec_creditcard_precheck which can be + found in /tcl/ecommerce-credit). The procedure checks the + length of the credit card number, makes sure it starts with the + right digit for the card type, and does a LUHN-10 check (that's + a checksum which can't determine whether the number is a valid + credit card number but which determines whether it's even + possible for it to be a valid credit card number).

    + +

    This procedure only encompasses the three most common credit + card types: MasterCard, Visa, and American Express. It can + quite easily be extended to include other credit card types.

    + +
    + +

    Automatic Emails

    + +
    + +

    When you install the system, there are 7 automatic emails + included that are sent to customers in common situations (e.g., + "Thank you for your order" or "Your order has shipped"). If a + site administrator adds a new email template using the admin + pages, you will have to create a new procedure that does all the + variable substitution, the actual sending out of the email, etc. + This should be easy. Just copy any one of the 7 autoemail + procedures in /tcl/ecommerce-email (except for + ec_email_gift_certificate_recipient, which is + unusual). Then invoke your new procedure anywhere appropriate + (e.g. the email that says "Thank you for your order" is invoked + by calling ec_email_new_order $order_id after the + order has been successfully authorized).

    + +
    + +

    Storage of Credit Card Numbers

    + +
    + +

    Credit card numbers are stored until an order is completely + fulfilled. This is done because a new charge might need to be + authorized if a partial shipment is made (we are forced to + either capture the amount that a charge was authorized for or to + capture nothing at all - we can't capture any amount in between; + therefore, we are forced to do a new authorization for each + amount we are going to charge the user). A new charge also + might need to be authorized if a user has asked the site + administrator to add an item to their order.

    + +

    If you've decided not to allow customers to reuse their credit + cards, their credit card data is removed periodically (a few + times a day) by ec_remove_creditcard_data in + /tcl/ecommerce-scheduled-procs (it removes credit card numbers + for orders that are FULFILLED, RETURNED, VOID, or EXPIRED).

    + +

    If you've decided to allow customers to reuse their credit + cards, their credit card information is stored indefinitely. + This is not recommended unless you have top-notch, full-time, + security-minded system administrators. The credit card numbers + are not encrypted in the database because there isn't much point + in doing so; our software would have to decrypt the numbers + anyway in order to pass them off to the payment gateway, so it + would be completely trivial for anyone who breaks into the + machine to grep for the little bit of code that decrypts them. + The ideal thing would be if payment gateways were willing to + develop a system that uses PGP so that we could encrypt credit + card numbers immediately, store them, and send them to the + payment gateway at will. Philip and Alex's Guide to Web + Publishing says:

    + +
    + +

    What would plug this last hole is for a payment gateway to + give us a public key. We'd encrypt the consumer's card number + immediately upon receipt and stuff it into our Oracle + database. Then if we needed to retry an authorization, we'd + simply send the payment gateway a message with the encrypted + card number. They would decrypt the card number with their + private key and process the transaction normally. If a cracker + broke into our server, the handful of credit card numbers in + our database would be unreadable without the payment gateway's + private key. The same sort of architecture would let us do + reorders or returns six months after an order.

    + +
    + +

    Note 1: The above discussion does not mean that the + credit card numbers go over the network unencrypted. Most + payment gateways use secure connections.

    + +

    Note 2: If you want to let your customers reuse their old + credit cards, you can reduce some of the risk by manually + removing old credit card data once in a while (at least then + there will be fewer numbers in your database for the crackers to + steal). To clear out the unnecessary credit card data, just run + a procedure like ec_remove_creditcard_data (in + /tcl/ecommerce-scheduled-procs) but get rid of the if statement + that checks whether SaveCreditCardDataP is 0 or 1.

    + +
    + +

    Price Calculation

    + +
    + +

    The site administrator can give the same product different + prices for different classes of users. They can also put + products on sale over arbitrary periods of time (sale prices may + be available to all customers or only to ones who have the + appropriate offer_code in their URL).

    + +

    The procedure + ec_lowest_price_and_price_name_for_an_item in + /tcl/ecommerce-money-computations determines the lowest price + that a given user is entitled to receive based on what user + classes they're in and what offer_codes they came + to product with. Their offer_codes are stored, + along with their user_session_id, in + ec_user_session_offer_codes (we decided to store + this in the database instead of in cookies because it was a + slightly more efficient method, although either implementation + would have worked). One minor complication to this is that if a + user saves their shopping cart, we want them to get their + special offer price, even though they may be coming back with a + different user_session_id; therefore, upon + retrieving saved carts, the offer_codes are + inserted again into ec_user_session_offer_codes + with the user's current user_session_id (we had to + associate offer_codes with + user_session_id as opposed to user_id + because someone with an offer_code shouldn't be + prevented from seeing the special offer price if they haven't + logged in yet).

    +
    + +

    The above items are just things that I've found myself explaining + to others or things that I think will be useful for people + extending this module. Obviously the bulk of the module's code + has not been discussed here. If you have any questions, please + email Eve at eveander@arsdigita.com or + Janine at janine@furfly.net + + Index: openacs-4/packages/ecommerce/www/doc/index.adp =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/ecommerce/www/doc/index.adp,v diff -u -r1.1 -r1.2 --- openacs-4/packages/ecommerce/www/doc/index.adp 20 Apr 2001 20:51:14 -0000 1.1 +++ openacs-4/packages/ecommerce/www/doc/index.adp 26 May 2002 04:36:50 -0000 1.2 @@ -1,53 +1,85 @@ - -Ecommerce Module + -This module implements all the IT needs for a standard -business-to-consumer Web service. Most importantly, it is tightly -integrated with the rest of the ArsDigita Community System. This -enables the site administrator to run a single Oracle query to "find -users who have participated in the discussion forum on at least ten -separate occasions but who have not bought anything yet", then spam -those folks with gift certificates. + + @title@ + @signatory@ -

    -In addition to the standard shopping cart and real-time credit card billing -that you'd expect in any ecommerce system, this module provides a customer -service submodule (call center support), security, user tracking, -gift certificates, mailing lists, an auditing system, order fulfillment, -order tracking, special offers, and online reporting, among other features -detailed in the overview below. +

    @title@

    + + + + + + + +
    @context_bar@ + + [ Administer ] + +
    +
    +

    @package_name@ implements all the IT needs for a standard + business-to-consumer web service. Most importantly, it is tightly + integrated with the rest of the Open Architecture Community System + (OpenACS). This enables the site administrator to run a single + query to "find users who have participated in the discussion forum + on at least ten separate occasions but who have not bought + anything yet", then spam those folks with gift certificates.

    -
      -
    1. Two overviews: for MBAs | feature-by-feature -
    2. Setting up your ecommerce site -
    3. Operation of your ecommerce site -
    4. The Customer Service submodule -
    5. Technical details -
    6. Establishing Style and Supporting Multi-Lingualism -
    7. Audit Trail Package -

      -

    8. Release notes -

      -

    9. Porting Diary +

      In addition to the standard shopping cart and real-time credit + card billing that you'd expect in any ecommerce system, @package_name@ + provides a customer service submodule (call center support), + security, user tracking, gift certificates, mailing lists, an + auditing system, order fulfillment, order tracking, special offers, + and online reporting, among other features detailed in the overview + below.

      -
    +
      +
    1. Two overviews: for MBAs | feature-by-feature
    2. +
    3. Setting up @package_name@
    4. +
    5. Operation of @package_name@
    6. +
    7. The @package_name@ Customer Service Module
    8. +
    9. Technical details
    10. +
    11. Auditing @package_name@
    12. +
    -
    - +

    Notes from the transition from ACS 3.x to 4.x.

    -If you just want to sell a handful of items and not build a full online -community, you're probably better off starting with ArsDigita Shoppe, -downloadable from -http://arsdigita.com/free-tools/shoppe. -If what you want to sell is conference or course registration, we'll be -adding those features to the ACS soon but meanwhile we do have the -source code for register.photo.net. This code has -been used to process thousands of course and marathon registrations. +
      +
    1. 4.1a Release notes
    2. +
    3. 4.1a Porting diary
    4. +
    -
    -
    +
    + +

    If you just want to sell a handful of items and not build a + full online community, you're probably better off starting + with ArsDigita Shoppe, downloadable from http://arsdigita.com/free-tools/shoppe.

    +
    +
    +

    @package_name@ is part of the Open + Architecture Community System (OpenACS) originally developed + by Eve Andersson then ported + from the Arsdigita Community System to OpenACS by Jerry Asher, Walter McGinnis, and furfly.net followed by a major overhaul + by Bart + Teeuwisse.

    +

    @package_name@ is free software; you can redistribute it + and/or modify it under the terms of the GNU General Public License + as published by the Free Software Foundation; either version 2 of + the License, or (at your option) any later version.

    + +

    @package_name@ is distributed in the hope that it will be + useful, but WITHOUT ANY WARRANTY; without even the implied + warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + See the GNU General Public License for more details.

    + +

    A copy of the GNU General Public License is + included. If not write to the Free Software Foundation, Inc., 59 + Temple Place, Suite 330, Boston, MA 02111-1307 USA Index: openacs-4/packages/ecommerce/www/doc/kernel-patches.txt =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/ecommerce/www/doc/kernel-patches.txt,v diff -u -r1.1 -r1.2 --- openacs-4/packages/ecommerce/www/doc/kernel-patches.txt 20 Apr 2001 20:51:14 -0000 1.1 +++ openacs-4/packages/ecommerce/www/doc/kernel-patches.txt 26 May 2002 04:36:50 -0000 1.2 @@ -10,25 +10,30 @@ ad_returnredirect "/register/index?return_url=[ns_urlencode [ad_conn url]&http_id=$user_id&[ad_conn query]]" -## you will also need to add http_id handling to packages/acs-subsites/www/register/index.tcl and index.adp +## you will also need to add http_id handling to packages/acs-subsite/www/register/index.tcl and index.adp add the following to expected variables for index.tcl.ad_page_contract http_id:optional then add the following to the body of the index.tcl script - if {[info exists http_id]} { - template::query email onevalue "select email from parties where party_id = :http_id" + + if {[info exists http_id]} { + template::query select_email email onevalue "select email from parties where party_id = :http_id" } else { - set http_id "" + set http_id "" } on register/index.adp do the following: change +

    Log In

    + to

    Secure Log In

    + and after the first
    tag (roughly line 11) add +

    Please login to our secure server. ## that's it, ofcourse you can customize the template as you wish. Index: openacs-4/packages/ecommerce/www/doc/porting-diary.adp =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/ecommerce/www/doc/porting-diary.adp,v diff -u -r1.1 -r1.2 --- openacs-4/packages/ecommerce/www/doc/porting-diary.adp 20 Apr 2001 20:51:14 -0000 1.1 +++ openacs-4/packages/ecommerce/www/doc/porting-diary.adp 26 May 2002 04:36:50 -0000 1.2 @@ -1,289 +1,507 @@ - -Porting Diary + -

    Porting Diary

    -

    ACS 4.0 alpha

    -
    -
      + + @title@ + @signatory@ -
    • Initial import into 4.0. Collected files from acs-3.4.8 doc, -doc/sql, tcl, admin/ecommerce, and ecommerce/ (and later from -templates). Moved ad.ini params into ecommerce params. +

      @title@

      + + + + + + +
      @context_bar@
      +
      -
    • ec_create_new_session_if_necessary (ecommerce-defs.tcl), redirects -to the cookie chain were removed (as cookie chain strategy has been -altered radically in 4.0 (removing the cookie-chain code.) +

      Diary

      + +
        -

        -a new standard? -

        +
      • +

        Initial import into 4.0. Collected files from acs-3.4.8 doc, + doc/sql, tcl, admin/ecommerce, and ecommerce/ (and later from + templates). Moved ad.ini params into ecommerce params.

        +
      • -Our standard in the future is going to be that we always redirect the -user to "www.sitename.com" if they try to access the site as -"sitename.com". Then we can set cookies with Domain=.sitename.com and -they will take effect on all cobranded sites. A better answer is not -to use cookies at all (directly)! The new session-tracking facilities -(see the security and session-tracking documentation) take care of -managing session or persistent state for you in the database, securely -if necessary. -

        --- Jon Salz, April 13, 2000 -

        -

        +
      • +

        ec_create_new_session_if_necessary (ecommerce-defs.tcl), + redirects to the cookie chain were removed (as cookie chain + strategy has been altered radically in 4.0 (removing the + cookie-chain code.)

        -
      • Incorporated the ACS 3.4 style system. A grep of ACS 3.4 reveals -that ecommerce was only module to use the old system. The old system -has been renamed: calls of the form ad_... have been renamed to ec_... +

        a + new standard?

        -

        Expect that in the future, dependence on the old system will lessen -and the system will move to the new templating system. +

        -

        ad.ini params moved into ecommerce/styles package params +

        Our standard in the future is going to be that we always + redirect the user to "www.sitename.com" if they try to + access the site as "sitename.com". Then we can set cookies + with Domain=.sitename.com and they will take effect on all + cobranded sites. A better answer is not to use cookies at + all (directly)! The new session-tracking facilities (see the + security and session-tracking documentation) take care of + managing session or persistent state for you in the + database, securely if necessary.

        -
      • Modified calls to ad_parameter to take into account package_id -using [ec_id]. Ironically, this may take port a step backward and -prevent it from being mounted more than once in a site. This can be -relaxed by changing ec_id to find the "right" ecommerce package as -opposed to the first one, (or whichever one it is finding.) +

        -- Jon Salz, April 13, 2000

        -
      • Wrapped ad_parameter calls with util_memoize -- I think the 4.0 -ad_parameter is cool but quick benchmarking shows it is potentially -very slow. The util_memoize call uses the value of ec_cache_refresh -to periodically refresh the cache. (This should be simplified and -built into ad_parameter if you ask me.) +
      • +
      • -
      • Checked for nsssl and made ecommerce compatible with nsopenssl +
      • +

        ad.ini params moved into ecommerce/styles package params.

        +
      • -
      • Checked for nsunix and made ecommerce compatible with nsunix +
      • +

        Modified calls to ad_parameter to take into account + package_id using [ec_id]. Ironically, this may take port a + step backward and prevent it from being mounted more than once + in a site. This can be relaxed by changing ec_id to find the + "right" ecommerce package as opposed to the first one, (or + whichever one it is finding.)

        +
      • -
      • Added ecommerce-security-procs to help make it easy to create -links to and from secure pages. (Used code "repurposed" from David -Rodriguez's ACS 3.4 events modules and enhanced for nsopenssl and -nsunix compatibility. +
      • +

        Wrapped ad_parameter calls with util_memoize -- I think the + 4.0 ad_parameter is cool but quick benchmarking shows it is + potentially very slow. The util_memoize call uses the value + of ec_cache_refresh to periodically refresh the cache. (This + should be simplified and built into ad_parameter if you ask + me.)

        +
      • -
      • Added kernel security parameter SecureLoginsRequiredP, which -defaults to 1. For most ecommerce sites, this should probably be set -to 0 by the site admin. The affect of this parameter is to lessen -security somewhat, but to keep users from having to login twice, once -for an http and once for an https session. +
      • +

        Checked for nsssl and made ecommerce compatible with + nsopenssl.

        +
      • -
      • Later modified security_processor's sec_handler, as well as login -pages in acs-subsite...register to emulate Amazon's behavior. When -login on https is requested, email address of non-secure http user is -presented. +
      • +

        Checked for nsunix and made ecommerce compatible with + nsunix.

        +
      • -

        More information can be found at ACS feature request 9767 +

      • +

        Added ecommerce-security-procs to help make it easy to create + links to and from secure pages. (Used code "repurposed" from + David Rodriguez's ACS 3.4 events modules and enhanced for + nsopenssl and nsunix compatibility.

        +
      • +
      • +

        Added kernel security parameter SecureLoginsRequiredP, which + defaults to 1. For most ecommerce sites, this should probably + be set to 0 by the site admin. The affect of this parameter + is to lessen security somewhat, but to keep users from having + to login twice, once for an http and once for an https + session.

        +
      • -
      • tags-search-replace "/ecommerce/" "[ec_url]" +
      • +

        Later modified security_processor's sec_handler, as well as login + pages in acs-subsite...register to emulate Amazon's behavior. When + login on https is requested, email address of non-secure http user is + presented.

        -
      • replaced calls to philg_email_valid_p with ad_page_contract ... email filter (in gift-certificates....) +

        More information can be found at ACS + feature request 9767

        +
      • -
      • added cybercash-emulator-procs.tcl to ecommerce/tcl +
      • +

        tags-search-replace "/ecommerce/" "[ec_url]"

        +
      • -
      • changed references to table users_preferences to user_preferences +
      • +

        replaced calls to philg_email_valid_p with ad_page_contract + ... email filter (in gift-certificates....)

        +
      • -
      • changed references to table users to table cc_users +
      • +

        changed references to table users_preferences to + user_preferences.

        +
      • -
      • changed pages that made their own secure/insecure links to use -ec_securelink (which securelink will fallback to an insecure link if -that is all that is available.) +
      • +

        changed references to table users to table cc_users

        +
      • -
      • copied qmail.tcl from acs-3.4.8 to ecommerce/tcl/qmail-procs.tcl. -Eventually, ecommerce should instead use the ACS 4.1 acs-mail system. +
      • +

        changed pages that made their own secure/insecure links to use + ec_securelink (which securelink will fallback to an insecure link if + that is all that is available.)

        +
      • -
      • incorporated gift certificate fix from aD -forum +
      • +

        copied qmail.tcl from acs-3.4.8 to ecommerce/tcl/qmail-procs.tcl. + Eventually, ecommerce should instead use the ACS 4.1 acs-mail system.

        +
      • -
      • got product search working, I needed to copy -acs-3.4.8/www/doc/sql/pl-sql.sql to -ecommerce/sql/pl-sql-utilities-create.sql. Also created a -drop -script. Deleted functions and procs not used by ecommerce. +
      • +

        incorporated gift certificate fix from aD + forum

        +
      • -
      • changed view ec_customer_service_reps to use cc_users and not -users, checked that there were no other bad references to users in -ecommerce-create.sql +
      • +

        got product search working, I needed to copy + acs-3.4.8/www/doc/sql/pl-sql.sql to + ecommerce/sql/pl-sql-utilities-create.sql. Also created a + -drop script. Deleted functions and procs not used by + ecommerce.

        +
      • -
      • started rationalizing outgoing email messages: blew through code (tags search) to ensure everyone gets the from address correctly (using the [ec ..] routine) so that -ec_sendmail_from_service can put something better than just "Customer Service" on the from header. +
      • +

        changed view ec_customer_service_reps to use cc_users and not + users, checked that there were no other bad references to + users in ecommerce-create.sql

        +
      • -
      • in templates that send gift certs out change the link to include -ecommerce mount point to get back to the store itself. +
      • +

        started rationalizing outgoing email messages: blew through + code (tags search) to ensure everyone gets the from address + correctly (using the [ec ..] routine) so that + ec_sendmail_from_service can put something better than just + "Customer Service" on the from header.

        +
      • -
      • fix bug in admin/shipping-costs/edit involving validation of shipping charges (shipping weight) +
      • +

        in templates that send gift certs out change the link to + include ecommerce mount point to get back to the store + itself.

        +
      • -
      • imported ad_audit_trail facilities +
      • +

        fix bug in admin/shipping-costs/edit involving validation of + shipping charges (shipping weight)

        +
      • -
      • fixed up nav bars and ec footers to point to "\[ec_system_name\] -Home" and not just Home as sites might have multiple ecommerce -packages mounted and to indicate that ecommerce home is not the same -as site home +
      • +

        imported ad_audit_trail facilities

        +
      • -
      • fixed up https links once more pointing to site home page +
      • +

        fixed up nav bars and ec footers to point to + "\[ec_system_name\] Home" and not just Home as sites might + have multiple ecommerce packages mounted and to indicate that + ecommerce home is not the same as site home

        +
      • -
      • fixed up register/index and request processor so that a login -page redirect by transition from http to https contains the email -address of the user. +
      • +

        fixed up https links once more pointing to site home page

        +
      • -
      • tags search replace of context_bar.*ecommerce to .. Ecommerce(\[ec_system_name\]) +
      • +

        fixed up register/index and request processor so that a login + page redirect by transition from http to https contains the + email address of the user.

        +
      • -
      • tags search, add ad_require_permission admin to all admin pages +
      • +

        tags search replace of context_bar.*ecommerce to + .. Ecommerce(\[ec_system_name\])

        +
      • -
      • fix up ec_navbar to offer admins an admin link +
      • +

        tags search, add ad_require_permission admin to all admin + pages

        +
      • -
      • parameterized ImageMagick's convert utility (since it might not -live in /usr/local/bin). Created an ecommerce package parameter, -appropriately memoized getter function. Placed getter in admin/products/add-2 and edit-2 +
      • +

        fix up ec_navbar to offer admins an admin link

        +
      • -
      • checked for existence of convert utility (as more elegant than just catching failure)a -
      • checked for failure of convert utility as it runs -
      • fixed url generation of images, given new structure of acs -packages (not just under AOLservers webroot, but under package -webroot) +
      • +

        parameterized ImageMagick's convert utility (since it might + not live in /usr/local/bin). Created an ecommerce package + parameter, appropriately memoized getter function. Placed + getter in admin/products/add-2 and edit-2.

        +
      • -
      • removed registered proc that handles /product-file requests and -converts them to real names, created product-file/index.vuh to return -correct file +
      • +

        checked for existence of convert utility (as more elegant + than just catching failure)

        +
      • -
      • generalized a product's one line and detailed description so it could contain -html, which it appears it used to but now cannot since -ad_page_contract, defaults to using the filter :nohtml. How many more of -these are there? Does it need to be :allhtml? +
      • +

        checked for failure of convert utility as it runs

        +
      • -
      • fixed a bug in ec_display_rating s/EcommerceDirectory/EcommerceDataDirectory/ -
      • tweaked product template in ecommerce-create.sql to display ec_navbar (and to make category_id available to template) +
      • +

        fixed url generation of images, given new structure of acs + packages (not just under AOLservers webroot, but under package + webroot)

        +
      • -
      • fixed up hardcoded www/admin to lookup url of acs-admin package to fix up links to /acs-admin/users/one -
      • fixed up doc so that /admin/ecommerce is usually /ecommerce/admin or [ec_url]admin +
      • +

        removed registered proc that handles /product-file requests and + converts them to real names, created product-file/index.vuh to return + correct file

        +
      • -
      • replaced philg_quote_double_quotes with ad_quotehtml -
      • replaced philg_hidden_imput with ec_hidden_input +
      • +

        generalized a product's one line and detailed description so + it could contain html, which it appears it used to but now + cannot since ad_page_contract, defaults to using the filter + :nohtml. How many more of these are there? Does it need to + be :allhtml?

        +
      • -
      • Built acs-geo-table package to encapsulate old ACS 3 geo tables. Loaded it. -
      • Fixed ecommerce-create.sql to include country-code and state fields that Janine commented out. +
      • +

        fixed a bug in ec_display_rating + s/EcommerceDirectory/EcommerceDataDirectory/

        +
      • -
      • Tuned checkout pipeline, ensuring that it's https if possible the -entire time, that users are logged in, that there are no links out of -pipeline (not a requirement, just a "selling" focus) until final page, -that the navbar changes to show the various steps in the checkout -pipeline ala amazon, and that on final page, links away are insecure -and direct the visitor back to http mode. +
      • +

        tweaked product template in ecommerce-create.sql to display + ec_navbar (and to make category_id available to template)

        +
      • -
      • moved ad_adp_function_p to ec_adp_function_p, mainly used in -taking submission of templates from admins but restricting them to -template without tcl functions, and made the behavior subject to an -ecommerce style paramter. Changed the complaints to use -ad_return_complaint. +
      • +

        fixed up hardcoded www/admin to lookup url of acs-admin + package to fix up links to /acs-admin/users/one

        +
      • -
      • fixed bug in add member to mailing list which forgot (unlike acs3 -user-search to add percents around pattern to wildcard: %pattern% +
      • +

        fixed up doc so that /admin/ecommerce is usually + /ecommerce/admin or [ec_url]admin

        +
      • -
      • fixed two bugs in items-add-(2 3). In items-add-2, use -ec_add_to_cart_link instead of ec_add_to_cart_link_sub. In -items-add-3, change sytle to style. -Did anyone ever user/report this? +
      • +

        replaced philg_quote_double_quotes with ad_quotehtml

        +
      • -
      • made sure that product directory can be outside webroot so that -uploaded .tcl/.adp, etc. files cannot be executed with a webhit. - -
      • fix queries in customer-service/actions.tcl and statistics.tcl to use cc_users +
      • +

        replaced philg_hidden_imput with ec_hidden_input

        +
      • -
      • fix bug in email-send failing when there is no customer email address +
      • +

        Fixed ecommerce-create.sql to include country-code and state + fields that Janine commented out.

        +
      • -
      • fix bug in admin/sales-tax/clear-2.tcl which called -ec_audit_delete_row with a "wildcard" of "", something beyon the -simple API of ec_audit_delete_row. +
      • +

        Tuned checkout pipeline, ensuring that it's https if possible + the entire time, that users are logged in, that there are no + links out of pipeline (not a requirement, just a "selling" + focus) until final page, that the navbar changes to show the + various steps in the checkout pipeline ala amazon, and that on + final page, links away are insecure and direct the visitor + back to http mode.

        +
      • -
      +
    • +

      moved ad_adp_function_p to ec_adp_function_p, mainly used in + taking submission of templates from admins but restricting + them to template without tcl functions, and made the behavior + subject to an ecommerce style paramter. Changed the + complaints to use ad_return_complaint.

      +
    • +
    • +

      fixed bug in add member to mailing list which forgot (unlike + acs3 user-search to add percents around pattern to wildcard: + %pattern%

      +
    • -

      Todo

      -
        -
      • collect addresses of gift certificate people -
      • migrate from ecommerce templates to ATS -
      • better utilize ad_page_contract contracts and filters +
      • +

        fixed two bugs in items-add-(2 3). In items-add-2, use + ec_add_to_cart_link instead of ec_add_to_cart_link_sub. In + items-add-3, change sytle to style. Did anyone ever + user/report this?

        +
      • -
      • go through ecommerce-create.sql and deal with issues (such as the -states table) that were initially punted +
      • +

        made sure that product directory can be outside webroot so that + uploaded .tcl/.adp, etc. files cannot be executed with a webhit.

        +
      • + +
      • +

        fix queries in customer-service/actions.tcl and + statistics.tcl to use cc_users

        +
      • -
      • tried/fixed admin/gift-certificates-issued.tcl -
      • tried/fixed admin/refunds.tcl -
      • did a tags query replace for users to cc_users +
      • +

        fix bug in email-send failing when there is no customer email + address

        +
      • -
      • make gift certificate claim checks a link +
      • +

        fix bug in admin/sales-tax/clear-2.tcl which called + ec_audit_delete_row with a "wildcard" of "", something beyon + the simple API of ec_audit_delete_row.

        +
      • -
      • need to resolve the last modifying user during package creation time, setting it to user_id of initializer? -
      • product add/edit forms seem to have problems allowing html in (at least that was case in acs-3.4.8 -
      • add yourself to email link is annoying, it should not display if you are already subscribed +
      -
    • should products be able to be in both a subcategory AND a category -at the same time? If yes, change admin/products/edit-2.tcl +

      Todo

      -
    • generalize search to search through all categories, or store, or site +
        +
      • +

        collect addresses of gift certificate people

        +
      • -
      • generalize product templates to be mapped to subcategories and subsubcategories. +
      • +

        better utilize ad_page_contract contracts and filters

        +
      • -
      • incorporate acs-references or places package to get zipcode info +
      • +

        did a tags query replace for users to + cc_users

        +
      • -
      • place all references to ad_parameters into an ec_parameters tcl file +
      • +

        make gift certificate claim checks a link

        +
      • + +
      • +

        need to resolve the last modifying user during package + creation time, setting it to user_id of initializer?

        +
      • -
      • cleanup meaning of "no shipping" -- is this strictly for services -(e.g. software development), downloadable products, etc. or does this -reflect something else (e.g. hole in database initialization). -Perhaps parameterize display of "no shipping" so that sites can make -that display as "services", or "downloads." +
      • +

        add yourself to email link is annoying, it should not display + if you are already subscribed

        +
      • -
      • add an inventory module -
      • add a top level link to admin/orders/fulfillment-items-needed -
      • add downloads of data in csv or excel form to get into spreadsheets -
      • create page (or module) specific doc and add links to those doc pages -
      • add top level page to view various logs, including ec_automatic_email_log, ec_spam_log +
      • +

        should products be able to be in both a subcategory AND a + category at the same time? If yes, change + admin/products/edit-2.tcl

        +
      • -
      +
    • +

      generalize search to search through all categories, or store, + or site

      +
    • -

      To test (or to fix)

      -
        -
      • fix back button back to a form in ssl mode (known to expire immediately) -
      • product search -
      • double click protection on gift certificates -
      • test test test test test test test test test test test test test test test test test test test test test test test test test test test test -
      • As usual aD module is meant to create, not maintain. In this case, ec_sessions and ec_orders are created but never deleted -
      • replace ec_sessions with ad_sessions -
      • reengineer to prevent url hacking +
      • +

        generalize product templates to be mapped to subcategories + and subsubcategories.

        +
      • -
      • either a zero dollar order or a gift cert order creates an order with no date information -
      • Order emails do not contain an order number or a tracking link -
      • Gift cert emails don't contain a link back to the site to automagically redeem the gift cert +
      • +

        place all references to ad_parameters into an ec_parameters + tcl file

        +
      • -
      • after an http to https transition (caused during a submit?) from -checkout to checkout-2, you end back up at checkout-1 +
      • +

        cleanup meaning of "no shipping" -- is this strictly for + services (e.g. software development), downloadable products, + etc. or does this reflect something else (e.g. hole in + database initialization). Perhaps parameterize display of "no + shipping" so that sites can make that display as "services", + or "downloads."

        +
      • -
      • audit tables are often not working +
      • +

        add an inventory module

        +
      • -
      • fullfil appears to have a problem taking tracking numbers down -and/or fulfilling things that cosst $0. +
      • +

        add a top level link to + admin/orders/fulfillment-items-needed

        +
      • -
      • offer codes and sale prices +
      • +

        add downloads of data in csv or excel form to get into + spreadsheets

        +
      • -
      • make user classes more interesting -
          -
        • offer ability to add one, multiple, or all members from a search to class -
        • add some data mining (people who purchased in last n days, got refunds, bought more than x, bought ... -
        • parameterize the classes (bought more than X days, or bought more than Y) -
        • add complex searches to them bought more than AND bought from category -
        • add a QBE interface to search -
        +
      • +

        create page (or module) specific doc and add links to those + doc pages

        +
      • -
      • unify ec tables with acs object system, esp wrt. permissions and audit trails +
      • +

        add top level page to view various logs, including + ec_automatic_email_log, ec_spam_log

        +
      • -
      +
    +

    To test (or to fix)

    +
      +
    • +

      fix back button back to a form in ssl mode (known to expire + immediately)

      +
    • -

      Add maintenance and exports tasks

      -
        -
      • Archive/Purge ec_automatic_email_log, ec_problems_log, ec_cybercash_log, ec_financial_transactions, ec_customer_service_issues, ec_spam_log; -
      -
    +
  • +

    As usual aD module is meant to create, not maintain. In this + case, ec_sessions and ec_orders are created but never + deleted

    +
  • + +
  • +

    replace ec_sessions with ad_sessions

    +
  • + +
  • +

    reengineer to prevent url hacking

    +
  • + +
  • +

    Order emails do not contain an order number or a tracking + link

    +
  • + +
  • +

    Gift cert emails don't contain a link back to the site to + automagically redeem the gift cert

    +
  • + +
  • +

    audit tables are often not working

    +
  • + +
  • +

    make user classes more interesting

    +
  • + +
  • +

    offer ability to add one, multiple, or all members from a search to class

    +
  • + +
  • +

    add some data mining (people who purchased in last n days, + got refunds, bought more than x, bought ...

    +
  • + +
  • +

    parameterize the classes (bought more than X days, or bought + more than Y)

    +
  • + +
  • +

    add complex searches to them bought more than AND bought from + category

    +
  • + +
  • +

    add a QBE interface to search

    +
  • + +
  • +

    unify ec tables with acs object system, esp wrt. permissions + and audit trails

    +
  • + + +

    Add maintenance and exports tasks

    + +
      +
    • +

      Archive/Purge:

      +
        +
      • ec_automatic_email_log
      • +
      • ec_problems_log
      • +
      • ec_financial_transactions
      • +
      • ec_customer_service_issues
      • +
      • ec_spam_log
      • +
      +
    • +
    Index: openacs-4/packages/ecommerce/www/doc/release.adp =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/ecommerce/www/doc/release.adp,v diff -u -r1.1 -r1.2 --- openacs-4/packages/ecommerce/www/doc/release.adp 20 Apr 2001 20:51:14 -0000 1.1 +++ openacs-4/packages/ecommerce/www/doc/release.adp 26 May 2002 04:36:50 -0000 1.2 @@ -1,90 +1,117 @@ - -Ecommerce Release Notes + -

    E-commerce Package Version 4.1a (first Alpha release)

    + + @title@ + @signatory@ -

    Features

    -

    The goal of this release was to bring the ACS 3x ecommerce module' -s features to an ACS 4x package. You can find a feature summary in the Features of the Ecommerce Module document. +

    @title@

    + + + + + + +
    @context_bar@
    +
    + +

    Features

    -

    Keep in mind that this release isn't a redesign of E-commerce to take advantage of all of ACS 4x new features. It doesn't have multiple retailer handling, nor can package be mounted in multiple instances in the site-map and work correctly. Templating is still done with the old E-commerce templating system (although it now lives alongside ATS). I hope that these improvements can be rolled into a future release. For now, those whose needs are satisfied by the functionality of the old ecommerce module, but want to move to ACS 4x, should be happy. To everybody who wants something more, we would love your contributions of code! Please see the OpenACS SDM to report bugs (patches always welcome) or make feature requests. +

    The goal of this release was to bring the ACS 3x ecommerce + module' s features to an ACS 4x package. You can find a feature + summary in the Features of the + Ecommerce Module document. -

    For more details about the porting process check out this partial porting diary. +

    Keep in mind that this release isn't a redesign of + @package_name@ to take advantage of all of ACS 4x new features. + It doesn't have multiple retailer handling, nor can package be + mounted in multiple instances in the site-map and work correctly. + For now, those whose needs are satisfied by the functionality of + the old ecommerce module, but want to move to ACS 4x, should be + happy. To everybody who wants something more, we would love your + contributions of code! Please see the OpenACS SDM to report bugs + (patches always welcome) or make feature requests.

    + +

    For more details about the porting process check out this partial + porting diary. -

    Requirements

    - +

    Requirements

    -

    Known Issues

    + -

    As this is an alpha release there are a few things that still need to be fixed. +

    Known Issues

    -
      -
    • www/admin/products/upload-2.tcl needs to be converted to using the PL/SQL function ec_product.new instead of old insert.
    • -
    • A number of auditing inserts are not working. -
    • The included (but disabled by default) CyberCash emulator has some problems, see the Technical documentation for details. -
    • The optional Site Wide Search interface results in the following error when a trying to rebuild the index after a new ec_product object has been created (ECOM_4X_DEV was the oracle user name): -

      -

      -
      -ERR_INDEX_NAME		       ERR_TIMEST ERR_TEXTKEY
      ------------------------------- ---------- ------------------
      -ERR_TEXT
      ---------------------------------------------------------------------------------
      -SWS_SRCH_CTS_DS_IIDX	       2001-04-06 AAAGkQAAIAAAEh5AAD
      -DRG-12604: execution of user datastore procedure has failed
      -DRG-50857: oracle error in drsinopen
      -ORA-06550: line 1, column 18:
      -PLS-00302: component 'SWS_INDEX_PROC' must be declared
      -ORA-06550: line 1, column 7:
      -PL/SQL: Statement ignored
      -ORA-06512: at "ECOM_4X_DEV.SWS_SERVICE", line 230
      -ORA-06512: at "ECOM_4X_DEV.SWS_SERVICE", line 260
      +  

      As this is an alpha release there are a few things that still + need to be fixed.

      -
      -
      -I'm pretty sure that the bug is actually in the SWS code, not the E-commerce package. -

      -

    • Technical documentation is still a little rough. You should be able to get things working with the documentation as is. It doesn't cover how to find, download, and install a package. I suspect all that is needed here is a link to an adequate document, but I haven't had a chance to find it yet. If you have questions please email wtem@olywa.net. -
    -We welcome any bugs fixes for any of these problems, please contact wtem@olywa.net if you come up with fixes and/or visit -the OpenACS SDM +
      + +
    • A number of auditing inserts are not working.
    • +
    • The optional Site Wide Search interface results in the + following error when a trying to rebuild the index after a new + ec_product object has been created (ECOM_4X_DEV was the oracle + user name): +
      + +
      +	ERR_INDEX_NAME		       ERR_TIMEST ERR_TEXTKEY
      +	------------------------------ ---------- ------------------
      +	ERR_TEXT
      +	--------------------------------------------------------------------------------
      +	SWS_SRCH_CTS_DS_IIDX	       2001-04-06 AAAGkQAAIAAAEh5AAD
      +	DRG-12604: execution of user datastore procedure has failed
      +	DRG-50857: oracle error in drsinopen
      +	ORA-06550: line 1, column 18:
      +	PLS-00302: component 'SWS_INDEX_PROC' must be declared
      +	ORA-06550: line 1, column 7:
      +	PL/SQL: Statement ignored
      +	ORA-06512: at "ECOM_4X_DEV.SWS_SERVICE", line 230
      +	ORA-06512: at "ECOM_4X_DEV.SWS_SERVICE", line 260
      +	
      +
      +
      -

      Functions "removed" from acs 4 stuck back into ec

      -
      - - - - - - - - - - - - - - - - - - - - - - - - - -
      wasis
      util_GetUserAgentHeaderecGetUserAgentHeader
      ad_register_styletagec_register_styletag
      ad_style_template_root_internalec_style_template_root_internal
      ad_style_template_rootec_style_template_root
      ad_style_language_from_cookieec_style_language_from_cookie
      ad_style_plain_fancy_from_cookieec_style_plain_fancy_from_cookie
      ad_style_user_preferences_from_dbec_style_user_preferences_from_db
      ad_style_score_templatesec_style_score_templates
      ad_style_sort_by_scoreec_style_sort_by_score
      ad_return_templateec_return_template
      cc_send_to_server_21cc_send_to_server_21
      qmailqmail
      qmail_send_complete_messageqmail_send_complete_message
      logical_negationlogical_negation
      one_if_within_n_daysone_if_within_n_days
      pseudo_containspseudo_contains
      util_decodeutil_decode
      ad_audit_trail ec_audit_trail
      ad_audit_trail_for_table ec_audit_trail_for_table
      ad_state_name_from_usps_abbrevec_state_name_from_usps_abbrev
      ad_country_name_from_country_codeec_country_name_from_country_code
      fm_adp_function_pec_adp_function_p
      util_IllustraDatetoPrettyDateec_IllustraDatetoPrettyDate
      -
      +

      I'm pretty sure that the bug is actually in the SWS code, not + @package_name@. (wtem@olywa.net)

      -
    +
  • Technical documentation is + still a little rough. You should be able to get things working + with the documentation as is. It doesn't cover how to find, + download, and install a package. I suspect all that is needed + here is a link to an adequate document, but I haven't had a + chance to find it yet. If you have questions please email wtem@olywa.net.
  • - - + + +

    We welcome any bugs fixes for any of these problems, please + contact wtem@olywa.net if you + come up with fixes and/or visit the OpenACS SDM

    + +

    Functions "removed" from acs 4 stuck back into ec

    + +
    + + + + + + + + + + + + + + +
    Was:Is:
    util_GetUserAgentHeaderecGetUserAgentHeader
    qmailqmail
    qmail_send_complete_messageqmail_send_complete_message
    logical_negationlogical_negation
    one_if_within_n_daysone_if_within_n_days
    pseudo_containspseudo_contains
    ad_audit_trail ec_audit_trail
    ad_audit_trail_for_table ec_audit_trail_for_table
    ad_state_name_from_usps_abbrevec_state_name_from_usps_abbrev
    ad_country_name_from_country_codeec_country_name_from_country_code
    fm_adp_function_pec_adp_function_p
    util_IllustraDatetoPrettyDateec_IllustraDatetoPrettyDate
    +