fix: use WC attribute ID (not name) when setting variation attributes

WooCommerce silently ignores attribute 'name' on variation updates —
requires 'id' (the WC attribute ID). Built a lookup map from the
parent product's wc_attributes and use 'id' in all variation payloads.
Fixed in all 3 files: variant push wizard, product creation wizard,
and product map direct push.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
gsinghpal
2026-04-01 18:59:54 -04:00
parent 71dea1f91b
commit 75ceee1e69
3 changed files with 38 additions and 16 deletions

View File

@@ -207,10 +207,12 @@ class WooProductMap(models.Model):
except Exception as e: except Exception as e:
raise UserError("Failed to convert WC product to variable: %s" % str(e)) raise UserError("Failed to convert WC product to variable: %s" % str(e))
# Build WC attribute ID lookup
wc_attr_id_map = {a['name'].upper(): a['id'] for a in wc_attributes}
# Step 3: Create a WC variation for each Odoo variant # Step 3: Create a WC variation for each Odoo variant
created = 0 created = 0
for variant in variants: for variant in variants:
# Check if variation already mapped
existing = self.search([ existing = self.search([
('instance_id', '=', inst.id), ('instance_id', '=', inst.id),
('product_id', '=', variant.id), ('product_id', '=', variant.id),
@@ -219,13 +221,17 @@ class WooProductMap(models.Model):
if existing: if existing:
continue continue
# Build variation attributes # Build variation attributes with WC IDs
var_attributes = [] var_attributes = []
for ptav in variant.product_template_attribute_value_ids: for ptav in variant.product_template_attribute_value_ids:
var_attributes.append({ attr_name = ptav.attribute_id.name
'name': ptav.attribute_id.name, wc_aid = wc_attr_id_map.get(attr_name.upper(), 0)
'option': ptav.name, entry = {'option': ptav.name}
}) if wc_aid:
entry['id'] = wc_aid
else:
entry['name'] = attr_name
var_attributes.append(entry)
var_data = { var_data = {
'regular_price': str(variant.list_price), 'regular_price': str(variant.list_price),

View File

@@ -585,6 +585,9 @@ class WooProductCreateWizard(models.TransientModel):
'company_id': inst.company_id.id, 'company_id': inst.company_id.id,
}) })
# Build WC attribute ID lookup
wc_attr_id_map = {a['name'].upper(): a['id'] for a in wc_attributes}
# Create variations # Create variations
variation_count = 0 variation_count = 0
for line in self.variant_line_ids: for line in self.variant_line_ids:
@@ -592,13 +595,17 @@ class WooProductCreateWizard(models.TransientModel):
continue continue
variant = line.product_id variant = line.product_id
# Build variation attributes # Build variation attributes with WC IDs
var_attributes = [] var_attributes = []
for ptav in variant.product_template_attribute_value_ids: for ptav in variant.product_template_attribute_value_ids:
var_attributes.append({ attr_name = ptav.attribute_id.name
'name': ptav.attribute_id.name, wc_aid = wc_attr_id_map.get(attr_name.upper(), 0)
'option': ptav.name, entry = {'option': ptav.name}
}) if wc_aid:
entry['id'] = wc_aid
else:
entry['name'] = attr_name
var_attributes.append(entry)
var_data = { var_data = {
'regular_price': str(line.sale_price), 'regular_price': str(line.sale_price),

View File

@@ -108,6 +108,11 @@ class WooVariantPushWizard(models.TransientModel):
'options': wc_terms, 'options': wc_terms,
}) })
# Build a lookup: Odoo attribute name → WC attribute ID
wc_attr_id_map = {}
for wc_attr in wc_attributes:
wc_attr_id_map[wc_attr['name'].upper()] = wc_attr['id']
# Step 2: Update product as variable with attributes + set default # Step 2: Update product as variable with attributes + set default
# Default attribute = first included variant's attribute values # Default attribute = first included variant's attribute values
default_attrs = [] default_attrs = []
@@ -234,13 +239,17 @@ class WooVariantPushWizard(models.TransientModel):
if not wc_var_id: if not wc_var_id:
continue continue
# Build variation attributes from Odoo # Build variation attributes with WC attribute IDs
var_attributes = [] var_attributes = []
for ptav in variant.product_template_attribute_value_ids: for ptav in variant.product_template_attribute_value_ids:
var_attributes.append({ attr_name = ptav.attribute_id.name
'name': ptav.attribute_id.name, wc_attr_id = wc_attr_id_map.get(attr_name.upper(), 0)
'option': ptav.name, attr_entry = {'option': ptav.name}
}) if wc_attr_id:
attr_entry['id'] = wc_attr_id
else:
attr_entry['name'] = attr_name
var_attributes.append(attr_entry)
var_data = { var_data = {
'regular_price': str(line.regular_price), 'regular_price': str(line.regular_price),