Marketplaces / Tesco (on Marketplacer) / Tesco Technical Scope / Tesco Product Management / Tesco Product Update

Tesco Product Update

Version Date Created / Updated Notes
v1.0 Hristiyan Georgiev Initial version
v1.1 12/05/2025 Hristiyan Georgiev Mapping changes
v1.2 21/05/2025 Hristiyan Georgiev Additional mapping changes

When we are talking about product updates on Tesco we need to distinguish them by two flows : Advert(product) updates and Variant updates :

  • Advert updates: These encompass general product information such as description, title, product features, and dimensions. The tricky part is that an advert update can include variants, making it essentially a full update.
  • Variant updates: These pertain to specific product variations, allowing updates to price and quantity. These updates are used for stock and price changes, which are explained in separate pages.

As advised above, in this page we will only look for the advert updates which can be considered full updates on our end.

Protect flags handle :

The good thing in GraphQL is that we do not need to block any communication but rather we can exclude fields that we don’t want to update.

  • Protect the whole item - This field blocks all content updates for the relevant product to the marketplace except for Stock & Price update. GraphQL allows us to only update the stock & price in a single “full” update call, but it will be misleading for the end user and if we have this flag, we want to skip the update and leave the List/Update the whole item on Pending.
  • Protect Price - This means we include everything except the price and salePrice fields in our variables payload.
  • Protect Stock - This means we include everything except countOnHand field in our variables payload.

API Docs : https://api.marketplacer.com/docs/seller-api/examples/products/howto_addproducts_latest/#updating-adverts-and-variants

All triggers, validations except the protect flags mentioned above, are as per the listing abstraction for product update - Product Listing general requirements. <v1.2> We also want to add an additional trigger on top of the abstraction, and this is Listing > Product Status = Product Created <v1.2>

<v1.2>GraphQL Query</v1.2> :

mutation AdvertUpdate($input: AdvertUpsertMutationInput!) {
    advertUpsert(input: $input) {
        advert {
              id           
          statusText
          displayable         
          catalogRulesErrors{
                        errorMessage
                        fieldName
                        objectId                        
                    }
            legacyId        
            variants(displayableOnly: false)
            {
                nodes {
                    sku
                    id
                    displayable

                }
            }          
            }

        errors {
            field
            messages
        }
    }
}

Query Variables :

{
    "input": {
      "advertId": "QWR2ZXJ0LTEwMDA5NTcwNg==",
      "attributes": {
        "brandId": "QnJhbmQtNA==",
        "taxonId": "VGF4b24tMjgw",
        "title": "Noviq TESTIKO NO QTY Puuuut6",
        "description": "Test test test. Shetst Shets!",
        "productFeatures": ["Super Best, Very Good", "Amazin' Feature2", "the best feature3"],
        "shippingParcelAttributes": {
          "weight": 100,
          "massUnit": "g",
          "length": 5,
          "width": 6,
          "depth": 15,
          "distanceUnit": "cm"
        },
        "saleType": "BUY_ONLINE",
        "attemptAutoPublish": true,
        "images": [
          {
            "sourceUrl": "https://images.puma.net/images/398352/03/fnd/GBR/"
          },
          {
            "sourceUrl": "https://images.puma.net/images/398672/02/sv01/fnd/GBR/"
          },
          {
            "sourceUrl": "https://images.puma.net/images/398672/02/sv02/fnd/GBR/"
          }
        ],
        "advertOptionValues": [
          {
            "optionValueId": "T3B0aW9uVmFsdWUtNzM0"
          },
          {
            "optionValueId": "T3B0aW9uVmFsdWUtNzI4"
          },
          {
            "optionValueId": "T3B0aW9uVmFsdWUtNzI5"
          },
          {
            "optionTypeId": "T3B0aW9uVHlwZS0yNTA=",
            "textValue": "asdasda"
          }
        ],

        "variants": [
          {
            "id": "VmFyaWFudC0xMDU2NDI=",
            "description": "Its amazing!",
            "sku": "1234561",
            "barcode": "6723827005389",
            "price": "99",
            "salePrice": "98",
            "countOnHand": 110,
            "images": [
              {
                "sourceUrl": "https://images.puma.net/images/935520/01/fnd/GBR/"
              },
              {
                "sourceUrl": "https://images.puma.net/images/935520/01/bv/fnd/GBR/"
              },
              {
                "sourceUrl": "https://images.puma.net/images/935520/01/mod02/fnd/GBR/"
              }
            ],
            "variantOptionValues": [
              {
                "optionValueId": "T3B0aW9uVmFsdWUtNzMy"
              },
              {
                "optionValueId": "T3B0aW9uVmFsdWUtNzIz"
              },
              {
                "optionValueId": "T3B0aW9uVmFsdWUtNzI0"
              },
              {
                "optionTypeId": "T3B0aW9uVHlwZS0yNTI=",
                "textValue": "Very not cool Color"
              }
            ]
          },
          {
            "id": "VmFyaWFudC0xMDU2MzU=",
            "description": "Its amazing!",
            "sku": "6543211",
            "price": "99",
            "salePrice": "55",
            "countOnHand": 10,
            "images": [
              {
                "sourceUrl": "https://images.puma.net/images/398352/03/fnd/GBR/"
              }
            ],
            "variantOptionValues": [
              {
                "optionValueId": "T3B0aW9uVmFsdWUtNzMx"
              },
              {
                "optionValueId": "T3B0aW9uVmFsdWUtNzIz"
              },
              {
                "optionValueId": "T3B0aW9uVmFsdWUtNzI0"
              },
              {
                "optionTypeId": "T3B0aW9uVHlwZS0yNTI=", "textValue": "Very not cool Color"
              }
            ]
          }
        ]
      }
    }
  }

Variables mapping :

Tesco Field Integration Requried Hemi Mapping Hemi Notes
input
advertId Yes Product Account > Channel Item ID
attributes
brandId Yes Product > Brand

OR Product Account > Item Specifics | Product is with priority. We need to send the Id of the brand as per the taxonomy. | | | taxonId | | | Yes | Product Account > Primary Category ID | We need to send the Id of the category | | | title | | | Yes | Product Account > Title | Since we keep this info on Product Account level, we might have a case where we have a variation and we have different titles across the variations. In the case we have more than one product selectefd for update, we want to pick the Proudct Account with the lowest ID and use its title. | | | description | | | Yes | Product Account > Description | | | | productFeatures | | | No | Product Account Tesco > Product Features | New field! This should be a field with the possibility to “add more features”. Similar to the Item/Variation specifics fields. The only difference is that here we will have only one box for input instead of two. Then each row needs to be separated by comma in the payload. | | | shippingParcelAttributes | | | | | | | | | weight | | Conditional | Product > Weight | We need to send this together with massUnit. If we are not sending weight, we need to exclude massUnit from the payload | | | | massUnit | | Conditional | | Hardcoded as “g” . We only need to send it when sending weight | | | | length | | Conditional | Product > Length | We need to send either all 3 of length, width and depth or none of them. | | | | width | | Conditional | Product > Width | We need to send either all 3 of length, width and depth or none of them. | | | | depth | | Conditional | Product > Height | We need to send either all 3 of length, width and depth or none of them.. | | | | distanceUnit | | Conditional | | Hardcoded as ‘cm’ . We want to exclude this if we are not sending any measurements. | | | saleType | | | No | Product Account Tesco > Sale Type | New field! Should be an enumeration dropdown with the following options :

  • Buy Online sent as BUY_ONLINE
  • Buy Online & Click and Collect sent as BUY_ONLINE_OR_CLICK_AND_COLLECT
  • Click and Collect sent as CLICK_AND_COLLECT Our default option should be empty and if we have empty option, we send BUY_ONLINE as default when creating products. | | | attemptAutoPublish | | | No | Product Account Tesco > Auto Publish | New field. Should be a radio button with options “Yes” and “No”. When Yes is selected we send true When No is selected we send false Default option should be “Yes” | | | images | | | | | | | | | sourceUrl | | Yes | (2) Main Image(s), (1) Listing Image AND (3) More Images | As per the images abstraction - Images Handling Additional Explanation | | | advertOptionValues | | | | | | | | | optionValueId | | Yes | Product Account > Item Specifics | We need to send the ID corresponding to the item specific name | | | | optionTypeId | | No | Product Account > Item Specifics | We need to send the ID corresponding to the item specific name. We only need to send this if we have FREE_TEXT field type in the taxonomy | | | | textValue | | Conditional | Product Account > Item Specifics Value | This becomes required if we are sending optionTypeId | | | variants | | | | | | | | | id | | Yes | Product Account Tesco > Variant ID | | | | | description | | No | Product Account > Description | | | | | sku | | No | Product > SKU | | | | | barcode | | No | Product Account > Marketplace EAN OR Product > EAN OR Product > Barcode OR Product > MPN OR Product >UPC | Product Account is with priority. The priority in the other fields is : EAN, Barcode, MPN, UPC | | | | price | | No | Product Account > RRP | This must be excluded if we have Protect Price = Yes | | | | salePrice | | No | Product Account > Price | This must be excluded if we have Protect Price = Yes | | | | countOnHand | | No | Product Account > Quantity | This must be excluded if we have Protect Quantity = Yes | | | | images | | | | | | | | | sourceUrl | No | (2) Main Image | We want to have a logic and only send the Main image for the specific variant Images Handling Additional Explanation | | | | variantOptionValues | | | | | | | | | optionValueId | Yes | Product Account > Variation Specifics | | | | | | optionTypeId | No | Product Account > Variation Specifics | | | | | | textValue | Conditional | Product Account > Variation Specifics Value | This becomes required if we are sending optionTypeId |

<v1.2>Example response :

{
    "data": {
        "advertUpsert": {
            "advert": {
                "id": "QWR2ZXJ0LTEwMDEwMjIwMg==",
                "statusText": "Invalid",
                "displayable": false,
                "catalogRulesErrors": [
                    {
                        "errorMessage": "Product description must be greater than 10 characters",
                        "fieldName": "description",
                        "objectId": "26533820"
                    }
                ],
                "legacyId": 100102202,
                "variants": {
                    "nodes": [
                        {
                            "sku": "321123",
                            "id": "VmFyaWFudC0xMzA3NTQ=",
                            "displayable": true
                        },
                        {
                            "sku": "1234561",
                            "id": "VmFyaWFudC0xMzA3NTM=",
                            "displayable": true
                        }
                    ]
                }
            },
            "errors": null
        }
    }
}

<v1.1>Response Mapping :

Integration Field McPro Field Notes
data
advertUpsert
advert
id We want to use this id to map with Product Account > Channel Item ID and find which product we need to store the error into.
<v1.2> statusText N/A
displayable Based on this we want to update the Listings > Product Status :

If we have displayable = true, we set the status to Product Published If we have displayable = false, we leave the status as it is </v1.2> | | | | | catalogRulesErrors | | | | | | | | | | errorMessage | | Product Account > Update item error | | | | | | | fieldName | | | | | | | | | objectId | | | | | | | | legacyId | | | | | | | | | variants | | | | | | | | | | nodes | | | | | | | | | | sku | | We map this to find out which SKU we need to apply the below logic to. | | | | | | | id | | | | | | | | | displayable | | This is a boolean flag. We need to create a logic : If we receive this as false or if we have 0 quantity for the product, we set Product Account > Listing Status = Inactive In any other case, we set Product Account > Listing Status = Active | | | | errors | | | | | |

We want to act and update as per the listing abstraction Product Listing general requirements depending on if the update was successful or any errors will need to be stored. </v1.1>

Is this article helpful?
0 0 0