141 lines
		
	
	
		
			4.9 KiB
		
	
	
	
		
			Python
		
	
	
			
		
		
	
	
			141 lines
		
	
	
		
			4.9 KiB
		
	
	
	
		
			Python
		
	
	
| # -*- coding: utf-8 -*-
 | |
| # Copyright 2013-2017 Camptocamp SA
 | |
| # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html)
 | |
| 
 | |
| """
 | |
| Binders
 | |
| =======
 | |
| 
 | |
| 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.
 | |
| 
 | |
| """
 | |
| 
 | |
| from odoo import fields, models, tools
 | |
| from odoo.addons.component.core import AbstractComponent
 | |
| 
 | |
| 
 | |
| class Binder(AbstractComponent):
 | |
|     """ For one record of a model, capable to find an external or
 | |
|     internal id, or create the binding (link) between them
 | |
| 
 | |
|     This is a default implementation that can be inherited or reimplemented
 | |
|     in the connectors.
 | |
| 
 | |
|     This implementation assumes that binding models are ``_inherits`` of
 | |
|     the models they are binding.
 | |
| 
 | |
|     """
 | |
| 
 | |
|     _name = 'base.binder'
 | |
|     _inherit = 'base.connector'
 | |
|     _usage = 'binder'
 | |
| 
 | |
|     _external_field = 'external_id'  # override in sub-classes
 | |
|     _backend_field = 'backend_id'  # override in sub-classes
 | |
|     _odoo_field = 'odoo_id'  # override in sub-classes
 | |
|     _sync_date_field = 'sync_date'  # override in sub-classes
 | |
| 
 | |
|     def to_internal(self, external_id, unwrap=False):
 | |
|         """ Give the Odoo recordset for an external ID
 | |
| 
 | |
|         :param external_id: external ID for which we want
 | |
|                             the Odoo ID
 | |
|         :param unwrap: if True, returns the normal record
 | |
|                        else return the binding record
 | |
|         :return: a recordset, depending on the value of unwrap,
 | |
|                  or an empty recordset if the external_id is not mapped
 | |
|         :rtype: recordset
 | |
|         """
 | |
|         bindings = self.model.with_context(active_test=False).search(
 | |
|             [(self._external_field, '=', tools.ustr(external_id)),
 | |
|              (self._backend_field, '=', self.backend_record.id)]
 | |
|         )
 | |
|         if not bindings:
 | |
|             if unwrap:
 | |
|                 return self.model.browse()[self._odoo_field]
 | |
|             return self.model.browse()
 | |
|         bindings.ensure_one()
 | |
|         if unwrap:
 | |
|             bindings = bindings[self._odoo_field]
 | |
|         return bindings
 | |
| 
 | |
|     def to_external(self, binding, wrap=False):
 | |
|         """ Give the external ID for an Odoo binding ID
 | |
| 
 | |
|         :param binding: Odoo binding for which we want the external id
 | |
|         :param wrap: if True, binding is a normal record, the
 | |
|                      method will search the corresponding binding and return
 | |
|                      the external id of the binding
 | |
|         :return: external ID of the record
 | |
|         """
 | |
|         if isinstance(binding, models.BaseModel):
 | |
|             binding.ensure_one()
 | |
|         else:
 | |
|             binding = self.model.browse(binding)
 | |
|         if wrap:
 | |
|             binding = self.model.with_context(active_test=False).search(
 | |
|                 [(self._odoo_field, '=', binding.id),
 | |
|                  (self._backend_field, '=', self.backend_record.id),
 | |
|                  ]
 | |
|             )
 | |
|             if not binding:
 | |
|                 return None
 | |
|             binding.ensure_one()
 | |
|             return binding[self._external_field]
 | |
|         return binding[self._external_field]
 | |
| 
 | |
|     def bind(self, external_id, binding):
 | |
|         """ Create the link between an external ID and an Odoo ID
 | |
| 
 | |
|         :param external_id: external id to bind
 | |
|         :param binding: Odoo record to bind
 | |
|         :type binding: int
 | |
|         """
 | |
|         # Prevent False, None, or "", but not 0
 | |
|         assert (external_id or external_id is 0) and binding, (
 | |
|             "external_id or binding missing, "
 | |
|             "got: %s, %s" % (external_id, binding)
 | |
|         )
 | |
|         # avoid to trigger the export when we modify the `external_id`
 | |
|         now_fmt = fields.Datetime.now()
 | |
|         if isinstance(binding, models.BaseModel):
 | |
|             binding.ensure_one()
 | |
|         else:
 | |
|             binding = self.model.browse(binding)
 | |
|         binding.with_context(connector_no_export=True).write(
 | |
|             {self._external_field: tools.ustr(external_id),
 | |
|              self._sync_date_field: now_fmt,
 | |
|              })
 | |
| 
 | |
|     def unwrap_binding(self, binding):
 | |
|         """ For a binding record, gives the normal record.
 | |
| 
 | |
|         Example: when called with a ``magento.product.product`` id,
 | |
|         it will return the corresponding ``product.product`` id.
 | |
| 
 | |
|         :param browse: when True, returns a browse_record instance
 | |
|                        rather than an ID
 | |
|         """
 | |
|         if isinstance(binding, models.BaseModel):
 | |
|             binding.ensure_one()
 | |
|         else:
 | |
|             binding = self.model.browse(binding)
 | |
| 
 | |
|         return binding[self._odoo_field]
 | |
| 
 | |
|     def unwrap_model(self):
 | |
|         """ For a binding model, gives the normal model.
 | |
| 
 | |
|         Example: when called on a binder for ``magento.product.product``,
 | |
|         it will return ``product.product``.
 | |
|         """
 | |
|         try:
 | |
|             column = self.model._fields[self._odoo_field]
 | |
|         except KeyError:
 | |
|             raise ValueError(
 | |
|                 'Cannot unwrap model %s, because it has no %s fields'
 | |
|                 % (self.model._name, self._odoo_field))
 | |
|         return column.comodel_name
 |