My company rents ski and snowboard apparel. Some of our products include many options.
Note #203 and #160 get into this need a little bit, but I feel this will be a more comprehensive place to start the discussion *
Rental Gloves Example
Gloves
Style
Mitten
Gloves
Color
Black
White
Size
Small
Medium
Large
Add Glove Liners?
Yes
No
Sell Through Example
Another example. At the end of the season we sell through our inventory.
Jackets, Pants, etc generally have two variants, such as Color/Style and Size, but at the end of the season we sell through our inventory and add a third variant that is "Condition".
For example, a Jacket we might sell
Jacket Title
Color Options
Red
Green
Blue
Black
Size Options
S
M
L
XL
Condition
New With Tags
Like New
Damaged
Custom Variables
We also have the need for a custom variable(s) that can be attached to any product. An example would be adding a name to a product. These custom variables are independent of price and inventory and thus do not need to be factored in as variants.
How could it be implemented?
Considerations
A consideration with variants is that any given variant should be able to impact price and inventory.
For some types of variants, this may be more of a bundle/add-on affect, e.g. my "Glove Liners" example, the inventory that it affects is independent of the core product and the price is in addition to any other calculated price.
For other variants, such as the Jacket example, or Gloves without the liner option, all three options have an affect on inventory and potentially on price of the core product. For example: a Small / Red / New With Tags jacket cannot be substituted for a Small / Red / Like New jacket and vice-versa. Additionally, the price will be different based on it's condition.
How Shopify Does it
Shopify allows up to three options for each product. Options all have the same OptionTitle (such as Color or Size). Once options for a product have been defined, each variant may have a definition Each option has it's own SKU, Price, CompareAtPrice, Barcode, Weight, and Featured Image
Option 1 - Color
Option 2 - Size
Option 3 - Condition
QTY
Price
Red
Small
Like New
4
$65
Red
Medium
Like New
3
$65
Blue
Small
Damaged
1
$25
How Reaction Could do it?
I'm still coming to a full understanding of exactly how the product and variants interact in ReactionCommerce so push back on these ideas at will.
I think we could potentially expand the ProductVariant Schema include up to a set number of potential options. I think the simplest way would be to add up to 3 or 4 set options - E.g:
Obviously this is not the only way to do this, we could allow for an unrestricted number of product options, but if we can also bundle products (issue forthcoming) in the future, then something like this would satisfy my needs.
We would also have to make some adjustments into the admin interface as well as the product template for products and product variants.
Would love to hear feedback on this as well as if anyone else has similar needs.
I've tried to give some additional background information and as a complete a view of the design direction I had been envisioning.
Variants
My view of what defines a variant:
a variant is a product (it is a sku, something for sale)
a product is a group of variants
product.variants is a hierarchical list of infinite child products linked by parentId
a variant could (potentially) be promoted to be a product
a variant is a unique self-encompassing product
a combination of variants make up a product
a product
is already a bundle of products
variants already bundle child variants
In your first example, the product could be the "style".
Product "Mitten"->Color(Red)->Size(Small)
This is the case we support currently.
"Add Glove liners" is probably not a variant, but an add-on-product (or an upsell).
In the second example, or where "Style" is a variant,
the schema and methods support more nesting than the current UI, but this is the way it could work:
My intention was to allow infinite creation of parent->child variants and go as deep as needed.
Just as a matter of priorities, I didn't build a deeper hierarchical variant UI when I built the first variant UI. It's probably a good time to give this whole process another iteration if we want to accommodate more use cases (and test cases). The UI work will be the majority of the effort I think, as little should change in the product or variant methods.
We could add a new action on the child variant ui to allow children to be created.
Likely need to refactor the general option selection to be more user friendly with multiple option paths as well...
Options
where variants are products, options are how we can define the handling for variants.
For bundling #368 and multiple variants, we could add an options array to the Product schema.
Although I've not thought through the use case for variant options, they could potentially exist on the ProductVariant schema as well.
# default variants (variant + child variant)
product.options
template: "coreVariants"
variantId: [variantId]
# include all these variants in the product price and override
template: "coreVariantBundle"
variants: [variantId,variantId,variantId]
variant: **//override all variants*
price: inherit || <pricing method>
inventory: inherit || <inventory method>
# include all these variants in the product price and override individually
template: "coreVariantBundle"
variants: [{variant},variantId,variantId]
# include several products, or product bundles as a bundle with a set price
template: "coreProductBundle"
products: [productId,productId,productId]
product:
price: <pricing method>
inventory: <inventory method>
# to hide a variant
template: "coreVariantDisabled"
variants: [variantId,variantId,variantId]
# to add on optional variants or products
template: "coreProductUpsell"
variants: [variantId]
products: [productId]
for each template in options we return options.template and load a dynamicTemplate with a helper, similar to the reactionApps helper.
alternate, or additional pricing methods
define inventory handling at the product, something that can be easily be made a lot more robust
adds a publish/hide mechanism for variants (which would need to be enforced)
testable
pricing
not unique to options, but we need to notify carts with inventory / pricing changes #120
pricing for variants with pricing methods
inventory
potential inventory methods
chain inventory (tbd)
group inventory (tbd)
without necessarily needing to maintain single inventory record:
i.e.: The SKU is but I only have one that is damaged.
It's possible that much of the logic needed could reside in the products publication, where we could transform the client products collection to an ideal standard. Client collections don't need to mirror the actual data, so this would be an ideal place to implement additional rules.
I've had some discussion and thought about wether variants should be it's own collection. I'm still leaning towards a 'rich document' approach where the documents are as self contained as possible.
I think we want to have a complete snapshot of the users collection states, at each significant event - and - I want to be able to say "If I show you this product" versus "another version of this product", which did you choose? This product is going to the cart made up just as the user saw it, and that's how it should live through the fulfillment process.
UI Updates
These might be a bit of work to make elegant UX wise, but not really technically complex.
we'd need to create/update templates for
bundle product
upsell
variant-child (current)
variant-child-and-more
and some updates to product templates
update variants to support more children
add metafields and display to variants
refactor product to use helper for alternate templates
refactor cart drawer for alternate templates
maybe just some default logic
update "add to cart" to validate different rules based on options.template
upsell or add-on could be an additional cart item
bundle would be one cart item
Metafields
The product.metafields are represented as "Details" in the current UI, but they can be, and are intended for reuse, including search, filtering, and variants properties. These product metafields are not factored in as variants, but metafields exists in variants as well.
Handling of metafields on the variants hasn't been implemented, it's in the Schema though. I think this is what you are looking for when you mentioned 'custom variables'.
However, with your second example it could make sense that condition would be another variant. As you mentioned, some additional warehousing metafields data is likely going to be needed, so you could clone variant of the original and use metafields for that warehousing information (we'd need to adjust inventory as well) - might be a easy UI trick there (split this variant).
metafields on the variant could go partway for #203.
But here, I think we could possibly merge the Products and ProductVariants schemas (adding description, options and other "product fields" to variants #203) making them truly identical.
down the roadmap
Thinking further ahead, there a couple features we have on the roadmap to take into consideration as well:
product and variant hierarchy management See #150
revision control See #151
downloadable products #161
merge the Products and ProductVariants schemas (adding description, options and other "product fields" to variants #203)
There is a lot here, and I probably missed some big holes - and I may have failed to clearly tie everything together - so bring on the feedback. (and hopefully our next posts can be shorter!)
Hopefully this is shorter. Trying to respond to all of the points you bring up:
We agree about what a variant is and most of the nuances around that type.
a product
is already a bundle of products
variants already bundle child variants
Is this part of the vision, or the way the schema works currently?
The schema and methods support more nesting than the current UI.
I should have looked at the schema more closely, this is good to know and fits our needs just fine, should make the 'multi-variant' issue trivial to implement.
Likely need to refactor the general option selection to be more user friendly with multiple option paths as well.
:+1: Agreed on this point. I've got some ideas that I'll start another issue with.
Product options
I like the idea of adding some type of options array to the product schema. I'm also not sure what the use-case for having options on the variants is.
This seems like it will work well for both bundled products as well as upsell products. I should be able to start working on an implementation for this now.
Are there existing pricing and inventory methods?
You might need to explain a little better how the product publication could be used to implement additional rules for these inventory/pricing methods as I don't think I'm following that idea very well.
It seems as if this direction could help solve #161 downloadable products as well as unforseen future product needs.
UI Updates
All of your UI suggestions make sense, definitely some work to make all of this play nice together, but pretty straightforward.
Using Metafields to store custom product variables seems obvious now that you've mentioned it. Should work well for what we need.
Combining Product and ProductVariant Schemas
When you suggest this, do you mean eliminate one of these entirely? It seems the closer we get towards variants being 'child-products' and having optional children themselves that this might be a good way to simplify. Not sure what all of the implications of this are though.
@spencern commented on Wed Apr 15 2015
Multi Variant Products Use-Case and Suggestion
My company rents ski and snowboard apparel. Some of our products include many options.
Rental Gloves Example
Sell Through Example
Another example. At the end of the season we sell through our inventory. Jackets, Pants, etc generally have two variants, such as Color/Style and Size, but at the end of the season we sell through our inventory and add a third variant that is "Condition".
For example, a Jacket we might sell
Custom Variables
We also have the need for a custom variable(s) that can be attached to any product. An example would be adding a name to a product. These custom variables are independent of price and inventory and thus do not need to be factored in as variants.
How could it be implemented?
Considerations
A consideration with variants is that any given variant should be able to impact price and inventory.
For some types of variants, this may be more of a bundle/add-on affect, e.g. my "Glove Liners" example, the inventory that it affects is independent of the core product and the price is in addition to any other calculated price.
For other variants, such as the Jacket example, or Gloves without the liner option, all three options have an affect on inventory and potentially on price of the core product. For example: a Small / Red / New With Tags jacket cannot be substituted for a Small / Red / Like New jacket and vice-versa. Additionally, the price will be different based on it's condition.
How Shopify Does it
Shopify allows up to three options for each product. Options all have the same OptionTitle (such as Color or Size). Once options for a product have been defined, each variant may have a definition Each option has it's own SKU, Price, CompareAtPrice, Barcode, Weight, and Featured Image
How Reaction Could do it?
I'm still coming to a full understanding of exactly how the product and variants interact in ReactionCommerce so push back on these ideas at will.
I think we could potentially expand the
ProductVariant
Schema include up to a set number of potential options. I think the simplest way would be to add up to 3 or 4 set options - E.g:Obviously this is not the only way to do this, we could allow for an unrestricted number of product options, but if we can also bundle products (issue forthcoming) in the future, then something like this would satisfy my needs.
We would also have to make some adjustments into the admin interface as well as the product template for products and product variants.
Would love to hear feedback on this as well as if anyone else has similar needs.
@aaronjudd commented on Fri May 01 2015
I've tried to give some additional background information and as a complete a view of the design direction I had been envisioning.
Variants
My view of what defines a variant:
In your first example, the product could be the "style".
This is the case we support currently.
"Add Glove liners" is probably not a variant, but an add-on-product (or an upsell).
In the second example, or where "Style" is a variant, the schema and methods support more nesting than the current UI, but this is the way it could work:
My intention was to allow infinite creation of parent->child variants and go as deep as needed.
Just as a matter of priorities, I didn't build a deeper hierarchical variant UI when I built the first variant UI. It's probably a good time to give this whole process another iteration if we want to accommodate more use cases (and test cases). The UI work will be the majority of the effort I think, as little should change in the product or variant methods.
We could add a new action on the child variant ui to allow children to be created.
Likely need to refactor the general option selection to be more user friendly with multiple option paths as well...
Options
For bundling #368 and multiple variants, we could add an
options
array to theProduct
schema. Although I've not thought through the use case for variant options, they could potentially exist on theProductVariant
schema as well.for each template in options we return
options.template
and load a dynamicTemplate with a helper, similar to thereactionApps
helper.It's possible that much of the logic needed could reside in the
products publication
, where we could transform the client products collection to an ideal standard. Client collections don't need to mirror the actual data, so this would be an ideal place to implement additional rules.I've had some discussion and thought about wether
variants
should be it's own collection. I'm still leaning towards a 'rich document' approach where the documents are as self contained as possible.I think we want to have a complete snapshot of the users collection states, at each significant event - and - I want to be able to say "If I show you this product" versus "another version of this product", which did you choose? This product is going to the cart made up just as the user saw it, and that's how it should live through the fulfillment process.
UI Updates
These might be a bit of work to make elegant UX wise, but not really technically complex.
we'd need to create/update templates for
and some updates to product templates
options.template
Metafields
The
product.metafields
are represented as "Details" in the current UI, but they can be, and are intended for reuse, including search, filtering, and variants properties. These productmetafields
are not factored in as variants, butmetafields
exists in variants as well.Handling of
metafields
on the variants hasn't been implemented, it's in the Schema though. I think this is what you are looking for when you mentioned 'custom variables'.However, with your second example it could make sense that
condition
would be another variant. As you mentioned, some additional warehousingmetafields
data is likely going to be needed, so you could clone variant of the original and usemetafields
for that warehousing information (we'd need to adjust inventory as well) - might be a easy UI trick there (split this variant).metafields
on the variant could go partway for #203.But here, I think we could possibly merge the Products and ProductVariants schemas (adding description, options and other "product fields" to variants #203) making them truly identical.
down the roadmap
Thinking further ahead, there a couple features we have on the roadmap to take into consideration as well:
There is a lot here, and I probably missed some big holes - and I may have failed to clearly tie everything together - so bring on the feedback. (and hopefully our next posts can be shorter!)
@spencern commented on Tue May 05 2015
Hopefully this is shorter. Trying to respond to all of the points you bring up:
We agree about what a variant is and most of the nuances around that type.
Is this part of the vision, or the way the schema works currently?
I should have looked at the schema more closely, this is good to know and fits our needs just fine, should make the 'multi-variant' issue trivial to implement.
:+1: Agreed on this point. I've got some ideas that I'll start another issue with.
Product options
I like the idea of adding some type of options array to the product schema. I'm also not sure what the use-case for having options on the variants is.
This seems like it will work well for both bundled products as well as upsell products. I should be able to start working on an implementation for this now.
Are there existing pricing and inventory methods?
You might need to explain a little better how the product publication could be used to implement additional rules for these inventory/pricing methods as I don't think I'm following that idea very well.
It seems as if this direction could help solve #161 downloadable products as well as unforseen future product needs.
UI Updates
All of your UI suggestions make sense, definitely some work to make all of this play nice together, but pretty straightforward.
Using Metafields to store custom product variables seems obvious now that you've mentioned it. Should work well for what we need.
Combining
Product
andProductVariant
SchemasWhen you suggest this, do you mean eliminate one of these entirely? It seems the closer we get towards variants being 'child-products' and having optional children themselves that this might be a good way to simplify. Not sure what all of the implications of this are though.
@aaronjudd commented on Fri Feb 19 2016
Related conversation: see https://github.com/reactioncommerce/reaction/pull/741
@aaronjudd commented on Wed Feb 14 2018
Feature request that requires more definition to meet our current issue guidelines.