fix: add missing action_fetch_products and action_sync methods
Product mapping UI called these methods but they didn't exist on woo.instance. action_fetch_products fetches WC products via API, auto-matches by SKU, handles variations. action_sync runs all enabled sync types manually. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -147,6 +147,146 @@ class WooInstance(models.Model):
|
|||||||
'company_id': self.company_id.id,
|
'company_id': self.company_id.id,
|
||||||
})
|
})
|
||||||
|
|
||||||
|
# ------------------------------------------------------------------
|
||||||
|
# UI actions (called from OWL product mapping + dashboard)
|
||||||
|
# ------------------------------------------------------------------
|
||||||
|
|
||||||
|
def action_fetch_products(self):
|
||||||
|
"""Fetch products from WooCommerce and run auto-match."""
|
||||||
|
self.ensure_one()
|
||||||
|
if self.state != 'connected':
|
||||||
|
raise UserError("Please test the connection first.")
|
||||||
|
client = self._get_client()
|
||||||
|
ProductMap = self.env['woo.product.map']
|
||||||
|
page = 1
|
||||||
|
total_fetched = 0
|
||||||
|
auto_matched = 0
|
||||||
|
|
||||||
|
while True:
|
||||||
|
try:
|
||||||
|
products = client.get_products(page=page, per_page=100)
|
||||||
|
except Exception as e:
|
||||||
|
self._log_sync('product', 'woo_to_odoo', self.name, 'failed', str(e))
|
||||||
|
raise UserError("Failed to fetch products: %s" % str(e))
|
||||||
|
if not products:
|
||||||
|
break
|
||||||
|
|
||||||
|
for wc_prod in products:
|
||||||
|
wc_id = wc_prod.get('id')
|
||||||
|
# Skip if already mapped
|
||||||
|
existing = ProductMap.search([
|
||||||
|
('instance_id', '=', self.id),
|
||||||
|
('woo_product_id', '=', wc_id),
|
||||||
|
], limit=1)
|
||||||
|
if existing:
|
||||||
|
continue
|
||||||
|
|
||||||
|
wc_sku = wc_prod.get('sku', '') or ''
|
||||||
|
wc_name = wc_prod.get('name', '')
|
||||||
|
wc_type = wc_prod.get('type', 'simple')
|
||||||
|
|
||||||
|
# Try SKU match
|
||||||
|
odoo_product = False
|
||||||
|
match_state = 'unmapped'
|
||||||
|
if wc_sku:
|
||||||
|
odoo_product = self.env['product.product'].search([
|
||||||
|
('default_code', '=', wc_sku),
|
||||||
|
], limit=1)
|
||||||
|
if odoo_product:
|
||||||
|
match_state = 'mapped'
|
||||||
|
auto_matched += 1
|
||||||
|
|
||||||
|
ProductMap.create({
|
||||||
|
'instance_id': self.id,
|
||||||
|
'product_id': odoo_product.id if odoo_product else False,
|
||||||
|
'woo_product_id': wc_id,
|
||||||
|
'woo_product_name': wc_name,
|
||||||
|
'woo_sku': wc_sku,
|
||||||
|
'woo_product_type': wc_type if wc_type in ('simple', 'variable', 'grouped', 'external') else 'simple',
|
||||||
|
'state': match_state,
|
||||||
|
'company_id': self.company_id.id,
|
||||||
|
})
|
||||||
|
total_fetched += 1
|
||||||
|
|
||||||
|
# Fetch variations for variable products
|
||||||
|
if wc_type == 'variable':
|
||||||
|
try:
|
||||||
|
var_page = 1
|
||||||
|
while True:
|
||||||
|
variations = client.get_product_variations(wc_id, page=var_page, per_page=100)
|
||||||
|
if not variations:
|
||||||
|
break
|
||||||
|
for var in variations:
|
||||||
|
var_id = var.get('id')
|
||||||
|
var_existing = ProductMap.search([
|
||||||
|
('instance_id', '=', self.id),
|
||||||
|
('woo_product_id', '=', var_id),
|
||||||
|
], limit=1)
|
||||||
|
if var_existing:
|
||||||
|
continue
|
||||||
|
|
||||||
|
var_sku = var.get('sku', '') or ''
|
||||||
|
var_name = wc_name + ' - ' + ', '.join(
|
||||||
|
[a.get('option', '') for a in var.get('attributes', [])]
|
||||||
|
)
|
||||||
|
var_product = False
|
||||||
|
var_state = 'unmapped'
|
||||||
|
if var_sku:
|
||||||
|
var_product = self.env['product.product'].search([
|
||||||
|
('default_code', '=', var_sku),
|
||||||
|
], limit=1)
|
||||||
|
if var_product:
|
||||||
|
var_state = 'mapped'
|
||||||
|
auto_matched += 1
|
||||||
|
|
||||||
|
ProductMap.create({
|
||||||
|
'instance_id': self.id,
|
||||||
|
'product_id': var_product.id if var_product else False,
|
||||||
|
'woo_product_id': var_id,
|
||||||
|
'woo_product_name': var_name,
|
||||||
|
'woo_sku': var_sku,
|
||||||
|
'woo_product_type': 'simple',
|
||||||
|
'woo_parent_id': wc_id,
|
||||||
|
'is_variation': True,
|
||||||
|
'state': var_state,
|
||||||
|
'company_id': self.company_id.id,
|
||||||
|
})
|
||||||
|
total_fetched += 1
|
||||||
|
var_page += 1
|
||||||
|
if len(variations) < 100:
|
||||||
|
break
|
||||||
|
except Exception:
|
||||||
|
_logger.warning("Failed to fetch variations for product %s", wc_id)
|
||||||
|
|
||||||
|
page += 1
|
||||||
|
if len(products) < 100:
|
||||||
|
break
|
||||||
|
|
||||||
|
self._log_sync('product', 'woo_to_odoo', self.name, 'success',
|
||||||
|
'Fetched %d products, auto-matched %d by SKU' % (total_fetched, auto_matched))
|
||||||
|
return True
|
||||||
|
|
||||||
|
def action_sync(self):
|
||||||
|
"""Manual sync trigger from the UI."""
|
||||||
|
self.ensure_one()
|
||||||
|
if self.state != 'connected':
|
||||||
|
raise UserError("Instance is not connected.")
|
||||||
|
try:
|
||||||
|
if self.sync_products:
|
||||||
|
self._sync_products()
|
||||||
|
if self.sync_orders:
|
||||||
|
self._sync_orders()
|
||||||
|
if self.sync_inventory:
|
||||||
|
self._sync_inventory()
|
||||||
|
if self.sync_customers:
|
||||||
|
self._sync_customers()
|
||||||
|
self.last_sync = fields.Datetime.now()
|
||||||
|
except Exception as e:
|
||||||
|
_logger.error("Manual sync failed for %s: %s", self.name, str(e))
|
||||||
|
self._log_sync('product', 'odoo_to_woo', self.name, 'failed', str(e))
|
||||||
|
raise UserError("Sync failed: %s" % str(e))
|
||||||
|
return True
|
||||||
|
|
||||||
# ------------------------------------------------------------------
|
# ------------------------------------------------------------------
|
||||||
# Cron entry points
|
# Cron entry points
|
||||||
# ------------------------------------------------------------------
|
# ------------------------------------------------------------------
|
||||||
|
|||||||
Reference in New Issue
Block a user