Files
Odoo-Modules/fusion-woo-odoo/fusion_woocommerce/models/woo_conflict.py
gsinghpal 7e302b0a27 feat: implement price, inventory, image sync and conflict resolution
- Replace _sync_products placeholder with price comparison logic that
  detects Odoo vs WC changes and creates woo.conflict on both-changed
- Replace _sync_inventory placeholder to push Odoo stock levels to WC
- Add _sync_product_from_wc webhook handler for inbound price updates
- Add action_sync_images on woo.product.map with hash-based comparison
- Add conflict resolution methods: action_use_odoo, action_use_woo,
  action_bulk_resolve_odoo, action_bulk_resolve_woo

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-31 21:01:57 -04:00

100 lines
3.8 KiB
Python

import logging
from odoo import fields, models
from odoo.exceptions import UserError
_logger = logging.getLogger(__name__)
class WooConflict(models.Model):
_name = 'woo.conflict'
_description = 'WooCommerce Sync Conflict'
instance_id = fields.Many2one('woo.instance', required=True, ondelete='cascade')
conflict_type = fields.Selection([
('product', 'Product'),
('customer', 'Customer'),
('order', 'Order'),
])
map_id = fields.Many2one('woo.product.map')
customer_id = fields.Many2one('woo.customer')
order_id = fields.Many2one('woo.order')
field_name = fields.Char()
odoo_value = fields.Char()
woo_value = fields.Char()
resolution = fields.Selection([
('pending', 'Pending'),
('use_odoo', 'Use Odoo'),
('use_woo', 'Use WooCommerce'),
], default='pending')
resolved_by = fields.Many2one('res.users')
company_id = fields.Many2one(
'res.company', default=lambda self: self.env.company,
)
# ------------------------------------------------------------------
# Resolution methods (Task 23)
# ------------------------------------------------------------------
def action_use_odoo(self):
"""Resolve conflict by pushing Odoo value to WooCommerce."""
self.ensure_one()
if self.resolution != 'pending':
raise UserError("This conflict has already been resolved.")
client = self.instance_id._get_client()
if self.conflict_type == 'product' and self.map_id:
if self.field_name == 'price':
client.update_product(self.map_id.woo_product_id, {
'regular_price': self.odoo_value,
})
self.map_id.state = 'mapped'
self.map_id.last_synced = fields.Datetime.now()
self.resolution = 'use_odoo'
self.resolved_by = self.env.user
self.instance_id._log_sync(
self.conflict_type or 'product', 'odoo_to_woo',
self.map_id.product_id.display_name if self.map_id and self.map_id.product_id else 'N/A',
'success', f'Conflict resolved: use Odoo value ({self.odoo_value})',
)
def action_use_woo(self):
"""Resolve conflict by pulling WooCommerce value into Odoo."""
self.ensure_one()
if self.resolution != 'pending':
raise UserError("This conflict has already been resolved.")
if self.conflict_type == 'product' and self.map_id and self.map_id.product_id:
if self.field_name == 'price':
self.map_id.product_id.list_price = float(self.woo_value or 0)
self.map_id.state = 'mapped'
self.map_id.last_synced = fields.Datetime.now()
self.resolution = 'use_woo'
self.resolved_by = self.env.user
self.instance_id._log_sync(
self.conflict_type or 'product', 'woo_to_odoo',
self.map_id.product_id.display_name if self.map_id and self.map_id.product_id else 'N/A',
'success', f'Conflict resolved: use WC value ({self.woo_value})',
)
def action_bulk_resolve_odoo(self):
"""Server action: resolve all selected conflicts with Odoo values."""
for conflict in self:
if conflict.resolution == 'pending':
try:
conflict.action_use_odoo()
except Exception as e:
_logger.error("Bulk resolve (Odoo) failed for conflict %s: %s", conflict.id, e)
def action_bulk_resolve_woo(self):
"""Server action: resolve all selected conflicts with WC values."""
for conflict in self:
if conflict.resolution == 'pending':
try:
conflict.action_use_woo()
except Exception as e:
_logger.error("Bulk resolve (WC) failed for conflict %s: %s", conflict.id, e)