From fdd67c9e51db9f1bedf01ce41c4ba9a651d13379 Mon Sep 17 00:00:00 2001 From: gsinghpal Date: Tue, 31 Mar 2026 20:08:49 -0400 Subject: [PATCH] feat: add all remaining models (product map, order, shipment, customer, sync log, conflict, tax/pricelist map, returns) Co-Authored-By: Claude Opus 4.6 (1M context) --- .../fusion_woocommerce/models/__init__.py | 12 +++++- .../fusion_woocommerce/models/woo_conflict.py | 28 +++++++++++++ .../fusion_woocommerce/models/woo_customer.py | 15 +++++++ .../fusion_woocommerce/models/woo_order.py | 25 +++++++++++ .../models/woo_pricelist_map.py | 14 +++++++ .../models/woo_product_map.py | 34 +++++++++++++++ .../fusion_woocommerce/models/woo_return.py | 41 +++++++++++++++++++ .../fusion_woocommerce/models/woo_shipment.py | 17 ++++++++ .../fusion_woocommerce/models/woo_sync_log.py | 30 ++++++++++++++ .../fusion_woocommerce/models/woo_tax_map.py | 14 +++++++ .../security/ir.model.access.csv | 24 +++++++++++ 11 files changed, 253 insertions(+), 1 deletion(-) create mode 100644 fusion-woo-odoo/fusion_woocommerce/models/woo_conflict.py create mode 100644 fusion-woo-odoo/fusion_woocommerce/models/woo_customer.py create mode 100644 fusion-woo-odoo/fusion_woocommerce/models/woo_order.py create mode 100644 fusion-woo-odoo/fusion_woocommerce/models/woo_pricelist_map.py create mode 100644 fusion-woo-odoo/fusion_woocommerce/models/woo_product_map.py create mode 100644 fusion-woo-odoo/fusion_woocommerce/models/woo_return.py create mode 100644 fusion-woo-odoo/fusion_woocommerce/models/woo_shipment.py create mode 100644 fusion-woo-odoo/fusion_woocommerce/models/woo_sync_log.py create mode 100644 fusion-woo-odoo/fusion_woocommerce/models/woo_tax_map.py diff --git a/fusion-woo-odoo/fusion_woocommerce/models/__init__.py b/fusion-woo-odoo/fusion_woocommerce/models/__init__.py index 2a4b64f8..b6c1345b 100644 --- a/fusion-woo-odoo/fusion_woocommerce/models/__init__.py +++ b/fusion-woo-odoo/fusion_woocommerce/models/__init__.py @@ -1 +1,11 @@ -# Models will be imported here +from . import woo_shipping_carrier +from . import woo_instance +from . import woo_product_map +from . import woo_order +from . import woo_shipment +from . import woo_customer +from . import woo_sync_log +from . import woo_conflict +from . import woo_tax_map +from . import woo_pricelist_map +from . import woo_return diff --git a/fusion-woo-odoo/fusion_woocommerce/models/woo_conflict.py b/fusion-woo-odoo/fusion_woocommerce/models/woo_conflict.py new file mode 100644 index 00000000..f9cc0bfc --- /dev/null +++ b/fusion-woo-odoo/fusion_woocommerce/models/woo_conflict.py @@ -0,0 +1,28 @@ +from odoo import fields, models + + +class WooConflict(models.Model): + _name = 'woo.conflict' + _description = 'WooCommerce Sync Conflict' + + instance_id = fields.Many2one('woo.instance', required=True, ondelete='cascade') + conflict_type = fields.Selection([ + ('product', 'Product'), + ('customer', 'Customer'), + ('order', 'Order'), + ]) + map_id = fields.Many2one('woo.product.map') + customer_id = fields.Many2one('woo.customer') + order_id = fields.Many2one('woo.order') + field_name = fields.Char() + odoo_value = fields.Char() + woo_value = fields.Char() + resolution = fields.Selection([ + ('pending', 'Pending'), + ('use_odoo', 'Use Odoo'), + ('use_woo', 'Use WooCommerce'), + ], default='pending') + resolved_by = fields.Many2one('res.users') + company_id = fields.Many2one( + 'res.company', default=lambda self: self.env.company, + ) diff --git a/fusion-woo-odoo/fusion_woocommerce/models/woo_customer.py b/fusion-woo-odoo/fusion_woocommerce/models/woo_customer.py new file mode 100644 index 00000000..82ce145a --- /dev/null +++ b/fusion-woo-odoo/fusion_woocommerce/models/woo_customer.py @@ -0,0 +1,15 @@ +from odoo import fields, models + + +class WooCustomer(models.Model): + _name = 'woo.customer' + _description = 'WooCommerce Customer' + + instance_id = fields.Many2one('woo.instance', required=True, ondelete='cascade') + partner_id = fields.Many2one('res.partner', required=True) + woo_customer_id = fields.Integer(index=True) + woo_email = fields.Char() + last_synced = fields.Datetime() + company_id = fields.Many2one( + 'res.company', required=True, default=lambda self: self.env.company, + ) diff --git a/fusion-woo-odoo/fusion_woocommerce/models/woo_order.py b/fusion-woo-odoo/fusion_woocommerce/models/woo_order.py new file mode 100644 index 00000000..84a8d89a --- /dev/null +++ b/fusion-woo-odoo/fusion_woocommerce/models/woo_order.py @@ -0,0 +1,25 @@ +from odoo import fields, models + + +class WooOrder(models.Model): + _name = 'woo.order' + _description = 'WooCommerce Order' + + instance_id = fields.Many2one('woo.instance', required=True, ondelete='cascade') + sale_order_id = fields.Many2one('sale.order') + woo_order_id = fields.Integer(index=True) + woo_order_number = fields.Char() + woo_status = fields.Char() + invoice_id = fields.Many2one('account.move') + invoice_synced = fields.Boolean() + company_id = fields.Many2one( + 'res.company', required=True, default=lambda self: self.env.company, + ) + state = fields.Selection([ + ('new', 'New'), + ('confirmed', 'Confirmed'), + ('shipped', 'Shipped'), + ('completed', 'Completed'), + ('cancelled', 'Cancelled'), + ], default='new') + shipment_ids = fields.One2many('woo.shipment', 'order_id') diff --git a/fusion-woo-odoo/fusion_woocommerce/models/woo_pricelist_map.py b/fusion-woo-odoo/fusion_woocommerce/models/woo_pricelist_map.py new file mode 100644 index 00000000..1ddf8dac --- /dev/null +++ b/fusion-woo-odoo/fusion_woocommerce/models/woo_pricelist_map.py @@ -0,0 +1,14 @@ +from odoo import fields, models + + +class WooPricelistMap(models.Model): + _name = 'woo.pricelist.map' + _description = 'WooCommerce Pricelist Mapping' + + instance_id = fields.Many2one('woo.instance', required=True, ondelete='cascade') + pricelist_id = fields.Many2one('product.pricelist', required=True) + woo_role = fields.Char(required=True) + woo_role_name = fields.Char() + company_id = fields.Many2one( + 'res.company', required=True, default=lambda self: self.env.company, + ) diff --git a/fusion-woo-odoo/fusion_woocommerce/models/woo_product_map.py b/fusion-woo-odoo/fusion_woocommerce/models/woo_product_map.py new file mode 100644 index 00000000..0865a924 --- /dev/null +++ b/fusion-woo-odoo/fusion_woocommerce/models/woo_product_map.py @@ -0,0 +1,34 @@ +from odoo import fields, models + + +class WooProductMap(models.Model): + _name = 'woo.product.map' + _description = 'WooCommerce Product Mapping' + + instance_id = fields.Many2one('woo.instance', required=True, ondelete='cascade') + product_id = fields.Many2one('product.product') + woo_product_id = fields.Integer() + woo_product_name = fields.Char() + woo_sku = fields.Char() + woo_product_type = fields.Selection([ + ('simple', 'Simple'), + ('variable', 'Variable'), + ('grouped', 'Grouped'), + ('external', 'External'), + ]) + woo_parent_id = fields.Integer() + is_variation = fields.Boolean() + sync_price = fields.Boolean(default=True) + sync_inventory = fields.Boolean(default=True) + sync_images = fields.Boolean(default=True) + woo_image_ids = fields.Char() # JSON + last_synced = fields.Datetime() + company_id = fields.Many2one( + 'res.company', required=True, default=lambda self: self.env.company, + ) + state = fields.Selection([ + ('unmapped', 'Unmapped'), + ('mapped', 'Mapped'), + ('conflict', 'Conflict'), + ('error', 'Error'), + ], default='unmapped') diff --git a/fusion-woo-odoo/fusion_woocommerce/models/woo_return.py b/fusion-woo-odoo/fusion_woocommerce/models/woo_return.py new file mode 100644 index 00000000..dec3eafe --- /dev/null +++ b/fusion-woo-odoo/fusion_woocommerce/models/woo_return.py @@ -0,0 +1,41 @@ +from odoo import fields, models + + +class WooReturn(models.Model): + _name = 'woo.return' + _description = 'WooCommerce Return' + + instance_id = fields.Many2one('woo.instance', required=True, ondelete='cascade') + order_id = fields.Many2one('woo.order', required=True) + picking_id = fields.Many2one('stock.picking') + reason = fields.Text() + line_ids = fields.One2many('woo.return.line', 'return_id') + state = fields.Selection([ + ('requested', 'Requested'), + ('approved', 'Approved'), + ('received', 'Received'), + ('refunded', 'Refunded'), + ('rejected', 'Rejected'), + ], default='requested') + company_id = fields.Many2one( + 'res.company', required=True, default=lambda self: self.env.company, + ) + + +class WooReturnLine(models.Model): + _name = 'woo.return.line' + _description = 'WooCommerce Return Line' + + return_id = fields.Many2one('woo.return', required=True, ondelete='cascade') + product_id = fields.Many2one('product.product', required=True) + quantity = fields.Float(default=1.0) + reason = fields.Selection([ + ('defective', 'Defective'), + ('wrong_item', 'Wrong Item'), + ('not_needed', 'Not Needed'), + ('damaged', 'Damaged'), + ('other', 'Other'), + ]) + company_id = fields.Many2one( + 'res.company', default=lambda self: self.env.company, + ) diff --git a/fusion-woo-odoo/fusion_woocommerce/models/woo_shipment.py b/fusion-woo-odoo/fusion_woocommerce/models/woo_shipment.py new file mode 100644 index 00000000..9a4d19cd --- /dev/null +++ b/fusion-woo-odoo/fusion_woocommerce/models/woo_shipment.py @@ -0,0 +1,17 @@ +from odoo import fields, models + + +class WooShipment(models.Model): + _name = 'woo.shipment' + _description = 'WooCommerce Shipment' + + order_id = fields.Many2one('woo.order', required=True, ondelete='cascade') + picking_id = fields.Many2one('stock.picking') + carrier_id = fields.Many2one('woo.shipping.carrier') + tracking_number = fields.Char() + shipped_date = fields.Datetime() + is_backorder = fields.Boolean() + synced_to_woo = fields.Boolean() + company_id = fields.Many2one( + 'res.company', required=True, default=lambda self: self.env.company, + ) diff --git a/fusion-woo-odoo/fusion_woocommerce/models/woo_sync_log.py b/fusion-woo-odoo/fusion_woocommerce/models/woo_sync_log.py new file mode 100644 index 00000000..00614157 --- /dev/null +++ b/fusion-woo-odoo/fusion_woocommerce/models/woo_sync_log.py @@ -0,0 +1,30 @@ +from odoo import fields, models + + +class WooSyncLog(models.Model): + _name = 'woo.sync.log' + _description = 'WooCommerce Sync Log' + _order = 'create_date desc' + + instance_id = fields.Many2one('woo.instance', ondelete='cascade') + sync_type = fields.Selection([ + ('product', 'Product'), + ('order', 'Order'), + ('invoice', 'Invoice'), + ('inventory', 'Inventory'), + ('customer', 'Customer'), + ]) + direction = fields.Selection([ + ('odoo_to_woo', 'Odoo \u2192 WooCommerce'), + ('woo_to_odoo', 'WooCommerce \u2192 Odoo'), + ]) + record_ref = fields.Char() + state = fields.Selection([ + ('success', 'Success'), + ('failed', 'Failed'), + ('conflict', 'Conflict'), + ]) + message = fields.Text() + company_id = fields.Many2one( + 'res.company', default=lambda self: self.env.company, + ) diff --git a/fusion-woo-odoo/fusion_woocommerce/models/woo_tax_map.py b/fusion-woo-odoo/fusion_woocommerce/models/woo_tax_map.py new file mode 100644 index 00000000..d2757f29 --- /dev/null +++ b/fusion-woo-odoo/fusion_woocommerce/models/woo_tax_map.py @@ -0,0 +1,14 @@ +from odoo import fields, models + + +class WooTaxMap(models.Model): + _name = 'woo.tax.map' + _description = 'WooCommerce Tax Mapping' + + instance_id = fields.Many2one('woo.instance', required=True, ondelete='cascade') + tax_id = fields.Many2one('account.tax', required=True) + woo_tax_class = fields.Char(required=True) + woo_tax_class_name = fields.Char() + company_id = fields.Many2one( + 'res.company', required=True, default=lambda self: self.env.company, + ) diff --git a/fusion-woo-odoo/fusion_woocommerce/security/ir.model.access.csv b/fusion-woo-odoo/fusion_woocommerce/security/ir.model.access.csv index 97dd8b91..3186a8e4 100644 --- a/fusion-woo-odoo/fusion_woocommerce/security/ir.model.access.csv +++ b/fusion-woo-odoo/fusion_woocommerce/security/ir.model.access.csv @@ -1 +1,25 @@ id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink +access_woo_instance_user,woo.instance.user,model_woo_instance,fusion_woocommerce.group_woo_user,1,0,0,0 +access_woo_instance_manager,woo.instance.manager,model_woo_instance,fusion_woocommerce.group_woo_manager,1,1,1,1 +access_woo_shipping_carrier_user,woo.shipping.carrier.user,model_woo_shipping_carrier,fusion_woocommerce.group_woo_user,1,0,0,0 +access_woo_shipping_carrier_manager,woo.shipping.carrier.manager,model_woo_shipping_carrier,fusion_woocommerce.group_woo_manager,1,1,1,1 +access_woo_product_map_user,woo.product.map.user,model_woo_product_map,fusion_woocommerce.group_woo_user,1,0,0,0 +access_woo_product_map_manager,woo.product.map.manager,model_woo_product_map,fusion_woocommerce.group_woo_manager,1,1,1,1 +access_woo_order_user,woo.order.user,model_woo_order,fusion_woocommerce.group_woo_user,1,0,0,0 +access_woo_order_manager,woo.order.manager,model_woo_order,fusion_woocommerce.group_woo_manager,1,1,1,1 +access_woo_shipment_user,woo.shipment.user,model_woo_shipment,fusion_woocommerce.group_woo_user,1,0,0,0 +access_woo_shipment_manager,woo.shipment.manager,model_woo_shipment,fusion_woocommerce.group_woo_manager,1,1,1,1 +access_woo_customer_user,woo.customer.user,model_woo_customer,fusion_woocommerce.group_woo_user,1,0,0,0 +access_woo_customer_manager,woo.customer.manager,model_woo_customer,fusion_woocommerce.group_woo_manager,1,1,1,1 +access_woo_sync_log_user,woo.sync.log.user,model_woo_sync_log,fusion_woocommerce.group_woo_user,1,0,0,0 +access_woo_sync_log_manager,woo.sync.log.manager,model_woo_sync_log,fusion_woocommerce.group_woo_manager,1,1,1,1 +access_woo_conflict_user,woo.conflict.user,model_woo_conflict,fusion_woocommerce.group_woo_user,1,0,0,0 +access_woo_conflict_manager,woo.conflict.manager,model_woo_conflict,fusion_woocommerce.group_woo_manager,1,1,1,1 +access_woo_tax_map_user,woo.tax.map.user,model_woo_tax_map,fusion_woocommerce.group_woo_user,1,0,0,0 +access_woo_tax_map_manager,woo.tax.map.manager,model_woo_tax_map,fusion_woocommerce.group_woo_manager,1,1,1,1 +access_woo_pricelist_map_user,woo.pricelist.map.user,model_woo_pricelist_map,fusion_woocommerce.group_woo_user,1,0,0,0 +access_woo_pricelist_map_manager,woo.pricelist.map.manager,model_woo_pricelist_map,fusion_woocommerce.group_woo_manager,1,1,1,1 +access_woo_return_user,woo.return.user,model_woo_return,fusion_woocommerce.group_woo_user,1,0,0,0 +access_woo_return_manager,woo.return.manager,model_woo_return,fusion_woocommerce.group_woo_manager,1,1,1,1 +access_woo_return_line_user,woo.return.line.user,model_woo_return_line,fusion_woocommerce.group_woo_user,1,0,0,0 +access_woo_return_line_manager,woo.return.line.manager,model_woo_return_line,fusion_woocommerce.group_woo_manager,1,1,1,1