import base64 import hashlib import json 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') # Mappings category_map_ids = fields.One2many('woo.category.map', 'instance_id', string='Category Mappings') tax_map_ids = fields.One2many('woo.tax.map', 'instance_id', string='Tax Mappings') pricelist_map_ids = fields.One2many('woo.pricelist.map', 'instance_id', string='Pricelist Mappings') excluded_category_ids = fields.Many2many( 'product.category', string='Hidden Categories', help='Products in these categories will be hidden from the unmatched products list.' ) # AI Configuration ai_provider = fields.Selection([ ('claude', 'Claude (Anthropic)'), ('openai', 'OpenAI'), ], string='AI Provider') ai_api_key = fields.Char(string='AI API Key', groups='base.group_system') ai_model = fields.Selection([ # Claude models ('claude-opus-4-20250514', 'Anthropic — Claude Opus 4'), ('claude-sonnet-4-5-20250514', 'Anthropic — Claude Sonnet 4.5'), ('claude-haiku-4-5-20251001', 'Anthropic — Claude Haiku 4.5'), # OpenAI models ('gpt-4o', 'OpenAI — GPT-4o'), ('gpt-4o-mini', 'OpenAI — GPT-4o Mini'), ('gpt-4-turbo', 'OpenAI — GPT-4 Turbo'), ('gpt-4.1', 'OpenAI — GPT-4.1'), ('gpt-4.1-mini', 'OpenAI — GPT-4.1 Mini'), ('gpt-4.1-nano', 'OpenAI — GPT-4.1 Nano'), ('o3-mini', 'OpenAI — o3 Mini'), ], string='AI Model') # AI Prompts prompt_product_title = fields.Text(string='Product Title Prompt', default='Generate an SEO-optimized product title in Title Case. Keep it concise, include the brand name and key product features. Do not use ALL CAPS.') prompt_short_description = fields.Text(string='Short Description Prompt', default='Write a compelling 2-3 sentence product summary in HTML format. Highlight key benefits and features. Use

tags.') prompt_long_description = fields.Text(string='Long Description Prompt', default='Write a detailed SEO-optimized product description in HTML format. Include sections with

headings for Features, Specifications, and Benefits. Use