feat: add woo.instance and woo.shipping.carrier models with default carriers
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -11,6 +11,7 @@
|
||||
'data': [
|
||||
'security/woo_security.xml',
|
||||
'security/ir.model.access.csv',
|
||||
'data/shipping_carriers.xml',
|
||||
],
|
||||
'assets': {
|
||||
'web.assets_backend': [
|
||||
|
||||
@@ -0,0 +1,33 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<odoo noupdate="1">
|
||||
<record id="carrier_canada_post" model="woo.shipping.carrier">
|
||||
<field name="name">Canada Post</field>
|
||||
<field name="code">canada_post</field>
|
||||
<field name="tracking_url">https://www.canadapost-postescanada.ca/track-reperage/en#/search?searchFor={tracking}</field>
|
||||
</record>
|
||||
<record id="carrier_ups" model="woo.shipping.carrier">
|
||||
<field name="name">UPS</field>
|
||||
<field name="code">ups</field>
|
||||
<field name="tracking_url">https://www.ups.com/track?tracknum={tracking}</field>
|
||||
</record>
|
||||
<record id="carrier_fedex" model="woo.shipping.carrier">
|
||||
<field name="name">FedEx</field>
|
||||
<field name="code">fedex</field>
|
||||
<field name="tracking_url">https://www.fedex.com/fedextrack/?trknbr={tracking}</field>
|
||||
</record>
|
||||
<record id="carrier_purolator" model="woo.shipping.carrier">
|
||||
<field name="name">Purolator</field>
|
||||
<field name="code">purolator</field>
|
||||
<field name="tracking_url">https://www.purolator.com/en/shipping/tracker?pin={tracking}</field>
|
||||
</record>
|
||||
<record id="carrier_dhl" model="woo.shipping.carrier">
|
||||
<field name="name">DHL</field>
|
||||
<field name="code">dhl</field>
|
||||
<field name="tracking_url">https://www.dhl.com/en/express/tracking.html?AWB={tracking}</field>
|
||||
</record>
|
||||
<record id="carrier_other" model="woo.shipping.carrier">
|
||||
<field name="name">Other</field>
|
||||
<field name="code">other</field>
|
||||
<field name="tracking_url"></field>
|
||||
</record>
|
||||
</odoo>
|
||||
117
fusion-woo-odoo/fusion_woocommerce/models/woo_instance.py
Normal file
117
fusion-woo-odoo/fusion_woocommerce/models/woo_instance.py
Normal file
@@ -0,0 +1,117 @@
|
||||
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,
|
||||
})
|
||||
@@ -0,0 +1,11 @@
|
||||
from odoo import fields, models
|
||||
|
||||
|
||||
class WooShippingCarrier(models.Model):
|
||||
_name = 'woo.shipping.carrier'
|
||||
_description = 'WooCommerce Shipping Carrier'
|
||||
|
||||
name = fields.Char(required=True)
|
||||
code = fields.Char(required=True)
|
||||
tracking_url = fields.Char(help='Use {tracking} as placeholder')
|
||||
active = fields.Boolean(default=True)
|
||||
Reference in New Issue
Block a user