FIX: Prevent duplicate inventory deductions in Shopify exchanges by removing grouping by product title. Group strictly by SKU or Variant ID to ensure size variants are handled accurately.

This commit is contained in:
2026-07-02 15:27:23 -06:00
parent d7350aaa8b
commit a2908167e6
@@ -2908,10 +2908,8 @@ class ShopifyConfig(models.Model):
if not product:
variant_id = str(item.get('variant_id') or '')
product = self.env['product.product'].search([('shopify_variant_id', '=', variant_id)], limit=1)
if not product:
item_title = item.get('title')
product = self.env['product.product'].search([('name', 'ilike', item_title)], limit=1) if item_title else False
# ── ALERTA 3: Producto no encontrado en Odoo ──
if not product:
not_found_items.append(item)
@@ -2959,23 +2957,36 @@ class ShopifyConfig(models.Model):
except Exception as e:
_logger.error("[Shopify BOPIS] Error al crear traspaso interno automático para artículo de cambio en '%s': %s", existing.name, str(e))
else:
# Si ya existe el artículo, validamos si cambió la cantidad en Shopify para actualizarla (Estilo Conectores Pro)
qty = float(item.get('quantity', 1))
# Si ya existe el artículo, validamos si cambió la cantidad total en Shopify para actualizarla.
# BUGFIX: Shopify manda líneas separadas para cambios (exchanges) del mismo producto.
# Sumamos la cantidad total de este producto en todo el payload de Shopify.
total_shopify_qty = 0
for si in s_order.get('line_items', []):
si_sku = si.get('sku')
si_vid = str(si.get('variant_id') or '')
if (si_sku and si_sku == product.default_code) or \
(si_vid and si_vid == product.shopify_variant_id):
total_shopify_qty += float(si.get('quantity', 1))
total_odoo_qty = sum(existing_line.mapped('product_uom_qty'))
# Solo actualizamos si la cantidad difiere y el pedido en Odoo no está en estado borrador (draft) donde se sobreescribiría de todos modos
if existing_line.product_uom_qty != qty:
old_qty = existing_line.product_uom_qty
if total_odoo_qty != total_shopify_qty:
old_qty = total_odoo_qty
_logger.info(
"[Shopify Edit] Detectada actualización de cantidad para %s en Shopify %s: %s%s. "
"Actualizando en Odoo %s.",
product.name, order_name, old_qty, qty, existing.name
product.name, order_name, old_qty, total_shopify_qty, existing.name
)
existing_line.write({'product_uom_qty': qty})
# Absorbemos la diferencia en la primera línea encontrada
new_line_qty = existing_line[0].product_uom_qty + (total_shopify_qty - total_odoo_qty)
existing_line[0].write({'product_uom_qty': new_line_qty})
# ── Actualizar traslado interno (BOPIS) si es pedido de retiro ──
ship_title_update = (existing.shopify_shipping_title or '').upper()
if any(x in ship_title_update for x in ['OFICINA', 'RETIRO', 'PICKUP', 'SUCURSAL', 'TIENDA']):
try:
existing._update_pickup_internal_transfer_qty(product, old_qty, qty)
existing._update_pickup_internal_transfer_qty(product, old_qty, total_shopify_qty)
except Exception as e:
_logger.error(
"[Shopify BOPIS Qty] Error al actualizar traslado interno para '%s' producto %s: %s",