Forum OpenACS Q&A: Product Display at Ecommerce Module

Collapse
Posted by k masuo on

Hi, I'd like some help on how best I could show products at Ecommerce Module like this,

aaa $3.50 bbb $2.80
ccc $4.20 ddd $3.50
eee $3.50 fff $2.60

And here is the procedure what I'm developping,

proc ec_display_product_purchase_combinations { db product_id } {
    # we don't want to return anything if either no purchase 
combinations
    # have been calculated or if no other products have been bought 
by
    # people who bought this product
    set selection [ns_db 0or1row $db "select * from 
ec_product_purchase_comb where product_id=$product_id"]
    if { [empty_string_p $selection] } {
	return ""
    }
    set_variables_after_query
    if { [empty_string_p $product_0] } {
	return ""
    }
    set to_return "People who bought [database_to_tcl_string $db 
"select product_name from ec_products where product_id=$product_id"] 
also bought:
   <table>
     "
    for { set counter 0 } { $counter < 6 } { incr counter } {
	if { ![empty_string_p [set product_$counter]] } {
	    append to_return "<tr><td><a href=&
quot;product.tcl?product_id=[set product_$counter]">
[database_to_tcl_string $db "select product_name from 
ec_products where product_id=[set product_$counter]"]</a>&
lt;/td></tr>
"
	}
    }
    
    append to_return </table>""
    return $to_return

}

and this shows just like this,

aaa $3.50
bbb $2.80
ccc $4.20
ddd $3.50
eee $3.50
fff $2.60

What I expect is a script make 2 different items loop at the same time. Anyone has idea? Please let me know. I'll appreciate any idea or suggestion of yours. Thanks.

Collapse
Posted by Jonathan Ellis on
Here is a proc that will spit out a table like the one you want:
proc_doc util_table_from_list { title list { n_columns 1 } { width 100% } } { returns html for a table, with each item in $list in its own tr/td } { set tr_txt "" set i 0 foreach item $list { if { [expr "$i % $n_columns"] == 0 } { if { $i > 0 } { append tr_txt </tr> } append tr_txt <tr> } append tr_txt " <td valign=top><img src=/graphics/bullet.gif></td> <td valign=top> $item</td>" } if { $i > 0 } { append tr_txt </tr> } set n_colspan [expr "$n_columns + 1"] return " <table cellspacing=0 cellpadding=0 width=$width> <tr><td colspan=$n_colspan align=center>$title</td></tr> $tr_txt </table>" }
Second I would comment that your proc makes between 2 and 8 calls to the db every time it is called. If you were using a normalized data model it should take at most 2 and probably only 1. ec_product_purchase_comb should probably look like

create table ec_product_purchases (
    product_id_1 int not null references ec_products(product_id),
    product_id_2 int not null references ec_products(product_id)
);
you can use the postgres limit keyword if you are concerned about getting more than 6 entries, and if down the road you find you need more than 6 it will be trivial to allow that. I.e. just select out the purchase_id_2 entries matching purchase_id_1 and loop through those rather than the two-step process you have where you have six different product_$counter entries. (Also this way if you have a row in there for every product pair a user purchases you can also do an order by on how popular that matching is.)
Collapse
Posted by k masuo on
Thank you very much for your suggestion. I tried to created that
function spend so much time based on your idea but i couldn't make it
but I will try to figure it out. if you have some suggestion I'll be
appriciate. Thanks.
Collapse
Posted by Jonathan Ellis on
What part are you having trouble with?  The function to print a table based on a list of items, or normalizing the tables in the db?