IMP connector_opencart Add field opencart_sku on product.template to let you pre-make products and link them up.

Improved partner matching and added some logging for the testing phase.
Added menu item Connectors->Opencart-Products to find and fix mapping easily.
Allow deleting `product.template` even with bindings so that you could re-make the binding.
This commit is contained in:
Jared Kipe
2020-03-06 11:20:27 -08:00
parent ce8bb41c03
commit cfaa06d2ca
6 changed files with 98 additions and 15 deletions

View File

@@ -22,6 +22,7 @@
'views/delivery_views.xml', 'views/delivery_views.xml',
'views/opencart_backend_views.xml', 'views/opencart_backend_views.xml',
'views/opencart_product_views.xml', 'views/opencart_product_views.xml',
'views/product_views.xml',
], ],
'installable': True, 'installable': True,
'application': False, 'application': False,

View File

@@ -12,7 +12,7 @@ class OpencartProductTemplate(models.Model):
odoo_id = fields.Many2one('product.template', odoo_id = fields.Many2one('product.template',
string='Product', string='Product',
required=True, required=True,
ondelete='restrict') ondelete='cascade') # cascade so that you can delete an Odoo product that was created by connector
opencart_attribute_value_ids = fields.One2many('opencart.product.template.attribute.value', opencart_attribute_value_ids = fields.One2many('opencart.product.template.attribute.value',
'opencart_product_tmpl_id', 'opencart_product_tmpl_id',
string='Opencart Product Attribute Values') string='Opencart Product Attribute Values')
@@ -34,7 +34,7 @@ class OpencartProductTemplate(models.Model):
if reentry: if reentry:
raise RetryableJobError('Product imported, but selected option is not available.') raise RetryableJobError('Product imported, but selected option is not available.')
if not opencart_attribute_value.odoo_id: if not opencart_attribute_value.odoo_id:
raise RetryableJobError('Order Product has option (%s) "%s" that is not mapped to an Odoo Attribute Value.' % (opencart_attribute_value.external_id, opencart_attribute_value.opencart_name)) raise RetryableJobError('Order Product (%s) has option (%s) "%s" that is not mapped to an Odoo Attribute Value.' % (self, opencart_attribute_value.external_id, opencart_attribute_value.opencart_name))
selected_attribute_values += opencart_attribute_value.odoo_id selected_attribute_values += opencart_attribute_value.odoo_id
# Now that we know what options are selected, we can load a variant with those options # Now that we know what options are selected, we can load a variant with those options
return self.odoo_id._create_product_variant(selected_attribute_values) return self.odoo_id._create_product_variant(selected_attribute_values)
@@ -43,6 +43,7 @@ class OpencartProductTemplate(models.Model):
class ProductTemplate(models.Model): class ProductTemplate(models.Model):
_inherit = 'product.template' _inherit = 'product.template'
opencart_sku = fields.Char('Opencart SKU')
opencart_bind_ids = fields.One2many('opencart.product.template', 'odoo_id', string='Opencart Bindings') opencart_bind_ids = fields.One2many('opencart.product.template', 'odoo_id', string='Opencart Bindings')

View File

@@ -23,6 +23,10 @@ class ProductImportMapper(Component):
def product_type(self, record): def product_type(self, record):
return {'type': 'product' if record.get('shipping') else 'service'} return {'type': 'product' if record.get('shipping') else 'service'}
@mapping
def opencart_sku(self, record):
return {'opencart_sku': (record.get('sku') or '').strip()}
@only_create @only_create
@mapping @mapping
def existing_product(self, record): def existing_product(self, record):
@@ -30,6 +34,11 @@ class ProductImportMapper(Component):
template = product_template.browse() template = product_template.browse()
if record.get('sku'): if record.get('sku'):
sku = (record.get('sku') or '').strip()
# Try to match our own field
template = product_template.search([('opencart_sku', '=', sku)], limit=1)
if not template:
# Try to match the default_code
template = product_template.search([('default_code', '=', record.get('sku'))], limit=1) template = product_template.search([('default_code', '=', record.get('sku'))], limit=1)
if not template and record.get('model'): if not template and record.get('model'):
template = product_template.search([('default_code', '=', record.get('model'))], limit=1) template = product_template.search([('default_code', '=', record.get('model'))], limit=1)

View File

@@ -9,6 +9,9 @@ from odoo.addons.component.core import Component
from odoo.addons.connector.components.mapper import mapping from odoo.addons.connector.components.mapper import mapping
from odoo.exceptions import ValidationError from odoo.exceptions import ValidationError
import logging
_logger = logging.getLogger(__name__)
class SaleOrderBatchImporter(Component): class SaleOrderBatchImporter(Component):
_name = 'opencart.sale.order.batch.importer' _name = 'opencart.sale.order.batch.importer'
@@ -184,14 +187,21 @@ class SaleOrderImporter(Component):
return self.env['res.partner'].create(values) return self.env['res.partner'].create(values)
def _partner_matches(self, partner, values): def _partner_matches(self, partner, values):
_logger.warn('_partner_matches partner: ' + str(partner) + ' values: ' + str(values))
for key, value in values.items(): for key, value in values.items():
if key in ('active', 'parent_id'):
continue
if key == 'state_id': if key == 'state_id':
if value != partner.state_id.id: if value != partner.state_id.id:
_logger.warn(' return false for state_id value: ' + str(value) + ' partner.state_id.id: ' + str(partner.state_id.id))
return False return False
elif key == 'country_id': elif key == 'country_id':
if value != partner.country_id.id: if value != partner.country_id.id:
_logger.warn(' return false for country_id value: ' + str(value) + ' partner.country_id.id: ' + str(partner.country_id.id))
return False return False
elif bool(value) and value != getattr(partner, key): elif bool(value) and value != getattr(partner, key):
_logger.warn(' return false for ' + str(key) + ' : ' + str(value) + ' partner value: ' + str(getattr(partner, key)))
return False return False
return True return True
@@ -232,13 +242,13 @@ class SaleOrderImporter(Component):
], limit=1) ], limit=1)
return { return {
'email': email, 'email': email.strip(),
'name': name, 'name': name.strip(),
'phone': phone, 'phone': phone.strip(),
'street': street, 'street': street.strip(),
'street2': street2, 'street2': street2.strip(),
'zip': zip_, 'zip': zip_.strip(),
'city': city, 'city': city.strip(),
'state_id': state.id, 'state_id': state.id,
'country_id': country.id, 'country_id': country.id,
} }
@@ -247,9 +257,18 @@ class SaleOrderImporter(Component):
record = self.opencart_record record = self.opencart_record
partner_values = self._get_partner_values() partner_values = self._get_partner_values()
partner = self.env['res.partner'].search([ partners = self.env['res.partner'].search([
('email', '=', partner_values['email']), ('email', '=', partner_values['email']),
], limit=1) ])
partner = None
for possible in partners:
if self._partner_matches(possible, partner_values):
_logger.warn('matched partner: ' + str(possible))
partner = possible
break
if not partner and partners:
partner = partners[0]
if not partner: if not partner:
# create partner. # create partner.
@@ -260,18 +279,28 @@ class SaleOrderImporter(Component):
partner_values['active'] = False partner_values['active'] = False
shipping_partner = self._create_partner(copy(partner_values)) shipping_partner = self._create_partner(copy(partner_values))
else: else:
_logger.warn('same shipping partner')
shipping_partner = partner shipping_partner = partner
invoice_values = self._get_partner_values(info_string='payment_') invoice_values = self._get_partner_values(info_string='payment_')
if (not self._partner_matches(partner, invoice_values) if (not self._partner_matches(partner, invoice_values)
and not self._partner_matches(shipping_partner, invoice_values)): and not self._partner_matches(shipping_partner, invoice_values)):
# Try to find existing invoice address....
for possible in partners:
if self._partner_matches(possible, invoice_values):
_logger.warn('matched invoice partner: ' + str(possible))
invoice_partner = possible
break
else:
partner_values['parent_id'] = partner.id partner_values['parent_id'] = partner.id
partner_values['active'] = False partner_values['active'] = False
invoice_partner = self._create_partner(copy(invoice_values)) invoice_partner = self._create_partner(copy(invoice_values))
elif self._partner_matches(partner, invoice_values): elif self._partner_matches(partner, invoice_values):
_logger.warn('same invoice partner')
invoice_partner = partner invoice_partner = partner
elif self._partner_matches(shipping_partner, invoice_values): elif self._partner_matches(shipping_partner, invoice_values):
_logger.warn('same invoice shipping partner')
invoice_partner = shipping_partner invoice_partner = shipping_partner
self.partner = partner self.partner = partner

View File

@@ -25,4 +25,32 @@
</field> </field>
</record> </record>
<record id="view_opencart_product_template_tree" model="ir.ui.view">
<field name="name">opencart.product.template.tree</field>
<field name="model">opencart.product.template</field>
<field name="arch" type="xml">
<tree string="Opencart Products">
<field name="backend_id"/>
<field name="external_id" string="Opencart ID"/>
<field name="odoo_id" string="Product Template"/>
<field name="create_date"/>
<field name="write_date"/>
</tree>
</field>
</record>
<record id="action_opencart_product_template" model="ir.actions.act_window">
<field name="name">Opencart Products</field>
<field name="res_model">opencart.product.template</field>
<field name="view_type">form</field>
<field name="view_mode">tree,form</field>
<field name="view_id" ref="view_opencart_product_template_tree"/>
</record>
<menuitem id="menu_opencart_product"
name="Products"
parent="menu_opencart_root"
sequence="50"
action="action_opencart_product_template"/>
</odoo> </odoo>

View File

@@ -0,0 +1,15 @@
<?xml version="1.0" encoding="UTF-8" ?>
<odoo>
<record id="product_template_only_form_view_inherit" model="ir.ui.view">
<field name="name">product.template.product.form.inherit</field>
<field name="model">product.template</field>
<field name="inherit_id" ref="product.product_template_only_form_view"/>
<field name="arch" type="xml">
<xpath expr="//field[@name='barcode']" position="after">
<field name="opencart_sku"/>
</xpath>
</field>
</record>
</odoo>