256 lines
6.6 KiB
ReStructuredText
256 lines
6.6 KiB
ReStructuredText
.. _concepts:
|
|
|
|
##################
|
|
Connector Concepts
|
|
##################
|
|
|
|
The framework to develop connectors is decoupled in small pieces of
|
|
codes interacting together. Each of them can be used or not in an
|
|
implementation.
|
|
|
|
An example of implementation is the `Odoo Magento Connector`_.
|
|
|
|
This document describes them from a high-level point of view and gives
|
|
pointers to more concrete 'how-to' or small tutorials.
|
|
|
|
.. _`Odoo Magento Connector`: http://www.odoo-magento-connector.com
|
|
|
|
******
|
|
Events
|
|
******
|
|
|
|
Reference: :ref:`api-event`
|
|
|
|
Events are hooks in Odoo on which we can plug some actions. They are
|
|
based on an Observer pattern.
|
|
|
|
The same event can be shared across several connectors, easing their
|
|
implementation.
|
|
For instance, the module connector_ecommerce_ which extends the
|
|
framework with common e-commerce capabilities, adds its own events
|
|
common to e-commerce.
|
|
|
|
A connectors developer is mostly interested by:
|
|
|
|
* adding and listening to events (see :ref:`api-event`)
|
|
|
|
.. _jobs-queue:
|
|
|
|
**********
|
|
Jobs Queue
|
|
**********
|
|
|
|
Reference: :ref:`api-queue`
|
|
|
|
This feature is part of a standalone addon, but is a prerequisite for
|
|
the connector framework.
|
|
|
|
The module is ``queue_job`` in https://github.com/OCA/queue.
|
|
|
|
A connectors developer is mostly interested by:
|
|
|
|
* Delay a job (see the decorator :py:func:`~odoo.addons.queue_job.job.job`)
|
|
|
|
|
|
*******
|
|
Backend
|
|
*******
|
|
|
|
Reference: :ref:`api-backend-model`
|
|
|
|
The Backend Model is what represents the external service / system we
|
|
synchronize with. The name on the backend indicates what is the collection the
|
|
Components will be registered into. Put another way: every backend has its own
|
|
collection of Components.
|
|
|
|
It must use an ``_inherit`` on ``connector.backend``.
|
|
|
|
``connector.backend`` inherits
|
|
:class:`odoo.addons.component.models.collection.Collection` which has a
|
|
:meth:`odoo.addons.component.models.collection.Collection.work_on` that will be
|
|
used as entrypoint for the component system. This method returns a
|
|
:class:`~odoo.addons.component.core.WorkContext`
|
|
|
|
***********
|
|
WorkContext
|
|
***********
|
|
|
|
Reference: :class:`~odoo.addons.component.core.WorkContext`
|
|
|
|
A :class:`~odoo.addons.component.core.WorkContext` is the work environment or
|
|
context that will be passed transversally through all the components. This is
|
|
also the entrypoint to the component system.
|
|
|
|
A connectors developer is mostly interested by:
|
|
|
|
* Get a Component from a WorkContext (:py:meth:`~odoo.addons.component.core.WorkContext.component`)
|
|
|
|
*********
|
|
Component
|
|
*********
|
|
|
|
Reference: :ref:`api-component`
|
|
|
|
:py:class:`~odoo.addons.component.core.Component` are pluggable classes used
|
|
for the synchronizations with the external systems (or anything!)
|
|
|
|
The Components system has been extracted in a standalone addon (``component``),
|
|
which means it can really be used in a totally different way.
|
|
|
|
The connector defines some base components, which you can find below. Note
|
|
that you can and are encouraged to define your own Components as well.
|
|
|
|
Mappings
|
|
========
|
|
|
|
The base class is :py:class:`connector.components.mapper.Mapper`.
|
|
|
|
In your components, you probably want to inherit from:
|
|
|
|
* ``_inherit = 'base.import.mapper'``
|
|
* ``_inherit = 'base.export.mapper'``
|
|
|
|
And the usages for the lookups are:
|
|
|
|
* ``import.mapper``
|
|
* ``export.mapper``
|
|
|
|
A mapping translates an external record to an Odoo record and
|
|
conversely.
|
|
|
|
It supports:
|
|
|
|
direct mappings
|
|
Fields *a* is written in field *b*.
|
|
|
|
method mappings
|
|
A method is used to convert one or many fields to one or many
|
|
fields, with transformation.
|
|
It can be filtered, for example only applied when the record is
|
|
created or when the source fields are modified.
|
|
|
|
submapping
|
|
a sub-record (lines of a sale order) is converted using another
|
|
Mapper
|
|
|
|
See the documentation of the class for more details.
|
|
|
|
Synchronizers
|
|
=============
|
|
|
|
The base class is :py:class:`connector.components.synchronizer.Synchronizer`.
|
|
|
|
In your components, you probably want to inherit from:
|
|
|
|
* ``_inherit = 'base.importer'``
|
|
* ``_inherit = 'base.exporter'``
|
|
|
|
And the usages for the lookups are:
|
|
|
|
* ``importer``
|
|
* ``exporter``
|
|
|
|
However, in your implementation, it is advised to use more refined usages such
|
|
as:
|
|
|
|
* ``record.importer``
|
|
* ``record.exporter``
|
|
* ``batch.importer``
|
|
* ``batch.exporter``
|
|
* ..
|
|
|
|
A synchronizer orchestrates a synchronization with a backend. It can be a
|
|
record's import or export, a deletion of something, or anything else. For
|
|
instance, it will use the mappings to convert the data between both systems,
|
|
the backend adapters to read or write data on the backend and the binders to
|
|
create the link between them.
|
|
|
|
Backend Adapters
|
|
================
|
|
|
|
The base class is
|
|
:py:class:`connector.components.backend_adapter.BackendAdapter`.
|
|
|
|
In your components, you probably want to inherit from:
|
|
|
|
* ``_inherit = 'base.backend.adapter'``
|
|
* ``_inherit = 'base.backend.adapter.crud'``
|
|
|
|
And the usages for the lookups are:
|
|
|
|
* ``backend.adapter``
|
|
|
|
An external adapter has a common interface to speak with the backend.
|
|
It translates the basic orders (search, read, write) to the protocol
|
|
used by the backend.
|
|
|
|
Binders
|
|
=======
|
|
|
|
The base class is
|
|
:py:class:`connector.components.binder.Binder`.
|
|
|
|
In your components, you probably want to inherit from:
|
|
|
|
* ``_inherit = 'base.binder'``
|
|
|
|
And the usages for the lookups are:
|
|
|
|
* ``binder``
|
|
|
|
Binders are components that know how to find the external ID for an
|
|
Odoo ID, how to find the Odoo ID for an external ID and how to
|
|
create the binding between them. A default implementation is
|
|
available and can be inherited if needed.
|
|
|
|
Listeners
|
|
=========
|
|
|
|
The base class is
|
|
:py:class:`connector.components.listener.ConnectorListener`.
|
|
|
|
In your components, you probably want to inherit from:
|
|
|
|
* ``_inherit = 'base.connector.listener'``
|
|
|
|
This is where you will register your event listeners.
|
|
See :mod:`addons.component_event.components.event`.
|
|
|
|
|
|
.. _binding:
|
|
|
|
********
|
|
Bindings
|
|
********
|
|
|
|
Reference: :ref:`api-binding-model`
|
|
|
|
A binding represents the link of a record between Odoo and a backend.
|
|
|
|
The proposed implementation for the connectors widely use the
|
|
`_inherits` capabilities.
|
|
|
|
Say we import a customer from *Magento*.
|
|
|
|
We create a `magento.res.partner` model, which `_inherits`
|
|
`res.partner`.
|
|
|
|
This model, called a *binding* model, knows the ID of the partner in
|
|
Odoo, the ID in Magento and the relation to the backend model.
|
|
|
|
It also stores all the necessary metadata related to this customer
|
|
coming from Magento.
|
|
|
|
.. _checkpoint:
|
|
|
|
**********
|
|
Checkpoint
|
|
**********
|
|
|
|
A checkpoint is a record in the model `connector.checkpoint` linked to a
|
|
model and a record, the connectors can create a new one when the user
|
|
needs to review imported documents.
|
|
|
|
|
|
.. _connector_ecommerce: https://github.com/OCA/connector-ecommerce
|