From 39e007b42fec907113996db13fec5c58f4fc5a0b Mon Sep 17 00:00:00 2001 From: gsinghpal Date: Wed, 1 Apr 2026 22:02:29 -0400 Subject: [PATCH] =?UTF-8?q?feat:=20default=20variant=20selector=20?= =?UTF-8?q?=E2=80=94=20user=20picks=20which=20variant=20is=20the=20default?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Added 'Default' toggle column in variant push wizard. First variant is pre-selected as default. User can change it. The default variant's attribute values are set as WC product's default_attributes using WC attribute IDs. Co-Authored-By: Claude Opus 4.6 (1M context) --- .../wizard/woo_variant_push.py | 25 +++++++++++++------ .../wizard/woo_variant_push_views.xml | 1 + 2 files changed, 18 insertions(+), 8 deletions(-) diff --git a/fusion-woo-odoo/fusion_woocommerce/wizard/woo_variant_push.py b/fusion-woo-odoo/fusion_woocommerce/wizard/woo_variant_push.py index 861688ef..013f939d 100644 --- a/fusion-woo-odoo/fusion_woocommerce/wizard/woo_variant_push.py +++ b/fusion-woo-odoo/fusion_woocommerce/wizard/woo_variant_push.py @@ -50,6 +50,7 @@ class WooVariantPushWizard(models.TransientModel): attr_values = ', '.join( variant.product_template_attribute_value_ids.mapped('name') ) + is_first = len(lines) == 0 lines.append((0, 0, { 'product_id': variant.id, 'variant_name': variant.display_name, @@ -60,6 +61,7 @@ class WooVariantPushWizard(models.TransientModel): 'cost_price': variant.standard_price, 'image': variant.image_variant_1920 or variant.image_1920 or False, 'include': True, + 'is_default': is_first, 'already_synced': bool(already_mapped), 'wc_variation_id': already_mapped.woo_product_id if already_mapped else 0, 'map_id': already_mapped.id if already_mapped else 0, @@ -114,15 +116,21 @@ class WooVariantPushWizard(models.TransientModel): wc_attr_id_map[wc_attr['name'].upper()] = wc_attr['id'] # Step 2: Update product as variable with attributes + set default - # Default attribute = first included variant's attribute values + # Use the variant marked as default, or first included + default_line = self.line_ids.filtered(lambda l: l.include and l.is_default)[:1] + if not default_line: + default_line = self.line_ids.filtered('include')[:1] default_attrs = [] - first_included = self.line_ids.filtered('include')[:1] - if first_included and first_included.product_id: - for ptav in first_included.product_id.product_template_attribute_value_ids: - default_attrs.append({ - 'name': ptav.attribute_id.name, - 'option': ptav.name, - }) + if default_line and default_line.product_id: + for ptav in default_line.product_id.product_template_attribute_value_ids: + attr_name = ptav.attribute_id.name + wc_aid = wc_attr_id_map.get(attr_name.upper(), 0) + entry = {'option': ptav.name} + if wc_aid: + entry['id'] = wc_aid + else: + entry['name'] = attr_name + default_attrs.append(entry) parent_update = { 'type': 'variable', @@ -323,6 +331,7 @@ class WooVariantPushLine(models.TransientModel): cost_price = fields.Float(string='Cost', digits='Product Price') image = fields.Binary(string='Image', attachment=False) include = fields.Boolean(string='Include', default=True) + is_default = fields.Boolean(string='Default') already_synced = fields.Boolean(string='Already Synced') wc_variation_id = fields.Integer(string='WC Variation ID') map_id = fields.Integer(string='Map Record ID') diff --git a/fusion-woo-odoo/fusion_woocommerce/wizard/woo_variant_push_views.xml b/fusion-woo-odoo/fusion_woocommerce/wizard/woo_variant_push_views.xml index 09f2eca6..34641a19 100644 --- a/fusion-woo-odoo/fusion_woocommerce/wizard/woo_variant_push_views.xml +++ b/fusion-woo-odoo/fusion_woocommerce/wizard/woo_variant_push_views.xml @@ -30,6 +30,7 @@ +