Product catalog

9 views
Skip to first unread message

bobwaycott

unread,
Feb 4, 2009, 1:57:25 PM2/4/09
to Satchmo developers
Hey guys,

A couple weeks ago, I posted in another thread about the current state
of Satchmo's product handling, and I thought it might be useful to
have a thread for discussing how things can be improved, ask questions
about how the current catalog could be better used, etc.

So, to start with, I thought I'd respond to Chris' invitation for
ideas on the product system. Here goes, and nothing that follows is
meant to diminish the incredible work that has been done on Satchmo
thus far -- it's one of the most robust, powerful, and complete open
source shops I've seen to date (and it's Django!).

1. Product model & CUSTOM_PRODUCT_MODULES

Currently, I think the greatest weakness in Satchmo's product handling
revolves around everything being setup via OneToOneField
relationships, thus requiring a lot of two-stepping to get a product
created, and creating various custom products that point back to the
original. I think the better approach would be the path of Model
Inheritance, provided very nicely via Django 1.0+. Rather than coding
up a custom_product_module like this:

class CustomProduct(models.Model):
product = models.OneToOneField(Product, primary_key=True)
... (extra special model code here)

We could instead code up our custom_product_modules like so:

class CustomProduct(Product):
special_field = models.WhateverField(blah blah)

I think this makes the custom product work the way a client/user or
even one of us custom developers expect it to -- I just have to load
up my admin form for adding a CustomProduct and a Product is created
that Satchmo can use without requiring me to create that product
first. I can then also create custom ModelForms for my CustomProduct
that might hide any of the base Product fields I don't want to expose
as part of my CustomProduct. To me, this ought to be the expected
behavior. If it was, I could more easily create a special Book,
Magazine, DVD, Computer, or whatever product a client has, and tailor
it specifically for what information they might actually intend to
manage for each type of product. Furthermore, this would also allow me
to perform other custom actions on my custom products, while ensuring
the minimum information needed by Satchmo's cart and checkout is still
there.

2. Product Options

We have traditionally provided Options as attributes that are accessed
and manipulated when viewing the actual product they relate to.
Satchmo brings users through creating an OptionGroup, then
OptionItems, then Variations -- which ultimately end up creating new
Products, the way CustomProducts should. From a data perspective, it
doesn't strike me as intuitive that creating variations from options
would create entirely separate products. This is one area where I
think we might just have things a little backward -- Options seem to
me to be most appropriately handled via ForeignKey relationships, and
each Option can have its own ability to have option-specific quantity,
price, etc. When I go to manage inventory now, I have three products
that show up, where one is the actual product I'm selling, and two are
the different options available. Furthermore, the front-end templates
list all three as individual products on sale, even though accessing
any of them shows the base product and the options appear in a drop-
down.

In short, I think options should be handled as additional attributes
of any particular product and would thus be editable from that
product's admin page, but wouldn't be created and listed as individual
products in their own right.

3. Pricing

This is the weakness that brought me over to dealing with Options and
realizing their behavior I discuss above. Pricing is currently limited
by forcing the existence of only one real price. To explain, my client
currently sells the same exact product at a US and International
price. Satchmo has no ability to handle this adequately. Price is
limited to a unique combination of product and quantity, so I can't
even save a Price 1 with qty 1 and save the higher international price
with qty 1. Pricing should, in my mind, be independent of quantity
altogether. Changing price based on quantity gets too close to
discounts, and should be left to handle appropriately there. When you
add in satchmo_ext.tieredpricing, you now have three different models/
apps that are handling pricing, all of which are in one way or another
tied to quantity.

If I was building a catalog based on model inheritance, I would hope
to see one default price stored with the product object itself, not in
some related table through a ForeignKey reference. I'm not certain
about the rest of you, but it also seems like the issue of a US/
International price is still a common meme in online shopping. Even if
it isn't, having the ability to define multiple prices for a single
product doesn't seem too outrageous, leaving it up to the developer to
implement custom rules on when Price2 is used in place of Price1. So
far, it doesn't seem like creating a CustomProduct can handle this too
well -- I'm still forced to provide Price to my CustomProduct via a
Price_Inline in the admin form and am limited to the behavior that
makes it depend on quantity.

So aside from my comments on, any pointers on how to handle this US/
INTL price issue in a way that is quantity agnostic?

Hmm ... maybe I'll take a break at this point and see where this
conversation can go.

Additionally, I am going to try and work on some potential design
mockups related to the admin. I'm sure I'm not the only one who would
like to see a more user-friendly admin area, and I don't know about
the rest of you, but I often find it helpful to think about what I am
going to present the end-user interface-wise when I am coding up
anything at all. Django's automatic registration of models in the
admin is great for quickly building up and interacting with Models --
but no client I have approaches managing a store as interacting with a
long list of Models. Perhaps some sketches of a user-focused admin
could help us think through things.

Thanks for all the hard work, Chris & Bruce. Hopefully we can hear
from you guys, too.

Best,

Bob

Shankar Dhanasekaran

unread,
Feb 5, 2009, 3:39:13 AM2/5/09
to satchmo-d...@googlegroups.com
Thats a great long post! I totally agree with the admin area cleanup. Most ecommerce system have a good admin section and it's one of the best selling point for Magento ecommerce, though I'd not use it for my projects! Definetly with good admin imporvements, Satchmo will be adopted and looked upon by large number of users.

Just a small suggestion with the admin. see this ticket http://www.satchmoproject.com/trac/ticket/717

Thanks,
Shakthi

bobwaycott

unread,
Feb 5, 2009, 10:28:44 AM2/5/09
to Satchmo developers
Ticket 717 for read-only admin fields is high on my priority list for
my present client. I am going to be modifying a number of fields this
way, particularly the Order-related forms.

I am hoping to be granted permission to share that work back with the
community.



On Feb 5, 3:39 am, Shankar Dhanasekaran <newage.blog...@gmail.com>
wrote:
> Thats a great long post! I totally agree with the admin area cleanup. Most
> ecommerce system have a good admin section and it's one of the best selling
> point for Magento ecommerce, though I'd not use it for my projects!
> Definetly with good admin imporvements, Satchmo will be adopted and looked
> upon by large number of users.
> Just a small suggestion with the admin. see this tickethttp://www.satchmoproject.com/trac/ticket/717

Chris Moffitt

unread,
Feb 5, 2009, 10:12:49 PM2/5/09
to satchmo-d...@googlegroups.com
Thanks for taking the time to put your thoughts down. I have read them and will provide my perspective.

The main reason our current product model does not use inheritance is that when it was created, Django didn't have a good inheritance method in place. We used 1-1 relationships because that was the alternative. Now that model inheritance is fully supported in Django, I think it's worth taking a look at. Conceptually, this is cleaner.

As far as options, option groups and variants go, part of the reason we designed it the way we did is that we wanted an easy way to create all the combinations of various options. For instance, in the T-shirt model, each combo is an actual "inventoriable" item. The thought is that you would need the ability to monitor each combo and understand what is and is not in stock. Using the approach you propose would probably make that more difficult. However, if I'm misunderstanding you and there is a way to continue to maintain individual inventory/sku combos then I'd like to understand it.

Your point about multiple price points is valid and there are a lot of interactions between pricing and discounts. Given your needs of having multiple price points for US and International, there's not really a good way to do it now.

So, the bottom line is that you have some good ideas. You're bringing up true warts and areas we want to clean up. The problem is that we're tackling some pretty intrusive changes here and I just haven't had the time to dive in and figure out how to implement. I will say this, though, if we can figure something out to address a lot of your issues, Satchmo will truly be very robust.

I'd be interested in other's comments but I think the next step is to try to get some more detail design ideas out there  and see what shakes out.

-Chris

bobwaycott

unread,
Feb 6, 2009, 1:28:34 PM2/6/09
to Satchmo developers
Chris,

Thanks for the response. It's great to hear some of the thinking
behind Satchmo's current design.

Regarding model inheritance, I completely understand why it's not
currently implemented and don't fault Satchmo on that. But I do think
it could be an improvement for the community to look at and work
together on implementing.

Regarding options and variants, I, again, completely understand the
intention behind each variant being an "inventoried" item as it
currently operates. In fact, Satchmo is great on that front. In fact,
that is one strength it holds over one of our largest online
retailers' current shop (10,000+ products with >5 options each), who
often would like to be able to merchandise certain variant products
alone, rather than them only showing up as an option to a product.
However, for sanity's sake, I think variants really should be kept
separate from the base product table. The one verifiable proof I have
for this is what currently happens in the Satchmo templates -- after I
create a couple of variations, I notice that all the variations and
the product they descend from show in a list at /products/ . . . but
clicking on any of them brings me to the parent product's detail page,
with all variants in a drop-down box. I'm sure there's a way to filter
out the variants from the /products/ list (I haven't yet looked into
it), but it still strikes me as a counterintuitive behavior.

While I'm new to the Satchmo community, I hope you'll indulge me with
my own suggestion of how product data could be more sanely managed,
while providing a maximum of custom flexibility for the developers who
pick it up for their clients.

class Product
=============
product_id
site
name
slug
sku
price
[price_intl] ???
short_description
description
category
[vendor/brand] ???
items_in_stock
meta
date_added
active
featured
ordering
related items
taxable
taxClass
shipclass

You'll notice I've removed a lot of information that we currently have
tied to the base product class in Satchmo. That's because all that
width/height/length/weight stuff strikes me as non-base information.
Those are specifications of a particular kind of physical product for
which those properties are meaningful. In my thinking, those should be
left to a separate model of say:

class PhysicalSpecifications
============================
weight
weight_units
length
length_units
width
width_units
height
height_units
volume
volume_units
etc.

Separating these physical specifications into a separate model means
that we developers could include them as inlines for our
CUSTOM_PRODUCT_MODULES that subclass Product. Either way, I don't
think we should default to that being considered basic information,
since so many products can be sold in a store that either don't have
those physical specifications, or for which they are meaningless (say,
I'm selling packs of DVDs ... both the customer and the shop owner
aren't very concerned with how wide, long, or high the pack is).
Weight is arguably important for calculating shipping, but even that
is often determined on a store-by-store basis (for example, my client
charges 0 shipping on everything except international air mail) and
keeping that information as a separate specifcation looked up via
ForeignKey would not limit shipping calculations. What would probably
be even better would be a dual group/item setup like we currently have
for Options -- say, SpecificationGroups and Specifications. We could
then create custom groups of specifications of all name/value pairs
for any type of product characteristic, then include them again as
inlines to our own custom products where necessary. So we could create
a group for physical specs for products where that information is
meaningful, another group for computer specifications, or anything
else.

To my mind, Options should be handled the same way, via ForeignKey
references that tie them to a product and get pulled into templates in
that fashion. We can create OptionGroups and Options, but they are
immediately usable as such, not requiring the step of creating
variations that are saved to the product table as currently
implemented. For our largest retailer, we have a very versatile
options setup that handles things this way:

class ProductOption
===================
product_option_id
product_id (ForeignKey)
price
items_in_stock
etc.

This client is a large outdoor equipment/clothing retailer and sell a
jacket, for example, in multiple colors. We actually track inventory
at the Option level, and decrement accordingly at each purchase. Of
course, this may just be more meaningful for this client because we
also manage a three-tiered fulfillment setup:

1. Client fulfills customer orders from warehouse inventory
2. Vendor/Manufacturer drop ships each customer order
3. Client fulfills customer orders from warehouse inventory until 0,
then orders automatically routed to Vendor for drop shipment

Thus, whenever a customer orders a product, we check what fulfillment
that product is assigned to. If it's 1 or 3, we decrement option
quantity. If it is #2, we don't bother with product/option inventory
at all. When we are looking at items_in_stock, if that field is NULL
at the product level, we then look to the options. Items are always
purchased as a product_id + product_option_id combo, so essentially,
inventory logic is always tied to the Options.

Admittedly, this could provide a problem for instances like our
present client for whom we are using Satchmo. There aren't any options
available for a product, but we have a need for PriceOptions. Perhaps
this could even be handled along the lines of Options and
Specifications -- we could have PriceGroups and PriceOptions, or
something similar that would handle selling the same custom product at
multiple price levels that would not have anything at all to do with
quantity ordered -- which strikes me as the realm of Discounts. Of
course, the more simple a base Product class is, the easier it is to
inherit that Product model and make my custom products do what I want
them to do.

We could expand Satchmo's notions of Discounts to be quantity aware,
not just apply as a discount code. Perhaps the easiest way to
implement this is to add a quantity field to Discounts, and let
"automatic discounts" actually be automatic -- don't require a
customer to input a Discount code if it is automatic. Advertise the
discount in whatever way is sensible, but actually automatically apply
it when conditions are met and the item is added to the cart.

Now, about Product Variations -- the way Satchmo implements this is
really quite analogous to how we handle master/slave/normal products
for our largest retailer. That jacket I mentioned before? Well, really
it's a line of jackets, and they change every season. But each new
seasonal addition to the line also has it's own specific options
(like, what are this season's colors?). The option set is always the
same across each variation, but specific only to that variation. These
are added to the base product table, of course, but they also have a
master/slave relationship like so:

product_id = 10998, [various columns], master_product_id = 36

It *seems* like Satchmo is aware of where variations are descended
from, we just make it explicit in our product table. So, in our
scenario, we have MasterProducts, SlaveProducts, and NormalProducts
(the default, where master_product_id = product_id). The only rule
here is that a SlaveProduct cannot have children, and by extension, a
MasterProduct cannot become a SlaveProduct. Just a little sanity to
ensure we don't end up with a client accidentally setting Product A as
the parent of B, and C as the parent of A or child of B later.

I could be way off on that mark, but Satchmo's handling of Variations
just feel that way to me, which still brings me back to understanding
variants to be different from options, not a descendant of them, as
Satchmo currently implements them. Variants seems much more like the
"new model" of some product, whereas options are the red, blue, green,
and yellow colors available.

I hope I haven't lost anybody or myself in any of this. I further hope
I'm not proposing any conception that is drastically more difficult to
manage.

davis

unread,
Feb 6, 2009, 3:33:16 PM2/6/09
to Satchmo developers
I'm currently working on a store requiring a custom product module,
and I must say I keep wishing I could be extending a base product
rather than using the one-to-one field. Your Product class suggestion
sounds excellent to me.
Reply all
Reply to author
Forward
0 new messages