Backend¶
Le backend pour une version (par exemple Magento 1.7) est représenté par une instance de la classe Backend
.
Chaque connecteur va aussi créer un connector.backend
qui permet aux utilisateurs d’inscrire leurs backends. Par exemple le connecteur Magento a un magento.backend
(_inherit
connector.backend_model.connector_backend
). Ce modèle contient un champ version
qui doit avoir la même lists de versions (avec exactement le même nom) que les instances de Backend
.
Exemple avec le connecteur Magento
# in magentoerpconnect/backend.py
magento = backend.Backend('magento')
""" Generic Magento Backend """
magento1700 = backend.Backend(parent=magento, version='1.7')
""" Magento Backend for version 1.7 """
# in magentoerpconnect/magento_model.py
class MagentoBackend(models.Model):
_name = 'magento.backend'
_description = 'Magento Backend'
_inherit = 'connector.backend'
_backend_type = 'magento'
@api.model
def _select_versions(self):
""" Available versions
Can be inherited to add custom versions.
"""
return [('1.7', 'Magento 1.7')]
# <snip>
version = fields.Selection(
selection='_select_versions',
string='Version',
required=True,
)
location = fields.Char(string='Location', required=True)
username = fields.Char(string='Username')
password = fields.Char(string='Password')
# <snip>
Dans le code ci-dessus, “1.7” est la clé de correspondance entre l’instance de Backend
(magento1700
) et l’enregistrement magento_backend
.
-
class
connector.backend.
Backend
(service=None, version=None, parent=None, registry=None)[source]¶ Bases :
object
Un backend représente un système avec lequel interagir, comme Magento, Prestashop, Redmine, …
Il possède trois propriétés :
-
service
¶ Le nom du service, par exemple “magento”
-
version
¶ La version du service. Par exemple “1.7”
-
parent
¶ Un backend parent. Lorsqu’aucune classe
ConnectorUnit
n’est trouvée pour un backend, elle est cherchée dans le parent.
La structure des Backends est la partie clé du framework, mais elle est plutôt simple.
- Une instance de
Backend
contient un registre de classesConnectorUnit
- Il peut renvoyer la classe
ConnectorUnit
à utiliser pour une tâche - Si aucune
ConnectorUnit
n’est inscrite pour une tâche, le parent direct est interrogé (et ainsi de suite)
Les Backends ont deux mécanismes différents d’extension. L’un est plus vertical (entre plusieurs versions) et l’autre est plus horizontal car il permet de modifier le comportement pour une version donnée du backend.
Pour l’exemple, disons que nous avons les versions suivantes de backend
<Magento> | ----------------- | | <Magento 1.7> <Magento 2.0> | <Magento with specific>
Et voici la façon dont elles sont déclarées en Python
magento = Backend('magento') magento1700 = Backend(parent=magento, version='1.7') magento2000 = Backend(parent=magento, version='2.0') magento_specific = Backend(parent=magento1700, version='1.7-specific')
Dans le graphe ci-dessus,
<Magento>
va contenir toutes les classes partagées entre toutes les versions. Chaque version de Magento (<Magento 1.7>
,<Magento 2.0>
) va utiliser les classes définies sur<Magento>
, sauf si elles ont inscrit leur propres classes. C’est la même chose pour<Magento avec specifique>
mais celui-ci contient des personnalisations qui sont spécifiques à une instance (typiquement pour mettre en place des mappeurs spécifiques à une instance).Voici comment inscrire des classes sur
<Magento>
et une autre sur<Magento 1.7>
@magento class Synchronizer(ConnectorUnit): _model_name = 'res.partner' @magento class Mapper(ConnectorUnit): _model_name = 'res.partner' @magento1700 class Synchronizer1700(Synchronizer): _model_name = 'res.partner'
Ici, la méthode
get_class()
appelé surmagento1700
renverraitmagento1700.get_class(Synchronizer, session, 'res.partner') # => Synchronizer1700 magento1700.get_class(Mapper, session, 'res.partner') # => Mapper
C’est le mécanisme d’extension verticale, il dit que chaque version fille est capable d’étendre ou remplacer le comportement de son parent.
Note
en utilisant le framework, vous n’aurez pas besoin d’appeler
get_class()
, habituellement vous appellerezconnector.connector.ConnectorEnvironment.get_connector_unit()
.L’extension verticale est celle que vous utiliserez probablement le plus, parce que la plupart des choses que vous modifierez concerne vos applications personnalisées ou des comportements différents selon les versions du backend.
Cependant il peut arriver que nous ayons besoin de changer le comportement d’un connecteur, en installant un module. Par exemple, imaginons que nous ayons déjà un
ImportMapper
pour les articles dans le Connecteur Magento. Nous créons un module (générique) pour gérer le catalogue d’une manière plus avancée. Nous redéfinissons unAdvancedImportMapper
qui devrait être utilisé quand le module est installé. Ceci est le mécanisme d’extension horizontal.Remplace une clase
ConnectorUnit
par une autre dans le backend@backend(replacing=ImportMapper) class AdvancedImportMapper(ImportMapper): _model_name = 'product.product'
Avertissement
L’extension horizontale devrait être utilisée de manière très occasionnelle et précautionneuse, car dès que deux modules voudront remplacer la même classe il y aura un conflit (qui nécessiterait de créer un troisième module pour lier les deux, le remplacement pouvant prendre un tuple de classes à remplacer et ceci étant exponentiel). Ce mécanisme ne devrait être utilisé que dans certains circonstances bien précises pour des modules génériques.
-
get_class
(base_class, session, model_name)[source]¶ Trouve une sous-classe correspondante à
base_class
dans les classes inscrites.Paramètres: - base_class (
connector.connector.MetaConnectorUnit
) – Classe (et sous-classe) à rechercher dans le registre - session (
connector.session.ConnectorSession
) – session en cours
- base_class (
-
register_class
(cls, replacing=None)[source]¶ Inscrit une classe dans le backend
Paramètres: - cls (
connector.connector.MetaConnectorUnit
) – la classe ConnectorUnit à inscrire - replacing (
connector.connector.MetaConnectorUnit
) – optionnel, la classe ConnectorUnit à remplacer
- cls (
-
service
-
Modèles du backend¶
-
class
connector.backend_model.
ConnectorBackend
(pool, cr)[source]¶ Bases :
openerp.models.AbstractModel
Une instance d’un backend externe auquel se synchroniser
Les backends doivent
_inherit
ce modèle dans les modules des connecteurs.-
get_backend
(*args, **kwargs)[source]¶ Pour un enregistrement d’un backend, renvoie l’instance appropriée de
Backend
.
-
name
¶ Champ chaîne de caractère basique, peut être limité en longeur, habituellement affiché comme ligne unique dans les clients
Paramètres:
-
version
¶ Paramètres: - selection – specifies the possible values for this field.
It is given as either a list of pairs (
value
,string
), or a model method, or a method name. - selection_add – provides an extension of the selection in the case
of an overridden field. It is a list of pairs (
value
,string
).
The attribute
selection
is mandatory except in the case of related fields or field extensions.- selection – specifies the possible values for this field.
It is given as either a list of pairs (
-
-
class
connector.backend_model.
ExternalBinding
(pool, cr)[source]¶ Bases :
openerp.models.AbstractModel
Un modèle abstrait pour une liaison à des enregistrements externes
Un binding externe est une liaison entre un backend et OpenERP. Par exemple, pour un partner, cela peut être
magento.res.partner
ou pour un article,magento.product
.Le modèle final sera un
_inherits
du modèle OpenERP et va_inherit
ce modèle.Il aura une relation vers l’enregistrement (via
_inherits
) et vers le modèle backend concret (par exemplemagento.backend
).Il contiendra également toutes les données relatives aux backend pour l’enregistrement.
Il nécessite d’implémenter au moins ces champs :
openerp_id
Le many2one vers l’enregistrement lié (utilisé par_inherits
).backend_id
Le many2one vers le backend (par exemplemagento.backend
).magento_id ou prestashop_id ou …
L’ID sur le backend.sync_date
Dernière date de synchronisationLa définition des relations dans
_columns
doit être faite dans les classes concrètes, parce que les relations elle-mêmes n’existent pas dans ce module.Par exemple, pour un
res.partner.category
depuis Magento, J’aurais (ceci est une consolidation de toutes les colonnes des modèles abstraits. Dansmagentoerpconnect
vous ne trouveriez pas ça)class MagentoResPartnerCategory(models.Model): _name = 'magento.res.partner.category' _inherits = {'res.partner.category': 'openerp_id'} openerp_id = fields.Many2one(comodel_name='res.partner.category', string='Partner Category', required=True, ondelete='cascade') backend_id = fields.Many2one( comodel_name='magento.backend', string='Magento Backend', required=True, ondelete='restrict') magento_id = fields.Char(string='ID on Magento') tax_class_id = fields.Integer(string='Tax Class ID') _sql_constraints = [ ('magento_uniq', 'unique(backend_id, magento_id)', 'Partner Tag with same ID on Magento already exists.'), ]
-
sync_date
¶
-