Skip to content

Commit

Permalink
[WIP] add configurable inheritage
Browse files Browse the repository at this point in the history
  • Loading branch information
PierrickBrun committed Oct 10, 2017
1 parent f02affb commit ffe6c51
Show file tree
Hide file tree
Showing 9 changed files with 273 additions and 0 deletions.
44 changes: 44 additions & 0 deletions connector_magento/models/product/importer.py
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,44 @@ def run(self, external_id, binding):
self._write_image_data(binding, binary, image_data)


class ConfigurableImporter(Component):
""" Can be inherited to change the way the configurable products are
imported.
called at the end of the import of a product.
By default, the configurable products are imported as simple products, the
configurable product is skipped and his children are imported separately.
If you want to create a custom importer for the configurables, you have to
inherit the Component::
class ConfigurableImporter(Component):
_inherit = 'magento.product.configurable.importer'
And to bypass the _must_skip::
class ProductImporter(Component):
_inherit = 'magento.product.product.importer'
def _must_skip(self):
res = super(ProductImporter, self)._must_skip()
if self.magento_record['type_id'] != 'configurable':
return res
"""
_name = 'magento.product.configurable.importer'
_inherit = 'magento.importer'
_apply_on = ['magento.product.product']
_usage = 'product.configurable.importer'

def run(self, binding, magento_record):
print('BBB')
""" import the configurable information about a product.
:param magento_record: product information from Magento
"""


# TODO: not needed, use inheritance
class BundleImporter(Component):
""" Can be inherited to change the way the bundle products are
Expand Down Expand Up @@ -329,6 +367,12 @@ def _after_import(self, binding):
bundle_importer = self.component(usage='product.bundle.importer')
bundle_importer.run(binding, self.magento_record)

if self.magento_record['type_id'] == 'configurable':
configurable_importer = self.component(
usage='product.configurable.importer')
configurable_importer.run(binding, self.magento_record)
raise InvalidDataError('THE END')


class ProductInventoryExporter(Component):
_name = 'magento.product.product.exporter'
Expand Down
37 changes: 37 additions & 0 deletions connector_magento_configurable/README.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
.. image:: https://img.shields.io/badge/licence-AGPL--3-blue.svg
:target: http://www.gnu.org/licenses/agpl-3.0-standalone.html
:alt: License: AGPL-3

====================================================
Magento Connector - Configurable Product
====================================================

This modules aims to create configurable products as Product templates and
linked ProductProduct and not flat ProductProduct

Installation
============

Bug Tracker
===========

#Bugs are tracked on `GitHub Issues
#<https://github.com/OCA/connector-magento/issues>`_. In case of trouble, please
#check there if your issue has already been reported. If you spotted it first,
#help us smashing it by providing a detailed and welcomed feedback.

Credits
=======

Images
------

* Odoo Community Association: `Icon <https://github.com/OCA/maintainer-tools/blob/master/template/module/static/description/icon.svg>`_.

Contributors
------------


Maintainer
----------

2 changes: 2 additions & 0 deletions connector_magento_configurable/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
# -*- coding: utf-8 -*-
from . import models
14 changes: 14 additions & 0 deletions connector_magento_configurable/__manifest__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
# -*- coding: utf-8 -*-
# Copyright 2017 Camptocamp SA
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html)

{'name': 'Magento Connector - Configurable',
'version': '10.0.1.0.0',
'author': 'Akretion,Odoo Community Association (OCA)',
'license': 'AGPL-3',
'category': 'Hidden',
'depends': ['connector_magento'],
'data': [],
'installable': True,
'auto_install': True,
}
3 changes: 3 additions & 0 deletions connector_magento_configurable/models/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
# -*- coding: utf-8 -*-
from . import configurable
from . import product_attribute
28 changes: 28 additions & 0 deletions connector_magento_configurable/models/configurable.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
# -*- coding: utf-8 -*-
# Copyright 2017 Camptocamp SA
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html)

from odoo.addons.component.core import Component
# from odoo.addons.connector.components.mapper import mapping
from odoo.addons.connector.exception import InvalidDataError


class ConfigurableImporter(Component):
_inherit = 'magento.product.configurable.importer'

def run(self, binding, magento_record):
super(ConfigurableImporter, self).run(
binding,
magento_record)

# ne pas enlever pour dev
raise InvalidDataError('THE END', magento_record)


class ProductImporter(Component):
_inherit = 'magento.product.product.importer'

def _must_skip(self):
res = super(ProductImporter, self)._must_skip()
if self.magento_record['type_id'] != 'configurable':
return res
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
# -*- coding: utf-8 -*-
from . import common
from . import importer
64 changes: 64 additions & 0 deletions connector_magento_configurable/models/product_attribute/common.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
# -*- coding: utf-8 -*-
# Copyright 2013-2017 Camptocamp SA
# © 2016 Sodexis
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).

import logging
import xmlrpclib
from odoo import models, fields
from odoo.addons.connector.exception import IDMissingInBackend
from odoo.addons.component.core import Component

_logger = logging.getLogger(__name__)


class MagentoProductAttribute(models.Model):
_name = 'magento.product.attribute'
_inherit = 'magento.binding'
_inherits = {'product.attribute': 'odoo_id'}
_description = 'Magento Product Attribute'

odoo_id = fields.Many2one(
comodel_name='product.attribute',
string='Product Attribute',
required=True,
ondelete='cascade')
name = fields.Text(translate=True)


class ProductAttribute(models.Model):
_inherit = 'product.attribute'

magento_bind_ids = fields.One2many(
comodel_name='magento.product.attribute',
inverse_name='odoo_id',
string="Magento Bindings",
)


class ProductAttributeAdapter(Component):
_name = 'magento.product.attribute.adapter'
_inherit = 'magento.adapter'
_apply_on = 'magento.product.attribute'

_magento_model = 'ol_catalog_product_link'
_admin_path = '/{model}/index/'

def _call(self, method, arguments):
try:
return super(ProductAttributeAdapter, self)._call(method, arguments)
except xmlrpclib.Fault as err:
# 101 is the error in the Magento API
# when the attribute does not exist
if err.faultCode == 102:
raise IDMissingInBackend
else:
raise

def list_attributes(self, id, storeview_id=None, attributes=None):
""" Returns the information of a record
:rtype: dict
"""
return self._call('%s.listSuperAttributes' % self._magento_model,
[int(id), storeview_id, attributes])
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
# -*- coding: utf-8 -*-
# Copyright 2013-2017 Camptocamp SA
# © 2016 Sodexis
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html)

from odoo.addons.component.core import Component
from odoo.addons.connector.components.mapper import mapping
# from odoo.addons.connector.exception import MappingError


class ProductAttributeBatchImporter(Component):
""" Import the Magento Product Attributes.
For every product attribute in the list, a delayed job is created.
A priority is set on the jobs according to their level to rise the
chance to have the top level attributes imported first.
"""
_name = 'magento.product.attribute.batch.importer'
_inherit = 'magento.delayed.batch.importer'
_apply_on = ['magento.product.attribute']

def _import_record(self, external_id, job_options=None):
""" Delay a job for the import """
super(ProductAttributeBatchImporter, self)._import_record(
external_id, job_options=job_options
)

def run(self, filters=None):
""" Run the synchronization """
updated_ids = self.backend_adapter.listSuperAttributes()

base_priority = 10

def import_nodes(tree, level=0):
for node_id, children in tree.iteritems():
# By changing the priority, the top level attribute has
# more chance to be imported before the childrens.
# However, importers have to ensure that their parent is
# there and import it if it doesn't exist
if updated_ids is None or node_id in updated_ids:
job_options = {
'priority': base_priority + level,
}
self._import_record(
node_id, job_options=job_options)
import_nodes(children, level=level + 1)
tree = self.backend_adapter.tree()
import_nodes(tree)


class ProductAttributeImporter(Component):
_name = 'magento.product.attribute.importer'
_inherit = 'magento.importer'
_apply_on = ['magento.product.attribute']

def _create(self, data):
binding = super(ProductAttributeImporter, self)._create(data)
self.backend_record.add_checkpoint(binding)
return binding

def _after_import(self, binding):
""" Hook called at the end of the import """
translation_importer = self.component(usage='translation.importer')
translation_importer.run(self.external_id, binding)


class ProductAttributeImportMapper(Component):
_name = 'magento.product.attribute.import.mapper'
_inherit = 'magento.import.mapper'
_apply_on = 'magento.product.attribute'

direct = [
('name', 'name'),
]

@mapping
def backend_id(self, record):
return {'backend_id': self.backend_record.id}

0 comments on commit ffe6c51

Please sign in to comment.