Files
Odoo-Modules/fusion-woo-odoo/fusion_woocommerce/models/woo_instance.py
2026-03-31 20:08:41 -04:00

118 lines
4.6 KiB
Python

import logging
import secrets
from odoo import api, fields, models
from odoo.exceptions import UserError
from ..lib.woo_api_client import WooApiClient
_logger = logging.getLogger(__name__)
class WooInstance(models.Model):
_name = 'woo.instance'
_description = 'WooCommerce Instance'
_inherit = ['mail.thread']
name = fields.Char(required=True, tracking=True)
url = fields.Char(required=True, tracking=True)
consumer_key = fields.Char(groups='base.group_system')
consumer_secret = fields.Char(groups='base.group_system')
webhook_secret = fields.Char(groups='base.group_system')
wc_api_version = fields.Char(default='wc/v3')
odoo_api_key = fields.Char(groups='base.group_system')
company_id = fields.Many2one(
'res.company', required=True, default=lambda self: self.env.company,
)
sync_interval = fields.Selection(
[('5', '5 Min'), ('15', '15 Min'), ('30', '30 Min'), ('60', '1 Hour')],
default='15',
)
sync_products = fields.Boolean(default=True)
sync_orders = fields.Boolean(default=True)
sync_invoices = fields.Boolean(default=True)
sync_inventory = fields.Boolean(default=True)
sync_customers = fields.Boolean(default=True)
default_warehouse_id = fields.Many2one('stock.warehouse')
notify_on_failure = fields.Boolean()
notify_user_ids = fields.Many2many('res.users')
state = fields.Selection(
[('draft', 'Draft'), ('connected', 'Connected'), ('error', 'Error')],
default='draft', tracking=True,
)
last_sync = fields.Datetime(readonly=True)
# Relational
product_map_ids = fields.One2many('woo.product.map', 'instance_id')
order_ids = fields.One2many('woo.order', 'instance_id')
customer_ids = fields.One2many('woo.customer', 'instance_id')
sync_log_ids = fields.One2many('woo.sync.log', 'instance_id')
# Computed
mapped_count = fields.Integer(compute='_compute_counts')
unmapped_count = fields.Integer(compute='_compute_counts')
error_count = fields.Integer(compute='_compute_counts')
@api.depends('product_map_ids.state', 'sync_log_ids')
def _compute_counts(self):
for rec in self:
rec.mapped_count = self.env['woo.product.map'].search_count([
('instance_id', '=', rec.id), ('state', '=', 'mapped'),
])
rec.unmapped_count = self.env['woo.product.map'].search_count([
('instance_id', '=', rec.id), ('state', '=', 'unmapped'),
])
yesterday = fields.Datetime.subtract(fields.Datetime.now(), hours=24)
rec.error_count = self.env['woo.sync.log'].search_count([
('instance_id', '=', rec.id),
('state', '=', 'failed'),
('create_date', '>=', yesterday),
])
def _get_client(self):
"""Return a WooApiClient instance for this WooCommerce connection."""
self.ensure_one()
if not self.consumer_key or not self.consumer_secret:
raise UserError("Consumer key and secret are required.")
return WooApiClient(
url=self.url,
consumer_key=self.consumer_key,
consumer_secret=self.consumer_secret,
api_version=self.wc_api_version or 'wc/v3',
)
def action_test_connection(self):
"""Test the WooCommerce connection and update state."""
self.ensure_one()
try:
client = self._get_client()
success, info = client.test_connection()
if success:
self.state = 'connected'
self.message_post(body=f"Connection successful. WooCommerce version: {info}")
else:
self.state = 'error'
self.message_post(body=f"Connection failed: {info}")
except Exception as exc:
self.state = 'error'
self.message_post(body=f"Connection error: {exc}")
_logger.exception("WooCommerce connection test failed for %s", self.name)
def action_generate_api_key(self):
"""Generate a random API key for the Odoo webhook endpoint."""
self.ensure_one()
self.odoo_api_key = secrets.token_urlsafe(32)
def _log_sync(self, sync_type, direction, record_ref, state, message=''):
"""Create a woo.sync.log record for this instance."""
self.ensure_one()
self.env['woo.sync.log'].sudo().create({
'instance_id': self.id,
'sync_type': sync_type,
'direction': direction,
'record_ref': record_ref,
'state': state,
'message': message,
'company_id': self.company_id.id,
})