Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allow sharing of Product Variant relationships across the network #150

Open
RaggedStaff opened this issue Oct 10, 2024 · 21 comments
Open

Allow sharing of Product Variant relationships across the network #150

RaggedStaff opened this issue Oct 10, 2024 · 21 comments
Assignees

Comments

@RaggedStaff
Copy link
Contributor

For one of our current pilots, we urgently need to facilitate the sharing of Product>Variant links across the network.

How do we do this?

Do we use TransformationFlow logic to link a SuppliedProduct to another?

Should we do something else ? Add a new relationship (isVariant)?

This is urgent & FDC can fund this work.

@mkllnk
Copy link

mkllnk commented Oct 10, 2024

The Open Food Network is planning for products be associated in a product group. We mainly want to group products/variants in the shopfront.

Our thinking:

  • Product groups are optional. Not all products are related to others as variants.
  • Defining relationships only between the variants is not feasible. If you have 100 variants for the same product then each variant would need to point to 99 other variants. That's a fair bit of duplication as well and difficult to maintain.

But what's the purpose in your case?

There could be one wholesale product, for example a pig. And then that's cut up in transformations.

@olivier5741
Copy link

Hi @mkllnk , in OFN will you have three concepts : product group, product and variant or just product group and product ?

In my model, I'm only using product and product group concepts (an OFN variant is a product and an OFN product is a product group). A product is what corresponds to a GTIN.

The question for me is whether a product can be in several product groups or not ? So far in my model a product can only be in one product group. I consider that product groups are linked to the transformation line.

If you want to group products together like in a cash register or an online shop, in my model you create a dedicated classification (with categories, complex hierarchy is accepted) and you add the categories to the reference of that product. So DFC product categories, GPC, Google categories can be directly assigned to the product. In house categories can only be assigned to the reference you hold of that product.

@mkllnk
Copy link

mkllnk commented Oct 17, 2024

in OFN will you have three concepts : product group, product and variant or just product group and product ?

Just two concepts: product and product group. Same relationship as in your model.

That's the plan so far. In our DFC API, the Spree::Variant is the same as a DFC SuppliedProduct. Now the question is if the DFC creates a product group which would represent our Spree::Product or if we find a different model. 🤷

@RaggedStaff
Copy link
Contributor Author

RaggedStaff commented Oct 17, 2024

Ok. Following on from the Ontology meeting, here is the draft proposal:

Variants in DFC Standard

  1. We will add 2 relationships to DefinedProduct : hasVariant and the inverse hasMaster isVariantOf (DefinedProduct properties are then inherited by FunctionalProduct, TechnicalProduct & SuppliedProduct)
  2. These are mutually exclusive (i.e. a DefinedProduct can only be a Variant or a Master Product, not both), so we will not allow nesting of Variants Products within Variant Products.
  3. A Variant Product will inherit properties from the Master Product, except where they are explicitly defined in the Variant Product
  4. We will specify in the client-to-client specification the properties that are required for Master Products vs Variants:

Master Product

Variant Product

  1. Master Products MUST NOT include (these properties must be defined on the Variant Product):
  • dfc-b:consumedBy
  • dfc-b:hasQuantity
  • dfc-b:produces
  • dfc-b:producedBy
  • dfc-b:totalTheoreticalStock
  1. Variant Products MUST NOT include (if present, these properties SHOULD be defined on the Master Product):
  • dfc-b:description
  • dfc-b:availabilityTime
  • dfc-b:deliveryCondition
  • dfc-b:frozen
  • dfc-b:hasBrand
  • dfc-b:hasCertification
  • dfc-b:hasCharacteristic
  • dfc-b:hasClaim
  • dfc-b:hasContainerInformation
  • dfc-b:hasGeographicalOrigin
  • dfc-b:hasIngredient
  • dfc-b:hasLabellingCharacteristic
  • dfc-b:hasNatureOrigin
  • dfc-b:hasNutrientCharacteristic
  • dfc-b:hasPartOrigin
  • dfc-b:hasPhysicalCharacteristic
  • dfc-b:hasTemperature
  • dfc-b:hasType
  • dfc-b:hasPercentageOfAlcoholByVolume
  • dfc-b:image
  • dfc-b:lifetime
  • dfc-b:refrigerated
  • dfc-b:specificCondition
  • dfc-b:suppliedBy
  • dfc-b:URL

Please provide feedback by 24th Oct 13:00 UTC.

Ping @datafoodconsortium/ontology-maintainers

@lecoqlibre
Copy link
Member

Thanks @RaggedStaff.

Two remarks so far:

  • Perhaps the inverse relationship should be named isVariantOf?
  • About the C2C spec, perhaps it would be easier to define the properties that MUST and the ones that COULD be included rather than the ones that must not?

@olivier5741
Copy link

Just wondering, in DFC, is a FunctionalProduct not a product group then ?

  • FunctionalProduct -> Wheat Flour from a specific farm
  • SuppliedProduct -> A 2kg wheat flour bag, packaged in paper from a specific farm with GTIN 0054...

@RaggedStaff
Copy link
Contributor Author

* Perhaps the inverse relationship should be named `isVariantOf`?

I was thinking of that initially, but I think it would be preferable to have the Master>Variant Product relationship we're introducing here at least referenced somewhere in the ontology. I don't have a strong preference either way.

* About the C2C spec, perhaps it would be easier to define the properties that MUST and the ones that COULD be included rather than the ones that must not?

I guess, I was just thinking that there aren't many required properties within the ontology (I think for SuppliedProduct, in this instance it would be Id, suppliedBy & hasVariant/hasMaster), so figured it was better (simpler/quicker) to list the exclusions, also less ambiguous.

@RaggedStaff
Copy link
Contributor Author

Just wondering, in DFC, is a FunctionalProduct not a product group then ?

* FunctionalProduct -> Wheat Flour from a specific farm

* SuppliedProduct -> A 2kg wheat flour bag, packaged in paper from a specific farm with GTIN 0054...

That is a possible interpretation of the DefinedProduct hierarchy, but it actually aligns to Asks/Offers :

  • The Customer requests a FunctionalProduct
  • Suppliers propose TechnicalProducts (which satisfies the FunctionalProduct requirement)
  • The Customer then contracts for a SuppliedProduct which is suppleid by the chosen Supplier.

@lecoqlibre
Copy link
Member

lecoqlibre commented Oct 17, 2024

Good point @olivier5741!

I agree with @RaggedStaff, considering you example I would rather say that:

  • FunctionalProduct > Wheat Flour.
  • TechnicalProduct > Wheat flour of a specific variety.
  • SuppliedProduct > Wheat flour of a specific variety from producer A.

We discussed about this option today at our ontology meeting. We also discussed about another idea involving the TransformationLoop (AsPlannedTransformation).

I was in favor to use the product hierarchy to express variants as I thought it can be used for it and and so it does not require to introduce something new. Although after discussing with Baptiste and Garethe I'm not so sure anymore. The discussion of today was very interesting but we did not find a clear argument to eliminate the product hierarchy solution so we decided that we need to continue investigating on this (*).

Let's take an example with T-shirt. Using the product hierarchy solution we could have something like:

  • T-shirt (FunctionalProduct)
    • Blue T-shirt (TechnicalProduct)
      • Blue T-shirt from producer A - Small size variant (SuppliedProduct)
      • Blue T-shirt from producer A - Medium size variant (SuppliedProduct)
      • Blue T-shirt from producer A - Large size variant (SuppliedProduct)
      • Blue T-shirt from producer B - Small size variant (SuppliedProduct)

In order to get the variants of a particular SuppliedProduct we would have to get all the products linked to its TechnicalProduct and take only those made by the same producer (Enterprise). Otherwise, we would mix products of different producers and get for example the "Blue T-shirt from producer B - Small size variant" when listing the variants of let's say the "Blue T-shirt from producer A - Small size variant". But that may even be a valid/useful use case?

We are searching for ideas or inspirations from other existing systems about this "variant" feature. Feel free to list some.

(*) We planned a special meeting on this subject with me and Baptiste next Tuesday at 10AM CET. Note that anybody can also join the regular ontology meeting that takes place every two Thursday at 3PM CET.

@mkllnk
Copy link

mkllnk commented Oct 17, 2024

hasMaster

I would prefer to avoid the term master and its potential to offend people. When learning the terminology, I would also find it helpful to see a matching pair of verbs like hasVariant and isVariantOf.

A Variant Product will inherit properties from the Master Product

We have a similar data model in OFN and I find inherited properties a pain to work with in development. You either load the masters and variants and then filter in the app code or you need to join tables and select fields with a conditional ifnull.

These are mutually exclusive

Sounds complicated. When I have a full product and then add hasVariant to it, it suddenly becomes invalid. I also need to remove some properties and move them to the variant.

We basically have three different versions of a product then: full product, master/template product, variant product. If you want to go down this path, would it make sense to create new semantic types for these? And is that needed to write a validation schema for this?

What data needs to be shared via the master product in your use case?

I'm skeptical about this direction but I understand that you are solving an urgent issue, trusting that you find the best solution.

@Alcoz
Copy link
Collaborator

Alcoz commented Oct 23, 2024

Regarding the problem of variant description, I looked at difference resources, and I would propose to represent variants with specific concepts. In my opinion, it would be better to keep the different types of products for business operations (demand, offer, logistics). I propose to create for each product a list of options (i.e., size, color) and a list of values for the options (i.e., M, L, blue, red), then to create a variant of the product and link the specific variant characteristic to the options (schema below).

Variant drawio

This pattern allows to have a list of option reference reusable with different products and it keeps the description of product away from the business description as we done with the facets.

@RaggedStaff regarding your proposition, I am not fully ok with the properties that SHOULD not be on the variant, how to be sure that some properties should be different (i.e, image, description, URL).

@RaggedStaff
Copy link
Contributor Author

Hi @Alcoz,

Thanks, this looks really interesting... and like a breaking change! 😉

I looked at difference resources, and I would propose to represent variants with specific concepts.

Could you share some links to the resources you looked at? I'm curious what else is out there & too lazy to do my own digging! 😜

In my opinion, it would be better to keep the different types of products for business operations (demand, offer, logistics).

I'm not sure I quite understand what you mean here. 🤔 Are you referring to the Functional/Technical/Supplied/Localized/Physical Product progression ? If it's something else, could you elaborate please ? 🙏🏻

I propose to create for each product a list of options (i.e., size, color) and a list of values for the options (i.e., M, L, blue, red), then to create a variant of the product and link the specific variant characteristic to the options (schema below).

Variant drawio

Nice! 😎 Option does make sense for Variants in general and I think a lot of producers may be able to normalise pack sizes as you suggest. Although, as I mentioned on the call, we're not really dealing with garment size masks in short foodchain systems... the variants are a bit messier: 1 steak or 2, a 100ml bottle or a 400ml bottle. I can't think of an applicable example that would need more than 1 dimension of options, can anyone else? 🤔

In fact, I'm struggling to think of Option being anything other than Units, so do we need a new concept for that?

This pattern allows to have a list of option reference reusable with different products and it keeps the description of product away from the business description as we done with the facets.

I don't understand what you mean by this. What "business description" are we trying to separate from the Product description, and why ?

I'm thinking of Shopify particularly... they use Product.Name to search/apply categories e.g. "Organic" so if a store has a mix of Organic & non-Organic products, they often put the word "Organic" in the Product Name, to allow for search/categorisation by the platform.

@RaggedStaff regarding your proposition, I am not fully ok with the properties that SHOULD not be on the variant, how to be sure that some properties should be different (i.e, image, description, URL).

Ok, although is that still relevant now? Aren't we creating a separate class for Variant? Or do you want to agree what attributes to put where ? 😕

@mkllnk
Copy link

mkllnk commented Oct 25, 2024

I can't think of an applicable example that would need more than 1 dimension of options, can anyone else?

Not sure.
In OFN the dimension was fixed across variants of a product. Spree called it variant_unit like weight and variant_unit_scale like 1 for gram and 1000 for kilogram or variant_unit_name for items, bunches, bottles etc. But there may be a case for selling apples individually or in 2kg bags. And we changed our data model to hold the unit in the variant now. So in theory, OFN could support mixed scales. But our UI doesn't allow it yet.

And I don't see that limit in the proposed option model. The product can reference any option, right?

Before this proposal I assumed that we would translate that to transformations like in the FDC pilots which would allow for different units. So once we have these variants, would we re-implement the retail-wholesale quantity logic to work with variants instead?

I'm struggling to think of Option being anything other than Units, so do we need a new concept for that?

OFN users are creative with variants. For example, they sell jam and the variants are strawberry jam, plum jam and raspberry jam. We like to group them in the shopfront, hence our concept of a product group. But in terms of transformations, they are made from completely different produce, unless you specify the product as fruit with the type of fruit being a variant option...

Limiting the scope of the options to units may be an opportunity to prevent too creative uses that aren't compatible with other platforms... but it may also limit integration with different platforms. This is tricky.

@Alcoz
Copy link
Collaborator

Alcoz commented Oct 25, 2024

@RaggedStaff

Could you share some links to the resources you looked at? I'm curious what else is out there & too lazy to do my own digging! 😜

I also find an ontology but it seems very complicated. https://industryportal.enit.fr/ontologies/PRONTO?p=summary

I'm not sure I quite understand what you mean here. 🤔 Are you referring to the Functional/Technical/Supplied/Localized/Physical Product progression ? If it's something else, could you elaborate please ? 🙏🏻

Yes, I'm referring to the different products progression

I don't understand what you mean by this. What "business description" are we trying to separate from the Product description, and why ?

By business description, I mean the product progression. What I want to tell is I would prefer to not use Technical/Supplied product to describe variants.

Ok, although is that still relevant now? Aren't we creating a separate class for Variant? Or do you want to agree what attributes to put where ? 😕

It is still relevant because Variant is a subclass of a DefinedProduct in my design pattern so they share the same properties. Like @mkllnk said, users are creative and it is difficult to know the properties that will be used at product level and at variant level.

@mkllnk

And I don't see that limit in the proposed option model. The product can reference any option, right?

Yes, the idea is to let the user have the number of reference options he wants and use them for his variants. However, maybe we should prevent the user to create, for one Variant, different VariantCaracteristic for the same Option.

@RaggedStaff
Copy link
Contributor Author

Few things I'm noticing here:

The google example given, doesn't have a Variant Class, it uses a ProductGroup class to hold variant Products.

Other examples you point to bring in SKU's, which are highly relevant to variant logic (you cannot hold a variant without an explicit Stock Keeping Unit to manage it's stock). Noticing that DFC hold SKU on CatalogItem, which makes me wonder: how does the relationship to CatalogItem from the Variants differ from other DefinedProducts (if at all) ?

However, maybe we should prevent the user to create, for one Variant, different VariantCaracteristic for the same Option.

It seems to me that we're using VaraintCharacteristics as a resolution entity to allow us to (potentially) hold multiple options in a single variant, without enforcing an upper or lower limit. In which case I think this definitely makes sense: I could have my wine in 375ml & 750ml bottles, but I can't sell them both as the same Variant.

@Alcoz - I'm curious if you see any way to push this change without it being a breaking change ?

Could there be a way to incorporate a limited change (e.g. just using the hasVariant/isVariantOf relationships) that would allow us to pass variant relationships without substantial changes to the Product model ? 🤔

@Alcoz
Copy link
Collaborator

Alcoz commented Oct 30, 2024

The google example given, doesn't have a Variant Class, it uses a ProductGroup class to hold variant Products.

As I understand, ProductGroup is DefinedProduct and Product is Variant.

Other examples you point to bring in SKU's, which are highly relevant to variant logic (you cannot hold a variant without an explicit Stock Keeping Unit to manage it's stock). Noticing that DFC hold SKU on CatalogItem, which makes me wonder: how does the relationship to CatalogItem from the Variants differ from other DefinedProducts (if at all) ?

Do it has to differ ? To know if your CatalogItem is linked to a DefinedProduct or a Variant, you have to check its class.

It seems to me that we're using VaraintCharacteristics as a resolution entity to allow us to (potentially) hold multiple options in a single variant, without enforcing an upper or lower limit. In which case I think this definitely makes sense: I could have my wine in 375ml & 750ml bottles, but I can't sell them both as the same Variant.

The Variant could have multiple VariantCaracteristics linked to the option that it describes (ex, the size of the bottle) and the value (ex, 375m). At the end, to represent your exemple, you have 2 variant with one variant caracteristic, each link with one option value (bottle 1 : 375, bottle 2: 750)

@RaggedStaff Yes, I think we can import a minimalist version with hasVariant/isVariantOf. The user would have to create manually each variant independantly (like in the google example). And, to know if the product is a variant or not, the user has to check the placement of the product (Does my product is the domain or range of hasVariant ?)

@RaggedStaff
Copy link
Contributor Author

Further discussion on this:

  1. Variant class needs to be any subclass of DefinedProduct (e.g. SuppliedProduct, TechnicalProduct, FunctionalProduct). @Alcoz to figure this out.

  2. We are explicitly excluding Variant logic from LocalizedProduct and PhysicalProduct.

@RaggedStaff
Copy link
Contributor Author

For v1.15.0 @Alcoz will add isVariantof & hasVariant to DefinedProduct

@mkllnk
Copy link

mkllnk commented Jan 23, 2025

The standard probably doesn't care but I'm wondering where and how I'll publish this on the API. We currently have catalog_items/id5 and supplied_products/id6. So we could do have a semantic id ending in product_groups/id7 or technical_products/id7.

Is there any best practice for organising the API namespace?

@mkllnk
Copy link

mkllnk commented Jan 24, 2025

I noticed that these relationships are many-to-many. In the Open Food Network, it will be a one product group (TechnicalProduct) to many variants (SuppliedProduct) relationship.

But I guess that there are valid use cases for many-to-many. For example, I may say almonds in different forms: raw, roasted, flaked, ground and as almond butter. In parallel I could also sell some roasted nuts with different variants: almonds, cashews, peanuts etc. In this example, the roasted almonds are the variant of two other products.

How do we map that in OFN? I think that I'll just assume one group to start with.

Otherwise, one idea would be to create a broader product. We could name it "Almonds & Roasted nuts". It's linked to both groups. And when you create a variant in OFN through the DFC API then the variant is attached to a product which is linked to at least one group of the variant. But that can be ambiguous, too. If I first import raw almonds then it creates the product almonds as group/parent product. If I then import roasted cashews, it creates the roasted nuts product group. If I then import the roasted almonds, they could go in either category but OFN doesn't allow them to go in both.

In that example, it's just as good to assume only one product group and choose the first in the graph. Roasted almonds would still only go into the almond category and not into roasted nuts. We would avoid a third category "Almonds & Roasted nuts" which is good, I think. At least then we have a one-to-one relationship between OFN parent products and other DFC parent products.

@RaggedStaff
Copy link
Contributor Author

The standard probably doesn't care but I'm wondering where and how I'll publish this on the API. We currently have catalog_items/id5 and supplied_products/id6. So we could do have a semantic id ending in product_groups/id7 or technical_products/id7.

For now, my understanding is we're just adding an additional property to SuppliedProduct. The new class etc will be a v2 change. @Alcoz @lecoqlibre - does that match your understanding?

Is there any best practice for organising the API namespace?

I think that would come under the work @lecoqlibre is doing. Do you have anything in draft you could share Maxime ?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
Status: Todo
Development

No branches or pull requests

5 participants