118 lines
4.6 KiB
Python
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,
|
|
})
|