Original Message:
Sent: Oct 03, 2025 10:31
From: Matthieu Hattab
Subject: TMF620 v5 - BundledProductOffering v BundledGroupProductOffering
Hi Lutz,
we agree. the possibility to reference the same bundled PO in 2 groups was always going to be a problem, even for the first purchase because 620 user guide (and conformance profile) has no guidance for managing bundled PO cardinalities.
After doing some testing on how configurator consumes 620 and compute a runtime configuration tree, I came up with a few guidelines for our product catalogue implementation
- rule 1: do not use Groups to organise your Bundled Product offerings (=BPO). Groups are logical containers for offers that require "pick N of M" rules across a defined set of child offerings, it's not meant to define a presentation layer, it's meant to control quantities of a group of product offers. anything related to the presentation layer shall be Done in our CMS (product content mode) or using 620's product categories.
- rule 2: Use a single source of truth for BPO cardinalities.
- We recommend to only use [bundle-level] BPO cardinalities* as the authoritative reference as defined with OSS, network and commercial partners.
- You can still define [group-level] BPO cardinalities* but their allowance shall never exceed (below min or above max) [bundle-level] BPO cardinalities*. you need to validate the catalogue.
- ❗validating cardinalities can be very challenging if you use nested sub-groups
- rule 3: Never reference a BPO in more than 1 product group in the bundle:
- you will not be able to modify the bundle later, to change the quantity of the BPO, as the inventory has no knowledge of the product group that contained the BPO when it was first purchased.
* we have 3 locations in the API to specify cardinalities that affect BPOs:
- [group-level] group cardinalities (affect any offer in the group)
- [group-level] BPO cardinalities (affect a specific offer in the group)
- [bundle-level] BPO cardinalities (affect a specific offer in the bundle)
{ "productOffering": { "@type": "ProductOffering", "id": "po-iptv", "bundledGroupProductOffering": [ { "@type": "BundledGroupProductOffering", "id": "grp-wifi-everywhere", "bundledProductOffering": [ { "id": "po-mesh-router", "bundledProductOfferingOption": { "min": 1, "max": 7, "default": 1 } // [group-level] BPO cardinalities for wifi router in this group }, { "id": "po-mesh-point", "bundledProductOfferingOption": { "min": 0, "max": 7, "default": 0 } // [group-level] BPO cardinalities for wifi point in this group } ], "bundledGroupProductOfferingOption": { "min": 1, "max": 7 } // [group-level] group cardinalities } ], "bundledProductOffering": [ { "id": "po-mesh-router", "bundledProductOfferingOption": { "min": 1, "max": 7, "default": 1 }. // [bundle-level] BPO cardinalities }, { "id": "po-mesh-point", "bundledProductOfferingOption": { "min": 0, "max": 7, "default": 0 } // [bundle-level] BPO cardinalities } ] }}
------------------------------
Kind regards,
Matthieu Hattab
Digital Sales Domain Architect
Lyse Tele AS
Original Message:
Sent: Oct 02, 2025 07:30
From: Lutz Bettge
Subject: TMF620 v5 - BundledProductOffering v BundledGroupProductOffering
Matthieu,
you are right, in the so far discussed examples it is not necessary to have the group information in the inventory, but there are cases where you need them.
The problem is the missing step in what you describe as the configurator's tasks:
- retrieves the product bundle from the inventory (what the customer has)
- retrieves the bundle offer definition (including group rules and cardinalities) from the catalogue (what the customer can get)
- links all the elements retrieved from the inventory to the corresponding elements retrieved from the Catalog; only then you can validate which changes are allowed by the catalog
- computes a fresh runtime product configuration (based on the above)
If the 4711 PO is included not only in one selection group, but in two:
productOffering:{ bundledGroupProductOffering: [ { id: 1 name: "first selection group" bundledProductOffering: [ { id=4711 // points to some ProductOffering bundledProductOfferingOption: { min=0, max=1 } }, { id=4712 // points to some other ProductOffering bundledProductOfferingOption: { min=0, max=1 } } ], bundledGroupProductOfferingOption: { min=0, max=1 } }, { id: 2 name: "second selection group" bundledProductOffering: [ { id=4711 // points to the same ProductOffering as included in the first group bundledProductOfferingOption: { min=0, max=1 } }, { id=4713 // points to some other ProductOffering bundledProductOfferingOption: { min=0, max=1 } } ], bundledGroupProductOfferingOption: { min=0, max=1 } } ]}
then you have to know from which of the two selection groups you have chosen the 4711 instance.
In this example, you can choose via the first group 0 or 1 instance of either 4711 or 4712, and you can choose via the second group 0 or 1 instance of either 4711 or 4713.
If in the inventory you find one 4711 instance,
- if it was selected from the first selection group, you cannot add a 4712, but you can add a 4713.
- if it was selected from the second group, you can add a 4712, but you cannot add a 4713.
So you must get the information on the group from the inventory to be able to validate any modification.
------------------------------
Lutz Bettge
Deutsche Telekom AG
Original Message:
Sent: Oct 02, 2025 05:26
From: Matthieu Hattab
Subject: TMF620 v5 - BundledProductOffering v BundledGroupProductOffering
Manu,
In Lutz's example,
id=4711 // points the same ProductOffering bundledProductOfferingOption: { min=3, max=4 }
Your customer could not have ordered 2x 4711. The configurator would have rejected it, since the group-level option enforces a minimum of 3.
There is no need to store group information in the product inventory. Groups exist in the catalogue to declare business rules; the configurator enforces them. You should not store rules in the inventory.
When the customer buys the bundle and selects 4711, those instances are stored in the inventory.
Later, if they want more, they go to My products, click modify on the bundle.
At that point, the configurator:
- retrieves the product bundle from the inventory (what the customer has)
- retrieves the bundle offer definition (including group rules and cardinalities) from the catalogue (what the customer can get)
- computes a fresh runtime product configuration (based on the above)
TMF760 client will then show the product configuration in the UI
- customer will see their existing 4711 instances and will be allowed to add more 4711 (up to 4).
- if customer already has 4x active 4711 instances, UI would not allow to add more or configurator would reject the validation
------------------------------
Kind regards,
Matthieu Hattab
Digital Sales Domain Architect
Lyse Tele AS
Original Message:
Sent: Oct 01, 2025 11:03
From: MMH HH
Subject: TMF620 v5 - BundledProductOffering v BundledGroupProductOffering
Interesting conversation.
@Lutz Bettge Imagine 4711 is mentioned in both direct `bundledProductOffering` as well as `bundledGroupProductOffering` as you gave an example.
productOffering:{ bundledProductOffering: [ { id=4711 // points to some ProductOffering bundledProductOfferingOption: { min=1, max=2 } } ], bundledGroupProductOffering: [ { bundledProductOffering: [ { id=4711 // points the same ProductOffering bundledProductOfferingOption: { min=3, max=4 } } ] } ]}
At the time of order, let's say a customer orders 2 of this PO. However, later, she wants to buy 2 more of these, as per your explanation, it should be allowed. For this to happen, we will need to store the group information in the `customer product inventory` as well. AFAIK, inventory doesn't store the group information in `product` instance. Then how does it work?
------------------------------
Manu
Original Message:
Sent: Sep 30, 2025 11:15
From: Lutz Bettge
Subject: TMF620 v5 - BundledProductOffering v BundledGroupProductOffering
That is a good question, I have to ask a colleague who is involved in the actual product modelling. Will take a while, but I will come back to this as soon as I have an answer.
------------------------------
Lutz Bettge
Deutsche Telekom AG
Original Message:
Sent: Sep 30, 2025 10:36
From: Matthieu Hattab
Subject: TMF620 v5 - BundledProductOffering v BundledGroupProductOffering
hello @Lutz Bettge,
Thank you for sharing this view. I did not expect that.
can you confirm if your suggestion is an implementation choice or a requirement in 620?
because this approach has some concerns.
when we define a bundle, we define allowances (min, max, default) in accordance with OSS rules or commercial agreement with partners.
If they say you can only buy 1 Sport+UHD offer in this bundle, it has to be max=1
- If Sport+UHD appears in 2 groups ("UHD offers, pick 4 out of 10)), (Sport Offers, pick 20 out of 20), I cannot have customer select Sport+UHD 1x in each group because that will make 2 instances of Sport+UHD in my bundle. This is one example of drifting.
- with Sport+UHD, I need to check 2 sets of cardinalities: a global limit per bundle + a local limit per group.
your approach can work, but it comes at extra complexity and risks. It will require good catalogue governance and also making sure that this is well understood by 620 API, product configurator and 760 API and frontend clients
I hope we still have the options to model child offers allowances with bundledProductOffering and/or with bundledGroupProductOffering
------------------------------
Kind regards,
Matthieu Hattab
Digital Sales Domain Architect
Lyse Tele AS
Original Message:
Sent: Sep 30, 2025 06:45
From: Lutz Bettge
Subject: TMF620 v5 - BundledProductOffering v BundledGroupProductOffering
In TMF620, when introducing the BundledGroupProductOffering (the better term would have been BundledProductOfferingGroup), it was decided to keep the direct link between ProductOffering and BundeledProductOffering for reasons of backward compatibility, and also to avoid having to use the Group in simple cases.
So the two structures - linking a BundledPO directly to the PO, or using the Group - are alternatives and should not be mixed together.
For example:
productOffering:{ bundledProductOffering: [ { id=4711 // points to some ProductOffering bundledProductOfferingOption: { min=1, max=2 } } ], bundledGroupProductOffering: [ { bundledProductOffering: [ { id=4711 // points the same ProductOffering bundledProductOfferingOption: { min=3, max=4 } } ] } ]}
means that you can choose between 1 and 2 instances of the 4711 ProductOffering as simple bundledPO, and in addition you can choose between 3 and 4 additional 4711 ProductOfferings via the bundledGroupPO; these two ways are independent of each other!
And in principle, the direct link from ProductOffering to BundledProductOffering is not needed (but simplifies the structure if more complex choices from a group of different things are not needed).
The interplay of the BundledProductOfferingOption and BundledGroupProductOfferingOption can be seen in the following example, showing that there is no risk of drifting inconsistencies of cardinalities:
productOffering:{ bundledGroupProductOffering: [ { bundledProductOffering: [ { id=4711 // points to some ProductOffering bundledProductOfferingOption: { min=2, max=4 } }, { id=4712 // points to some other ProductOffering bundledProductOfferingOption: { min=1, max=2 } } ], bundledGroupProductOfferingOption: { min=2, max=5 } } ]}
This means that you can choose between 2 and 4 instances of the 4711 ProductOffering and between 1 and 2 instances of the 4712 ProductOffering, but in total it must be between 2 and 5 instances of any of the two ProductOfferings.
So if you e.g. choose only one 4712 instance, you have to add at least one 4711 instance,
and if you choose four 4711 instances, you cannot add more than one 4712 instance.
By nesting BundledGroupProductOfferings, with Options on each level, you can formulate very complex restrictions on the number of PO instances you can have.
------------------------------
Lutz Bettge
Deutsche Telekom AG
Original Message:
Sent: Sep 30, 2025 05:41
From: Matthieu Hattab
Subject: TMF620 v5 - BundledProductOffering v BundledGroupProductOffering
@Bostjan Keber
your approach for bundles is what I call the H2: Containment via nested ProductConfiguration[]
I see 2 other patterns for bundles:
- H1: Containment via nested
queryProductConfigurationItem[] - F1: Containment via sibling
queryProductConfigurationItem[] (+ parent relationship on the child ...Item)- this is the IG1228 (Fiber contract) example (with some tweaks that we discussed) you provided in the 760 OAS file
so we have 3 patterns to represent the bundle structure/runtime configuration tree in 760.
And to limit cardinality of individual bundled offerings within a bundle offering, use BundledProductOfferingOption(min/max/defaultnumberofbundledofferings).
I agree. Keep authoring simple (620): set per-child limits once in productOfferingbundledProductOffering{}.
I may suggest :
(if possible) only use a single source of truth for child offers' cardinalities:
- 620:
productOffering.bundledProductOffering.bundledProductOfferingOption{} - 760:
productConfiguration.bundledProductOffering.bundledProductOfferingOption{}
which means, avoid (both 620 and 760) using:
bundledGroupProductOffering.bundledProductOffering.bundledProductOfferingOption{}
- it introduces a risk of drifting when cardinalities are not consistent
- API clients would have to check cardinalities from 2 different nodes
- if you require drifting (say TV Box is max=4 in the bundle but max=2 in a specific group) or want to reference TV Box in 2 different groups, make sure all values are consistent in the catalogue.
------------------------------
Kind regards,
Matthieu Hattab
Digital Sales Domain Architect
Lyse Tele AS
Original Message:
Sent: Sep 29, 2025 09:45
From: Bostjan Keber
Subject: TMF620 v5 - BundledProductOffering v BundledGroupProductOffering
Hi all,
1. Gaps between 620 and 760 API in how they construct bundledProductOffering
- in 760 API, bundled offers cannot exist without a group.
- in 620 API, bundled offers can exist without a group.
I personally disagree with TMF760 approach, you should not force bundled PO to exist in a group. Group are meant to solve a specific problem: "Pick N of M from this set". If you don't have such a business requirement, you should be forced to use a product group.
This, unfortunately, means 760 has to manage synthetic product groups for offers that are not defined in a product group in 620.
You can compose bundled offerings without groups in TMF760. ProductConfiguration is comprised of ProductConfiguration(s) and each configuration points at ProductOffering. ProductOfferingRef is discriminated as ProductOffering or BundledProductOffering (through polymorphism/discriminator introduced with OAS3).
BundledGroupProductOffering is indeed used to model the case when you need to pick N of M budnled offerings from a group.
And to limit cardinality of individual bundled offerings within a bundle offering, use BundledProductOfferingOption(min/max/defaultnumberofbundledofferings).
Hope this helps.
------------------------------
Bostjan Keber
Marand, software ltd
Original Message:
Sent: Sep 23, 2025 09:40
From: Matthieu Hattab
Subject: TMF620 v5 - BundledProductOffering v BundledGroupProductOffering
It's a good thing that this old discussion surfaces again. After playing a lot with the 620 and 760 APIs lately and had some conversations the author of the 760 API, I came to these recommendations and clarifications
1. Gaps between 620 and 760 API in how they construct bundledProductOffering
- in 760 API, bundled offers cannot exist without a group.
- in 620 API, bundled offers can exist without a group.
I personally disagree with TMF760 approach, you should not force bundled PO to exist in a group. Group are meant to solve a specific problem: "Pick N of M from this set". If you don't have such a business requirement, you should be forced to use a product group.
This, unfortunately, means 760 has to manage synthetic product groups for offers that are not defined in a product group in 620.
2. bundledGroupProductOfferingOption vs bundledProductOffering[*]
They are not competing with each other. Both must be used in TMF620 because they serve different purposes:
bundledGroupProductOfferingOption[*] → solves one commercial capability: "Pick N of M from this set" with group-level cardinality (and optional default, i.e. Pick up to 3 Channel Packages of ouf these 10 channel Packages from the "Sport Channel package" product group).
bundledProductOffering[*] → is the authoritative child list, (= BOM, i.e. bill of material) where each child has its own bundledProductOfferingOption with per-child cardinalities and defaults (numberRelOfferLowerLimit, numberRelOfferUpperLimit, numberRelOfferDefault which are more relevant that per group cardinalities.
- Quote/cart/order, order management, provisioning do not care about
bundledGroupProductOfferingOption, nor recognise product groups
If you drop bundledProductOffering[*], you lose:
The per-child min/max/default, which are only present on child entries.
A single source of truth if a child belongs to multiple groups.
A clean mapping to TMF760, which expects {min,max,default} on each child under a group.
Based on this analysis and testing, my above conclusion is very different than Lutz's last comment:
And yes, also having an array of BundledProductOfferings is for backward compatibility, and can still be used for the simpler cases where you do not need the complexity of the Group.
It is not for backward compatibility. I actually now recommend:
Always publish bundledProductOffering[] on the parent PO.
Optionally publish bundledGroupProductOfferingOption[]
Keep them consistent: bundledGroupProductOfferingOption[] for group structure and defaults, bundledProductOffering[] for per-child limits.
------------------------------
Kind regards,
Matthieu Hattab
Digital Sales Domain Architect
Lyse Tele AS
Original Message:
Sent: Oct 20, 2023 11:05
From: Lutz Bettge
Subject: TMF620 v5 - BundledProductOffering v BundledGroupProductOffering
Hi Andrew,
let me try to explain:
You are right, the JSON example is incorrect, the bundledGroupProductOfferingOption is not directly an attribute of the ProductOffering; as in the OAS file and the diagram, the ProductOffering has an array of BundledGroupProductOfferings. Such a Group is a collection of BundledProductOfferings, and it can have a Option that defines how many instances of the BundledProdictOfferings you may choose in total. On the individual BundledProductOfferings contained in the group, you can also have an Option that defines how many instances you can have from that offering. And to make it even more flexible, you can have a tree structure of Groups, with Options on all levels, so that you can build very complex options for selection.
Putting the "Routers" and "Gifts" in the same Group as in your example would mean that the customer can choose between them, and get exactly one Router and optionally (up to) one Gift; but for that you would not need the Group, just attach the BundledProductOffering directly to the Top-Level productOffering, with corresponding BundledProductOfferingOptions. But you if want to let your customer choose between two different types of Gifts, and he can have zero to two in total, but only one of Type A and up to two of Type B, you can express that by setting up:
ProductOffering: Consumer Broadband (isBundle=true)
bundledProductOffering [ 1: { name=Router, bundledProductOfferingOption { numberRelOfferLowerLimit=1, numberRelOfferUpperLimit=1 } ] // you get exactly 1 Router
bundledGroupProductOffering [ // you can choose ...
1: {
name=Gifts,
bundledGroupProductOfferingOption { numberRelOfferLowerLimit=0, numberRelOfferUpperLimit=2 }, // between 0 and 2 in total
bundledProductOffering [
{ name=GiftTypeA, bundledProductOfferingOption { numberRelOfferLowerLimit=0, numberRelOfferUpperLimit=1 }, // one may be of type A
{ name=GiftTypeB, bundledProductOfferingOption { numberRelOfferLowerLimit=0, numberRelOfferUpperLimit=2 }, // up to 2 may be of type B
]
]
And yes, also having an array of BundledProductOfferings is for backward compatibility, and can still be used for the simpler cases where you do not need the complexity of the Group.
Does this make sense to you?
------------------------------
Lutz Bettge
Deutsche Telekom AG
Original Message:
Sent: Oct 19, 2023 10:05
From: Andrew Torrance
Subject: TMF620 v5 - BundledProductOffering v BundledGroupProductOffering
I am looking at the version 5 TMF620 and pleased to find the 'Selection Group' problem has been solved.
However I am struggling with some of the options given for definitions.
I believe I understand the basic premise, e.g. if my "Consumer Broadband" consists of
ProductOffering: Consumer Broadband (isBundle=true)
BundledGroupProductOfferingOption
1: { name=Routers , numberRelOfferLowerLimit=1, numberRelOfferUpperLimit=1, productOffering: [ ... some routers .. ] }
2: { name=Gifts , numberRelOfferLowerLimit=0, numberRelOfferUpperLimit=1,, productOffering: [ ... some gifts.. ] }
I can see how things like Speed can go in here, though at some point you are looking at it really being a different Offering altogether (if the customer ends up with a different item, for a different price, is it really the same thing? But that's down to the data going in.
This is extremely close to something we implemented internally, albeit with different key names. Migrating should be straightforward.
However, in JSON Examples in TMF620 document, on page 62, the bundledGroupProductOfferingOption array attribute is directly beneath productOffering
But in the swaggerfile itself, the productOffering has bundledGroupProductOffering (with a name) which in turn has bundledGroupProductOfferingOption (an object with the lower, upper and array of the Offerings actually in the group).
In situations like this, which is definitive?
Second, what I think is my more conceptual misunderstanding, is the purpose of "bundledProductOffering" - which features in many places, but is left empty in all the JSON examples.
I assume the 'top level' bundledProductOffering is for when the offering is an older (pre v5) style bundle whereby the ProductOffering consists of multiple things stuck together. This is of less interest to implement for us as most 'bundles' will have some degree of flex.
Where I get completely lost is the attribute bundledProductOffering within bundledGroupProductOffering - is there a documented use cases envisaged for this, or is it just residue from subclassing?
What does it mean to populate bundledGroupProductOffering.bundledProductOffering and not just bundledProductOffering directly? Have others used this for a specific case?
The description "Child offerings, from which instances can be created as direct or hierarchically indirect children of the parent offering." is not leaving me any wiser.
------------------------------
Andrew Torrance
Cerillion Technologies Limited
------------------------------