diff --git a/dev/odoo-server-dev-aa.conf b/dev/odoo-server-dev-aa.conf index a9bf5a9a..ad8880a1 100644 --- a/dev/odoo-server-dev-aa.conf +++ b/dev/odoo-server-dev-aa.conf @@ -15,3 +15,12 @@ timezone = Europe/Vienna #dbfilter_test = ['.*',] show_debug = 1 + +workers = 0 +server_wide_modules = web,base_sparse_field,queue_job + +portal_url = https://erp.tzaustria.info +portal_secret = secret + +[queue_job] +channels = root:4 diff --git a/ext/3rd-party-addons/component/README.rst b/ext/3rd-party-addons/component/README.rst new file mode 100644 index 00000000..9a6a4088 --- /dev/null +++ b/ext/3rd-party-addons/component/README.rst @@ -0,0 +1,90 @@ +.. image:: https://img.shields.io/badge/licence-AGPL--3-blue.svg + :target: http://www.gnu.org/licenses/agpl + :alt: License: AGPL-3 + +========== +Components +========== + +This module implements a component system and is a base block for the Connector +Framework. It can be used without using the full Connector though. + +Documentation: http://odoo-connector.com/ + +Installation +============ + +* Install ``component`` + +Configuration +============= + +The module does nothing by itself and has no configuration. + +Usage +===== + +As a developer, you have access to a component system. You can find the +documentation in the code or on http://odoo-connector.com + +In a nutshell, you can create components:: + + + from odoo.addons.component.core import Component + + class MagentoPartnerAdapter(Component): + _name = 'magento.partner.adapter' + _inherit = 'magento.adapter' + + _usage = 'backend.adapter' + _collection = 'magento.backend' + _apply_on = ['res.partner'] + +And later, find the component you need at runtime (dynamic dispatch at +component level):: + + def run(self, external_id): + backend_adapter = self.component(usage='backend.adapter') + external_data = backend_adapter.read(external_id) + + +Known issues / Roadmap +====================== + +Bug Tracker +=========== + +Bugs are tracked on `GitHub Issues +`_. In case of trouble, please +check there if your issue has already been reported. If you spotted it first, +help us smash it by providing detailed and welcomed feedback. + +Credits +======= + +Images +------ + +* Odoo Community Association: `Icon `_. + +Contributors +------------ + +* Guewen Baconnier + +Do not contact contributors directly about support or help with technical issues. + +Maintainer +---------- + +.. image:: https://odoo-community.org/logo.png + :alt: Odoo Community Association + :target: https://odoo-community.org + +This module is maintained by the OCA. + +OCA, or the Odoo Community Association, is a nonprofit organization whose +mission is to support the collaborative development of Odoo features and +promote its widespread use. + +To contribute to this module, please visit https://odoo-community.org. diff --git a/ext/3rd-party-addons/component/__init__.py b/ext/3rd-party-addons/component/__init__.py new file mode 100644 index 00000000..afa4a292 --- /dev/null +++ b/ext/3rd-party-addons/component/__init__.py @@ -0,0 +1,6 @@ +# -*- coding: utf-8 -*- +from . import core + +from . import components +from . import builder +from . import models diff --git a/ext/3rd-party-addons/component/__manifest__.py b/ext/3rd-party-addons/component/__manifest__.py new file mode 100644 index 00000000..5601832a --- /dev/null +++ b/ext/3rd-party-addons/component/__manifest__.py @@ -0,0 +1,19 @@ +# -*- coding: utf-8 -*- +# Copyright 2017 Camptocamp SA +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html) + +{'name': 'Components', + 'version': '11.0.1.0.0', + 'author': 'Camptocamp,' + 'Odoo Community Association (OCA)', + 'website': 'https://www.camptocamp.com', + 'license': 'AGPL-3', + 'category': 'Generic Modules', + 'depends': ['base', + ], + 'external_dependencies': { + 'python': ['cachetools'], + }, + 'data': [], + 'installable': True, + } diff --git a/ext/3rd-party-addons/component/builder.py b/ext/3rd-party-addons/component/builder.py new file mode 100644 index 00000000..7e537755 --- /dev/null +++ b/ext/3rd-party-addons/component/builder.py @@ -0,0 +1,107 @@ +# -*- coding: utf-8 -*- +# Copyright 2017 Camptocamp SA +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html) + +""" + +Components Builder +================== + +Build the components at the build of a registry. + +""" +import odoo +from odoo import api, models +from .core import ( + _component_databases, + ComponentRegistry, + DEFAULT_CACHE_SIZE, +) + + +class ComponentBuilder(models.AbstractModel): + """ Build the component classes + + And register them in a global registry. + + Every time an Odoo registry is built, the know components are cleared and + rebuilt as well. The Component classes are built using the same mechanism + than Odoo's Models: a final class is created, taking every Components with + a ``_name`` and applying Components with an ``_inherits`` upon them. + + The final Component classes are registered in global registry. + + This class is an Odoo model, allowing us to hook the build of the + components at the end of the Odoo's registry loading, using + ``_register_hook``. This method is called after all modules are loaded, so + we are sure that we have all the components Classes and in the correct + order. + + """ + _name = 'component.builder' + _description = 'Component Builder' + + _components_registry_cache_size = DEFAULT_CACHE_SIZE + + @api.model_cr + def _register_hook(self): + # This method is called by Odoo when the registry is built, + # so in case the registry is rebuilt (cache invalidation, ...), + # we have to to rebuild the components. We use a new + # registry so we have an empty cache and we'll add components in it. + components_registry = self._init_global_registry() + self.build_registry(components_registry) + components_registry.ready = True + + def _init_global_registry(self): + components_registry = ComponentRegistry( + cachesize=self._components_registry_cache_size + ) + _component_databases[self.env.cr.dbname] = components_registry + return components_registry + + def build_registry(self, components_registry, states=None, + exclude_addons=None): + if not states: + states = ('installed', 'to upgrade') + # lookup all the installed (or about to be) addons and generate + # the graph, so we can load the components following the order + # of the addons' dependencies + graph = odoo.modules.graph.Graph() + graph.add_module(self.env.cr, 'base') + + query = ( + "SELECT name " + "FROM ir_module_module " + "WHERE state IN %s " + ) + params = [tuple(states)] + if exclude_addons: + query += " AND name NOT IN %s " + params.append(tuple(exclude_addons)) + self.env.cr.execute(query, params) + + module_list = [name for (name,) in self.env.cr.fetchall() + if name not in graph] + graph.add_modules(self.env.cr, module_list) + + for module in graph: + self.load_components(module.name, + components_registry=components_registry) + + def load_components(self, module, components_registry=None): + """ Build every component known by MetaComponent for an odoo module + + The final component (composed by all the Component classes in this + module) will be pushed into the registry. + + :param module: the name of the addon for which we want to load + the components + :type module: str | unicode + :param registry: the registry in which we want to put the Component + :type registry: :py:class:`~.core.ComponentRegistry` + """ + components_registry = ( + components_registry or + _component_databases[self.env.cr.dbname]) + components_registry.load_components(module) diff --git a/ext/3rd-party-addons/component/components/__init__.py b/ext/3rd-party-addons/component/components/__init__.py new file mode 100644 index 00000000..a61d43eb --- /dev/null +++ b/ext/3rd-party-addons/component/components/__init__.py @@ -0,0 +1,2 @@ +# -*- coding: utf-8 -*- +from . import base diff --git a/ext/3rd-party-addons/component/components/base.py b/ext/3rd-party-addons/component/components/base.py new file mode 100644 index 00000000..081b6a15 --- /dev/null +++ b/ext/3rd-party-addons/component/components/base.py @@ -0,0 +1,15 @@ +# -*- coding: utf-8 -*- +# Copyright 2017 Camptocamp SA +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html) + +from ..core import AbstractComponent + + +class BaseComponent(AbstractComponent): + """ This is the base component for every component + + It is implicitely inherited by all components. + + All your base are belong to us + """ + _name = 'base' diff --git a/ext/3rd-party-addons/component/core.py b/ext/3rd-party-addons/component/core.py new file mode 100644 index 00000000..87761a93 --- /dev/null +++ b/ext/3rd-party-addons/component/core.py @@ -0,0 +1,857 @@ +# -*- coding: utf-8 -*- +# Copyright 2017 Camptocamp SA +# Copyright 2017 Odoo +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html) + +""" + +Core +==== + +Core classes for the components. +The most common classes used publicly are: + +* :class:`Component` +* :class:`AbstractComponent` +* :class:`WorkContext` + +""" + +import logging +import operator + +from collections import defaultdict, OrderedDict + +from odoo import models +from odoo.tools import OrderedSet, LastOrderedSet +from .exception import NoComponentError, SeveralComponentError + + +_logger = logging.getLogger(__name__) + +try: + from cachetools import LRUCache, cachedmethod +except ImportError: + _logger.debug("Cannot import 'cachetools'.") + + +# The Cache size represents the number of items, so the number +# of components (include abstract components) we will keep in the LRU +# cache. We would need stats to know what is the average but this is a bit +# early. +DEFAULT_CACHE_SIZE = 512 + + +# this is duplicated from odoo.models.MetaModel._get_addon_name() which we +# unfortunately can't use because it's an instance method and should have been +# a @staticmethod +def _get_addon_name(full_name): + # The (Odoo) module name can be in the ``odoo.addons`` namespace + # or not. For instance, module ``sale`` can be imported as + # ``odoo.addons.sale`` (the right way) or ``sale`` (for backward + # compatibility). + module_parts = full_name.split('.') + if len(module_parts) > 2 and module_parts[:2] == ['odoo', 'addons']: + addon_name = full_name.split('.')[2] + else: + addon_name = full_name.split('.')[0] + return addon_name + + +class ComponentDatabases(dict): + """ Holds a registry of components for each database """ + + +class ComponentRegistry(object): + """ Store all the components and allow to find them using criteria + + The key is the ``_name`` of the components. + + This is an OrderedDict, because we want to keep the registration order of + the components, addons loaded first have their components found first. + + The :attr:`ready` attribute must be set to ``True`` when all the components + are loaded. + + """ + + def __init__(self, cachesize=DEFAULT_CACHE_SIZE): + self._cache = LRUCache(maxsize=cachesize) + self._components = OrderedDict() + self._loaded_modules = set() + self.ready = False + + def __getitem__(self, key): + return self._components[key] + + def __setitem__(self, key, value): + self._components[key] = value + + def __contains__(self, key): + return key in self._components + + def get(self, key, default=None): + return self._components.get(key, default) + + def __iter__(self): + return iter(self._components) + + def load_components(self, module): + if module in self._loaded_modules: + return + for component_class in MetaComponent._modules_components[module]: + component_class._build_component(self) + self._loaded_modules.add(module) + + @cachedmethod(operator.attrgetter('_cache')) + def lookup(self, collection_name=None, usage=None, model_name=None): + """ Find and return a list of components for a usage + + If a component is not registered in a particular collection (no + ``_collection``), it might will be returned in any case (as far as + the ``usage`` and ``model_name`` match). This is useful to share + generic components across different collections. + + If no collection name is given, components from any collection + will be returned. + + Then, the components of a collection are filtered by usage and/or + model. The ``_usage`` is mandatory on the components. When the + ``_model_name`` is empty, it means it can be used for every models, + and it will ignore the ``model_name`` argument. + + The abstract components are never returned. + + This is a rather low-level function, usually you will use the + high-level :meth:`AbstractComponent.component`, + :meth:`AbstractComponent.many_components` or even + :meth:`AbstractComponent.component_by_name`. + + :param collection_name: the name of the collection the component is + registered into. + :param usage: the usage of component we are looking for + :param model_name: filter on components that apply on this model + + """ + + # keep the order so addons loaded first have components used first + candidates = ( + component for component in self._components.values() + if not component._abstract + ) + + if collection_name is not None: + candidates = ( + component for component in candidates + if (component._collection == collection_name or + component._collection is None) + ) + + if usage is not None: + candidates = (component for component in candidates + if component._usage == usage) + + if model_name is not None: + candidates = (c for c in candidates + if c.apply_on_models is None or + model_name in c.apply_on_models) + + return list(candidates) + + +# We will store a ComponentRegistry per database here, +# it will be cleared and updated when the odoo's registry is rebuilt +_component_databases = ComponentDatabases() + + +class WorkContext(object): + """ Transport the context required to work with components + + It is propagated through all the components, so any + data or instance (like a random RPC client) that need + to be propagated transversally to the components + should be kept here. + + Including: + + .. attribute:: model_name + + Name of the model we are working with. It means that any lookup for a + component will be done for this model. It also provides a shortcut + as a `model` attribute to use directly with the Odoo model from + the components + + .. attribute:: collection + + The collection we are working with. The collection is an Odoo + Model that inherit from 'collection.base'. The collection attribute + can be a record or an "empty" model. + + .. attribute:: model + + Odoo Model for ``model_name`` with the same Odoo + :class:`~odoo.api.Environment` than the ``collection`` attribute. + + This is also the entrypoint to work with the components. + + :: + + collection = self.env['my.collection'].browse(1) + work = WorkContext(model_name='res.partner', collection=collection) + component = work.component(usage='record.importer') + + Usually you will use the context manager on the ``collection.base`` Model: + + :: + + collection = self.env['my.collection'].browse(1) + with collection.work_on('res.partner') as work: + component = work.component(usage='record.importer') + + It supports any arbitrary keyword arguments that will become attributes of + the instance, and be propagated throughout all the components. + + :: + + collection = self.env['my.collection'].browse(1) + with collection.work_on('res.partner', hello='world') as work: + assert work.hello == 'world' + + When you need to work on a different model, a new work instance will be + created for you when you are using the high-level API. This is what + happens under the hood: + + :: + + collection = self.env['my.collection'].browse(1) + with collection.work_on('res.partner', hello='world') as work: + assert work.model_name == 'res.partner' + assert work.hello == 'world' + work2 = work.work_on('res.users') + # => spawn a new WorkContext with a copy of the attributes + assert work2.model_name == 'res.users' + assert work2.hello == 'world' + + """ + + def __init__(self, model_name=None, collection=None, + components_registry=None, **kwargs): + self.collection = collection + self.model_name = model_name + self.model = self.env[model_name] + # lookup components in an alternative registry, used by the tests + if components_registry is not None: + self.components_registry = components_registry + else: + dbname = self.env.cr.dbname + try: + self.components_registry = _component_databases[dbname] + except KeyError: + _logger.error( + 'No component registry for database %s. ' + 'Probably because the Odoo registry has not been built ' + 'yet.' + ) + raise + self._propagate_kwargs = [ + 'collection', + 'model_name', + 'components_registry', + ] + for attr_name, value in kwargs.items(): + setattr(self, attr_name, value) + self._propagate_kwargs.append(attr_name) + + @property + def env(self): + """ Return the current Odoo env + + This is the environment of the current collection. + """ + return self.collection.env + + def work_on(self, model_name=None, collection=None): + """ Create a new work context for another model keeping attributes + + Used when one need to lookup components for another model. + """ + kwargs = {attr_name: getattr(self, attr_name) + for attr_name in self._propagate_kwargs} + if collection is not None: + kwargs['collection'] = collection + if model_name is not None: + kwargs['model_name'] = model_name + return self.__class__(**kwargs) + + def _component_class_by_name(self, name): + components_registry = self.components_registry + component_class = components_registry.get(name) + if not component_class: + raise NoComponentError("No component with name '%s' found." % name) + return component_class + + def component_by_name(self, name, model_name=None): + """ Return a component by its name + + If the component exists, an instance of it will be returned, + initialized with the current :class:`WorkContext`. + + A :exc:`odoo.addons.component.exception.NoComponentError` is raised + if: + + * no component with this name exists + * the ``_apply_on`` of the found component does not match + with the current working model + + In the latter case, it can be an indication that you need to switch to + a different model, you can do so by providing the ``model_name`` + argument. + + """ + if isinstance(model_name, models.BaseModel): + model_name = model_name._name + component_class = self._component_class_by_name(name) + work_model = model_name or self.model_name + if (component_class._collection and + self.collection._name != component_class._collection): + raise NoComponentError( + "Component with name '%s' can't be used for collection '%s'." + (name, self.collection._name) + ) + + if (component_class.apply_on_models and + work_model not in component_class.apply_on_models): + if len(component_class.apply_on_models) == 1: + hint_models = "'%s'" % (component_class.apply_on_models[0],) + else: + hint_models = "" % ( + component_class.apply_on_models, + ) + raise NoComponentError( + "Component with name '%s' can't be used for model '%s'.\n" + "Hint: you might want to use: " + "component_by_name('%s', model_name=%s)" % + (name, work_model, name, hint_models) + ) + + if work_model == self.model_name: + work_context = self + else: + work_context = self.work_on(model_name) + return component_class(work_context) + + def _lookup_components(self, usage=None, model_name=None): + component_classes = self.components_registry.lookup( + self.collection._name, + usage=usage, + model_name=model_name, + ) + + return [cls for cls in component_classes if cls._component_match(self)] + + def component(self, usage=None, model_name=None): + """ Find a component by usage and model for the current collection + + It searches a component using the rules of + :meth:`ComponentRegistry.lookup`. When a component is found, + it initialize it with the current :class:`WorkContext` and returned. + + A :exc:`odoo.addons.component.exception.SeveralComponentError` is + raised if more than one component match for the provided + ``usage``/``model_name``. + + A :exc:`odoo.addons.component.exception.NoComponentError` is raised + if no component is found for the provided ``usage``/``model_name``. + + """ + if isinstance(model_name, models.BaseModel): + model_name = model_name._name + model_name = model_name or self.model_name + component_classes = self._lookup_components( + usage=usage, model_name=model_name + ) + if not component_classes: + raise NoComponentError( + "No component found for collection '%s', " + "usage '%s', model_name '%s'." % + (self.collection._name, usage, model_name) + ) + elif len(component_classes) > 1: + raise SeveralComponentError( + "Several components found for collection '%s', " + "usage '%s', model_name '%s'. Found: %r" % + (self.collection._name, usage or '', + model_name or '', component_classes) + ) + if model_name == self.model_name: + work_context = self + else: + work_context = self.work_on(model_name) + return component_classes[0](work_context) + + def many_components(self, usage=None, model_name=None): + """ Find many components by usage and model for the current collection + + It searches a component using the rules of + :meth:`ComponentRegistry.lookup`. When components are found, they + initialized with the current :class:`WorkContext` and returned as a + list. + + If no component is found, an empty list is returned. + + """ + if isinstance(model_name, models.BaseModel): + model_name = model_name._name + model_name = model_name or self.model_name + component_classes = self._lookup_components( + usage=usage, model_name=model_name + ) + if model_name == self.model_name: + work_context = self + else: + work_context = self.work_on(model_name) + return [comp(work_context) for comp in component_classes] + + def __str__(self): + return "WorkContext(%s, %s)" % (self.model_name, repr(self.collection)) + + __repr__ = __str__ + + +class MetaComponent(type): + """ Metaclass for Components + + Every new :class:`Component` will be added to ``_modules_components``, + that will be used by the component builder. + + """ + + _modules_components = defaultdict(list) + + def __init__(self, name, bases, attrs): + if not self._register: + self._register = True + super(MetaComponent, self).__init__(name, bases, attrs) + return + + if not hasattr(self, '_module'): + self._module = _get_addon_name(self.__module__) + + self._modules_components[self._module].append(self) + + @property + def apply_on_models(self): + # None means all models + if self._apply_on is None: + return None + # always return a list, used for the lookup + elif isinstance(self._apply_on, str): + return [self._apply_on] + return self._apply_on + + +class AbstractComponent(object, metaclass=MetaComponent): + """ Main Component Model + + All components have a Python inheritance either on + :class:`AbstractComponent` or either on :class:`Component`. + + Abstract Components will not be returned by lookups on components, however + they can be used as a base for other Components through inheritance (using + ``_inherit``). + + Inheritance mechanism + The inheritance mechanism is like the Odoo's one for Models. Each + component has a ``_name``. This is the absolute minimum in a Component + class. + + :: + + class MyComponent(Component): + _name = 'my.component' + + def speak(self, message): + print message + + Every component implicitly inherit from the `'base'` component. + + There are two close but distinct inheritance types, which look + familiar if you already know Odoo. The first uses ``_inherit`` with + an existing name, the name of the component we want to extend. With + the following example, ``my.component`` is now able to speak and to + yell. + + :: + + class MyComponent(Component): # name of the class does not matter + _inherit = 'my.component' + + def yell(self, message): + print message.upper() + + The second has a different ``_name``, it creates a new component, + including the behavior of the inherited component, but without + modifying it. In the following example, ``my.component`` is still able + to speak and to yell (brough by the previous inherit), but not to + sing. ``another.component`` is able to speak, to yell and to sing. + + :: + + class AnotherComponent(Component): + _name = 'another.component' + _inherit = 'my.component' + + def sing(self, message): + print message.upper() + + Registration and lookups + It is handled by 3 attributes on the class: + + _collection + The name of the collection where we want to register the + component. This is not strictly mandatory as a component can be + shared across several collections. But usually, you want to set a + collection to segregate the components for a domain. A collection + can be for instance ``magento.backend``. It is also the name of a + model that inherits from ``collection.base``. See also + :class:`~WorkContext` and + :class:`~odoo.addons.component.models.collection.Collection`. + + _apply_on + List of names or name of the Odoo model(s) for which the component + can be used. When not set, the component can be used on any model. + + _usage + The collection and the model (``_apply_on``) will help to filter + the candidate components according to our working context (e.g. I'm + working on ``magento.backend`` with the model + ``magento.res.partner``). The usage will define **what** kind of + task the component we are looking for serves to. For instance, it + might be ``record.importer``, ``export.mapper```... but you can be + as creative as you want. + + Now, to get a component, you'll likely use + :meth:`WorkContext.component` when you start to work with components + in your flow, but then from within your components, you are more + likely to use one of: + + * :meth:`component` + * :meth:`many_components` + * :meth:`component_by_name` (more rarely though) + + Declaration of some Components can look like:: + + class FooBar(models.Model): + _name = 'foo.bar.collection' + _inherit = 'collection.base' # this inherit is required + + + class FooBarBase(AbstractComponent): + _name = 'foo.bar.base' + _collection = 'foo.bar.collection' # name of the model above + + + class Foo(Component): + _name = 'foo' + _inherit = 'foo.bar.base' # we will inherit the _collection + _apply_on = 'res.users' + _usage = 'speak' + + def utter(self, message): + print message + + + class Bar(Component): + _name = 'bar' + _inherit = 'foo.bar.base' # we will inherit the _collection + _apply_on = 'res.users' + _usage = 'yell' + + def utter(self, message): + print message.upper() + '!!!' + + + class Vocalizer(Component): + _name = 'vocalizer' + _inherit = 'foo.bar.base' + _usage = 'vocalizer' + # can be used for any model + + def vocalize(action, message): + self.component(usage=action).utter(message) + + + And their usage:: + + >>> coll = self.env['foo.bar.collection'].browse(1) + >>> with coll.work_on('res.users') as work: + ... vocalizer = work.component(usage='vocalizer') + ... vocalizer.vocalize('speak', 'hello world') + ... + hello world + ... vocalizer.vocalize('yell', 'hello world') + HELLO WORLD!!! + + Hints: + + * If you want to create components without ``_apply_on``, choose a + ``_usage`` that will not conflict other existing components. + * Unless this is what you want and in that case you use + :meth:`many_components` which will return all components for a usage + with a matching or a not set ``_apply_on``. + * It is advised to namespace the names of the components (e.g. + ``magento.xxx``) to prevent conflicts between addons. + + """ + + _register = False + _abstract = True + + # used for inheritance + _name = None + _inherit = None + + # name of the collection to subscribe in + _collection = None + + # None means any Model, can be a list ['res.users', ...] + _apply_on = None + # component purpose ('import.mapper', ...) + _usage = None + + def __init__(self, work_context): + super(AbstractComponent, self).__init__() + self.work = work_context + + @classmethod + def _component_match(cls, work): + """ Evaluated on candidate components + + When a component lookup is done and candidate(s) have + been found for a usage, a final call is done on this method. + If the method return False, the candidate component is ignored. + + It can be used for instance to dynamically choose a component + according to a value in the :class:`WorkContext`. + + Beware, if the lookups from usage, model and collection are + cached, the calls to :meth:`_component_match` are executed + each time we get components. Heavy computation should be + avoided. + + :param work: the :class:`WorkContext` we are working with + + """ + return True + + @property + def collection(self): + """ Collection we are working with """ + return self.work.collection + + @property + def env(self): + """ Current Odoo environment, the one of the collection record """ + return self.work.env + + @property + def model(self): + """ The model instance we are working with """ + return self.work.model + + def component_by_name(self, name, model_name=None): + """ Return a component by its name + + Shortcut to meth:`~WorkContext.component_by_name` + """ + return self.work.component_by_name(name, model_name=model_name) + + def component(self, usage=None, model_name=None): + """ Return a component + + Shortcut to meth:`~WorkContext.component` + """ + return self.work.component(usage=usage, model_name=model_name) + + def many_components(self, usage=None, model_name=None): + """ Return several components + + Shortcut to meth:`~WorkContext.many_components` + """ + return self.work.many_components(usage=usage, model_name=model_name) + + def __str__(self): + return "Component(%s)" % self._name + + __repr__ = __str__ + + @classmethod + def _build_component(cls, registry): + """ Instantiate a given Component in the components registry. + + This method is called at the end of the Odoo's registry build. The + caller is :meth:`component.builder.ComponentBuilder.load_components`. + + It generates new classes, which will be the Component classes we will + be using. The new classes are generated following the inheritance + of ``_inherit``. It ensures that the ``__bases__`` of the generated + Component classes follow the ``_inherit`` chain. + + Once a Component class is created, it adds it in the Component Registry + (:class:`ComponentRegistry`), so it will be available for + lookups. + + At the end of new class creation, a hook method + :meth:`_complete_component_build` is called, so you can customize + further the created components. An example can be found in + :meth:`odoo.addons.connector.components.mapper.Mapper._complete_component_build` + + The following code is roughly the same than the Odoo's one for + building Models. + + """ + + # In the simplest case, the component's registry class inherits from + # cls and the other classes that define the component in a flat + # hierarchy. The registry contains the instance ``component`` (on the + # left). Its class, ``ComponentClass``, carries inferred metadata that + # is shared between all the component's instances for this registry + # only. + # + # class A1(Component): Component + # _name = 'a' / | \ + # A3 A2 A1 + # class A2(Component): \ | / + # _inherit = 'a' ComponentClass + # + # class A3(Component): + # _inherit = 'a' + # + # When a component is extended by '_inherit', its base classes are + # modified to include the current class and the other inherited + # component classes. + # Note that we actually inherit from other ``ComponentClass``, so that + # extensions to an inherited component are immediately visible in the + # current component class, like in the following example: + # + # class A1(Component): + # _name = 'a' Component + # / / \ \ + # class B1(Component): / A2 A1 \ + # _name = 'b' / \ / \ + # B2 ComponentA B1 + # class B2(Component): \ | / + # _name = 'b' \ | / + # _inherit = ['b', 'a'] \ | / + # ComponentB + # class A2(Component): + # _inherit = 'a' + + # determine inherited components + parents = cls._inherit + if isinstance(parents, str): + parents = [parents] + elif parents is None: + parents = [] + + if cls._name in registry and not parents: + raise TypeError('Component %r (in class %r) already exists. ' + 'Consider using _inherit instead of _name ' + 'or using a different _name.' % (cls._name, cls)) + + # determine the component's name + name = cls._name or (len(parents) == 1 and parents[0]) + + if not name: + raise TypeError('Component %r must have a _name' % cls) + + # all components except 'base' implicitly inherit from 'base' + if name != 'base': + parents = list(parents) + ['base'] + + # create or retrieve the component's class + if name in parents: + if name not in registry: + raise TypeError("Component %r does not exist in registry." % + name) + ComponentClass = registry[name] + ComponentClass._build_component_check_base(cls) + check_parent = ComponentClass._build_component_check_parent + else: + ComponentClass = type( + name, (AbstractComponent,), + {'_name': name, + '_register': False, + # names of children component + '_inherit_children': OrderedSet()}, + ) + check_parent = cls._build_component_check_parent + + # determine all the classes the component should inherit from + bases = LastOrderedSet([cls]) + for parent in parents: + if parent not in registry: + raise TypeError( + "Component %r inherits from non-existing component %r." % + (name, parent) + ) + parent_class = registry[parent] + if parent == name: + for base in parent_class.__bases__: + bases.add(base) + else: + check_parent(cls, parent_class) + bases.add(parent_class) + parent_class._inherit_children.add(name) + ComponentClass.__bases__ = tuple(bases) + + ComponentClass._complete_component_build() + + registry[name] = ComponentClass + + return ComponentClass + + @classmethod + def _build_component_check_base(cls, extend_cls): + """ Check whether ``cls`` can be extended with ``extend_cls``. """ + if cls._abstract and not extend_cls._abstract: + msg = ("%s transforms the abstract component %r into a " + "non-abstract component. " + "That class should either inherit from AbstractComponent, " + "or set a different '_name'.") + raise TypeError(msg % (extend_cls, cls._name)) + + @classmethod + def _build_component_check_parent(component_class, cls, parent_class): + """ Check whether ``model_class`` can inherit from ``parent_class``. + """ + if component_class._abstract and not parent_class._abstract: + msg = ("In %s, the abstract Component %r cannot inherit " + "from the non-abstract Component %r.") + raise TypeError( + msg % (cls, component_class._name, parent_class._name) + ) + + @classmethod + def _complete_component_build(cls): + """ Complete build of the new component class + + After the component has been built from its bases, this method is + called, and can be used to customize the class before it can be used. + + Nothing is done in the base Component, but a Component can inherit + the method to add its own behavior. + """ + + +class Component(AbstractComponent): + """ Concrete Component class + + This is the class you inherit from when you want your component to + be registered in the component collections. + + Look in :class:`AbstractComponent` for more details. + + """ + _register = False + _abstract = False diff --git a/ext/3rd-party-addons/component/exception.py b/ext/3rd-party-addons/component/exception.py new file mode 100644 index 00000000..71fcd38b --- /dev/null +++ b/ext/3rd-party-addons/component/exception.py @@ -0,0 +1,15 @@ +# -*- coding: utf-8 -*- +# Copyright 2017 Camptocamp SA +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html) + + +class ComponentException(Exception): + """ Base Exception for the components """ + + +class NoComponentError(ComponentException): + """ No component has been found """ + + +class SeveralComponentError(ComponentException): + """ More than one component have been found """ diff --git a/ext/3rd-party-addons/component/models/__init__.py b/ext/3rd-party-addons/component/models/__init__.py new file mode 100644 index 00000000..4343b4ae --- /dev/null +++ b/ext/3rd-party-addons/component/models/__init__.py @@ -0,0 +1,3 @@ +# -*- coding: utf-8 -*- + +from . import collection diff --git a/ext/3rd-party-addons/component/models/collection.py b/ext/3rd-party-addons/component/models/collection.py new file mode 100644 index 00000000..22033696 --- /dev/null +++ b/ext/3rd-party-addons/component/models/collection.py @@ -0,0 +1,97 @@ +# -*- coding: utf-8 -*- +# Copyright 2017 Camptocamp SA +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html) + +""" + +Collection Model +================ + +This is the base Model shared by all the Collections. +In the context of the Connector, a collection is the Backend. +The `_name` given to the Collection Model will be the name +to use in the `_collection` of the Components usable for the Backend. + +""" + +from contextlib import contextmanager + +from odoo import models, api +from ..core import WorkContext + + +class Collection(models.AbstractModel): + """ The model on which components are subscribed + + It would be for instance the ``backend`` for the connectors. + + Example:: + + class MagentoBackend(models.Model): + _name = 'magento.backend' # name of the collection + _inherit = 'collection.base' + + + class MagentoSaleImporter(Component): + _name = 'magento.sale.importer' + _apply_on = 'magento.sale.order' + _collection = 'magento.backend' # name of the collection + + def run(self, magento_id): + mapper = self.component(usage='import.mapper') + extra_mappers = self.many_components( + usage='import.mapper.extra', + ) + # ... + + Use it:: + + >>> backend = self.env['magento.backend'].browse(1) + >>> with backend.work_on('magento.sale.order') as work: + ... importer = work.component(usage='magento.sale.importer') + ... importer.run(1) + + See also: :class:`odoo.addons.component.core.WorkContext` + + + """ + _name = 'collection.base' + _description = 'Base Abstract Collection' + + @contextmanager + @api.multi + def work_on(self, model_name, **kwargs): + """ Entry-point for the components, context manager + + Start a work using the components on the model. + Any keyword argument will be assigned to the work context. + See documentation of :class:`odoo.addons.component.core.WorkContext`. + + It is a context manager, so you can attach objects and clean them + at the end of the work session, such as:: + + @contextmanager + @api.multi + def work_on(self, model_name, **kwargs): + self.ensure_one() + magento_location = MagentoLocation( + self.location, + self.username, + self.password, + ) + # We create a Magento Client API here, so we can create the + # client once (lazily on the first use) and propagate it + # through all the sync session, instead of recreating a client + # in each backend adapter usage. + with MagentoAPI(magento_location) as magento_api: + _super = super(MagentoBackend, self) + # from the components we'll be able to do: + # self.work.magento_api + with _super.work_on( + model_name, magento_api=magento_api, **kwargs + ) as work: + yield work + + """ + self.ensure_one() + yield WorkContext(model_name=model_name, collection=self, **kwargs) diff --git a/ext/3rd-party-addons/component/tests/__init__.py b/ext/3rd-party-addons/component/tests/__init__.py new file mode 100644 index 00000000..ef6a6108 --- /dev/null +++ b/ext/3rd-party-addons/component/tests/__init__.py @@ -0,0 +1,6 @@ +# -*- coding: utf-8 -*- + +from . import test_build_component +from . import test_component +from . import test_lookup +from . import test_work_on diff --git a/ext/3rd-party-addons/component/tests/common.py b/ext/3rd-party-addons/component/tests/common.py new file mode 100644 index 00000000..7a462186 --- /dev/null +++ b/ext/3rd-party-addons/component/tests/common.py @@ -0,0 +1,207 @@ +# -*- coding: utf-8 -*- +# Copyright 2017 Camptocamp SA +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html) + +import copy + +from contextlib import contextmanager + +import unittest +import odoo +from odoo import api +from odoo.tests import common +from odoo.addons.component.core import ( + ComponentRegistry, + MetaComponent, + _get_addon_name, +) + + +@contextmanager +def new_rollbacked_env(): + registry = odoo.registry(common.get_db_name()) + uid = odoo.SUPERUSER_ID + cr = registry.cursor() + try: + yield api.Environment(cr, uid, {}) + finally: + cr.rollback() # we shouldn't have to commit anything + cr.close() + + +class ComponentMixin(object): + + @classmethod + def setUpComponent(cls): + with new_rollbacked_env() as env: + builder = env['component.builder'] + # build the components of every installed addons + comp_registry = builder._init_global_registry() + cls._components_registry = comp_registry + # ensure that we load only the components of the 'installed' + # modules, not 'to install', which means we load only the + # dependencies of the tested addons, not the siblings or + # chilren addons + builder.build_registry(comp_registry, states=('installed',)) + # build the components of the current tested addon + current_addon = _get_addon_name(cls.__module__) + env['component.builder'].load_components(current_addon) + + def setUp(self): + # should be ready only during tests, never during installation + # of addons + self._components_registry.ready = True + + @self.addCleanup + def notready(): + self._components_registry.ready = False + + +class TransactionComponentCase(common.TransactionCase, ComponentMixin): + """ A TransactionCase that loads all the components + + It it used like an usual Odoo's TransactionCase, but it ensures + that all the components of the current addon and its dependencies + are loaded. + + """ + + @classmethod + def setUpClass(cls): + super(TransactionComponentCase, cls).setUpClass() + cls.setUpComponent() + + def setUp(self): + # resolve an inheritance issue (common.TransactionCase does not call + # super) + common.TransactionCase.setUp(self) + ComponentMixin.setUp(self) + + +class SavepointComponentCase(common.SavepointCase, ComponentMixin): + """ A SavepointCase that loads all the components + + It it used like an usual Odoo's SavepointCase, but it ensures + that all the components of the current addon and its dependencies + are loaded. + + """ + + @classmethod + def setUpClass(cls): + super(SavepointComponentCase, cls).setUpClass() + cls.setUpComponent() + + def setUp(self): + # resolve an inheritance issue (common.SavepointCase does not call + # super) + common.SavepointCase.setUp(self) + ComponentMixin.setUp(self) + + +class ComponentRegistryCase(unittest.TestCase): + """ This test case can be used as a base for writings tests on components + + This test case is meant to test components in a special component registry, + where you want to have maximum control on which components are loaded + or not, or when you want to create additional components in your tests. + + If you only want to *use* the components of the tested addon in your tests, + then consider using one of: + + * :class:`TransactionComponentCase` + * :class:`SavepointComponentCase` + + This test case creates a special + :class:`odoo.addons.component.core.ComponentRegistry` for the purpose of + the tests. By default, it loads all the components of the dependencies, but + not the components of the current addon (which you have to handle + manually). In your tests, you can add more components in 2 manners. + + All the components of an Odoo module:: + + self._load_module_components('connector') + + Only specific components:: + + self._build_components(MyComponent1, MyComponent2) + + Note: for the lookups of the components, the default component + registry is a global registry for the database. Here, you will + need to explicitly pass ``self.comp_registry`` in the + :class:`~odoo.addons.component.core.WorkContext`:: + + work = WorkContext(model_name='res.users', + collection='my.collection', + components_registry=self.comp_registry) + + Or:: + + collection_record = self.env['my.collection'].browse(1) + with collection_record.work_on( + 'res.partner', + components_registry=self.comp_registry) as work: + + """ + + def setUp(self): + super(ComponentRegistryCase, self).setUp() + + # keep the original classes registered by the metaclass + # so we'll restore them at the end of the tests, it avoid + # to pollute it with Stub / Test components + self._original_components = copy.deepcopy( + MetaComponent._modules_components + ) + + # it will be our temporary component registry for our test session + self.comp_registry = ComponentRegistry() + + # it builds the 'final component' for every component of the + # 'component' addon and push them in the component registry + self.comp_registry.load_components('component') + # build the components of every installed addons already installed + # but the current addon (when running with pytest/nosetest, we + # simulate the --test-enable behavior by excluding the current addon + # which is in 'to install' / 'to upgrade' with --test-enable). + current_addon = _get_addon_name(self.__module__) + with new_rollbacked_env() as env: + env['component.builder'].build_registry( + self.comp_registry, + states=('installed',), + exclude_addons=[current_addon], + ) + + # Fake that we are ready to work with the registry + # normally, it is set to True and the end of the build + # of the components. Here, we'll add components later in + # the components registry, but we don't mind for the tests. + self.comp_registry.ready = True + + def tearDown(self): + super(ComponentRegistryCase, self).tearDown() + # restore the original metaclass' classes + MetaComponent._modules_components = self._original_components + + def _load_module_components(self, module): + self.comp_registry.load_components(module) + + def _build_components(self, *classes): + for cls in classes: + cls._build_component(self.comp_registry) + + +class TransactionComponentRegistryCase(common.TransactionCase, + ComponentRegistryCase): + """ Adds Odoo Transaction in the base Component TestCase """ + + def setUp(self): + # resolve an inheritance issue (common.TransactionCase does not use + # super) + common.TransactionCase.setUp(self) + ComponentRegistryCase.setUp(self) + self.collection = self.env['collection.base'] + + def teardown(self): + common.TransactionCase.tearDown(self) + ComponentRegistryCase.tearDown(self) diff --git a/ext/3rd-party-addons/component/tests/test_build_component.py b/ext/3rd-party-addons/component/tests/test_build_component.py new file mode 100644 index 00000000..0d7bc35f --- /dev/null +++ b/ext/3rd-party-addons/component/tests/test_build_component.py @@ -0,0 +1,272 @@ +# -*- coding: utf-8 -*- +# Copyright 2017 Camptocamp SA +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html) + +import mock +from odoo.addons.component.core import AbstractComponent, Component +from .common import ComponentRegistryCase + + +class TestBuildComponent(ComponentRegistryCase): + """ Test build of components + + All the tests in this suite are based on the same principle with + variations: + + * Create new Components (classes inheriting from + :class:`component.core.Component` or + :class:`component.core.AbstractComponent` + * Call :meth:`component.core.Component._build_component` on them + in order to build the 'final class' composed from all the ``_inherit`` + and push it in the components registry (``self.comp_registry`` here) + * Assert that classes are built, registered, have correct ``__bases__``... + + """ + + def test_no_name(self): + """ Ensure that a component has a _name """ + class Component1(Component): + pass + + msg = '.*must have a _name.*' + with self.assertRaisesRegex(TypeError, msg): + Component1._build_component(self.comp_registry) + + def test_register(self): + """ Able to register components in components registry """ + class Component1(Component): + _name = 'component1' + + class Component2(Component): + _name = 'component2' + + # build the 'final classes' for the components and check that we find + # them in the components registry + Component1._build_component(self.comp_registry) + Component2._build_component(self.comp_registry) + self.assertEqual( + ['base', 'component1', 'component2'], + list(self.comp_registry) + ) + + def test_inherit_bases(self): + """ Check __bases__ of Component with _inherit """ + class Component1(Component): + _name = 'component1' + + class Component2(Component): + _inherit = 'component1' + + class Component3(Component): + _inherit = 'component1' + + Component1._build_component(self.comp_registry) + Component2._build_component(self.comp_registry) + Component3._build_component(self.comp_registry) + self.assertEqual( + (Component3, + Component2, + Component1, + self.comp_registry['base']), + self.comp_registry['component1'].__bases__ + ) + + def test_prototype_inherit_bases(self): + """ Check __bases__ of Component with _inherit and different _name """ + class Component1(Component): + _name = 'component1' + + class Component2(Component): + _name = 'component2' + _inherit = 'component1' + + class Component3(Component): + _name = 'component3' + _inherit = 'component1' + + class Component4(Component): + _name = 'component4' + _inherit = ['component2', 'component3'] + + Component1._build_component(self.comp_registry) + Component2._build_component(self.comp_registry) + Component3._build_component(self.comp_registry) + Component4._build_component(self.comp_registry) + self.assertEqual( + (Component1, + self.comp_registry['base']), + self.comp_registry['component1'].__bases__ + ) + self.assertEqual( + (Component2, + self.comp_registry['component1'], + self.comp_registry['base']), + self.comp_registry['component2'].__bases__ + ) + self.assertEqual( + (Component3, + self.comp_registry['component1'], + self.comp_registry['base']), + self.comp_registry['component3'].__bases__ + ) + self.assertEqual( + (Component4, + self.comp_registry['component2'], + self.comp_registry['component3'], + self.comp_registry['base']), + self.comp_registry['component4'].__bases__ + ) + + def test_custom_build(self): + """ Check that we can hook at the end of a Component build """ + class Component1(Component): + _name = 'component1' + + @classmethod + def _complete_component_build(cls): + # This method should be called after the Component + # is built, and before it is pushed in the registry + cls._build_done = True + + Component1._build_component(self.comp_registry) + # we inspect that our custom build has been executed + self.assertTrue( + self.comp_registry['component1']._build_done + ) + + def test_inherit_attrs(self): + """ Check attributes inheritance of Components with _inherit """ + class Component1(Component): + _name = 'component1' + + msg = 'ping' + + def say(self): + return 'foo' + + class Component2(Component): + _name = 'component2' + _inherit = 'component1' + + msg = 'pong' + + def say(self): + return super(Component2, self).say() + ' bar' + + Component1._build_component(self.comp_registry) + Component2._build_component(self.comp_registry) + # we initialize the components, normally we should pass + # an instance of WorkContext, but we don't need a real one + # for this test + component1 = self.comp_registry['component1'](mock.Mock()) + component2 = self.comp_registry['component2'](mock.Mock()) + self.assertEqual('ping', component1.msg) + self.assertEqual('pong', component2.msg) + self.assertEqual('foo', component1.say()) + self.assertEqual('foo bar', component2.say()) + + def test_duplicate_component(self): + """ Check that we can't have 2 components with the same name """ + class Component1(Component): + _name = 'component1' + + class Component2(Component): + _name = 'component1' + + Component1._build_component(self.comp_registry) + msg = 'Component.*already exists.*' + with self.assertRaisesRegex(TypeError, msg): + Component2._build_component(self.comp_registry) + + def test_no_parent(self): + """ Ensure we can't _inherit a non-existent component """ + class Component1(Component): + _name = 'component1' + _inherit = 'component1' + + msg = 'Component.*does not exist in registry.*' + with self.assertRaisesRegex(TypeError, msg): + Component1._build_component(self.comp_registry) + + def test_no_parent2(self): + """ Ensure we can't _inherit by prototype a non-existent component """ + class Component1(Component): + _name = 'component1' + + class Component2(Component): + _name = 'component2' + _inherit = ['component1', 'component3'] + + Component1._build_component(self.comp_registry) + msg = 'Component.*inherits from non-existing component.*' + with self.assertRaisesRegex(TypeError, msg): + Component2._build_component(self.comp_registry) + + def test_add_inheritance(self): + """ Ensure we can add a new inheritance """ + class Component1(Component): + _name = 'component1' + + class Component2(Component): + _name = 'component2' + + class Component2bis(Component): + _name = 'component2' + _inherit = ['component2', 'component1'] + + Component1._build_component(self.comp_registry) + Component2._build_component(self.comp_registry) + Component2bis._build_component(self.comp_registry) + + self.assertEqual( + (Component2bis, + Component2, + self.comp_registry['component1'], + self.comp_registry['base']), + self.comp_registry['component2'].__bases__ + ) + + def test_check_parent_component_over_abstract(self): + """ Component can inherit from AbstractComponent """ + class Component1(AbstractComponent): + _name = 'component1' + + class Component2(Component): + _name = 'component2' + _inherit = 'component1' + + Component1._build_component(self.comp_registry) + Component2._build_component(self.comp_registry) + self.assertTrue( + self.comp_registry['component1']._abstract + ) + self.assertFalse( + self.comp_registry['component2']._abstract + ) + + def test_check_parent_abstract_over_component(self): + """ Prevent AbstractComponent to inherit from Component """ + class Component1(Component): + _name = 'component1' + + class Component2(AbstractComponent): + _name = 'component2' + _inherit = 'component1' + + Component1._build_component(self.comp_registry) + msg = '.*cannot inherit from the non-abstract.*' + with self.assertRaisesRegex(TypeError, msg): + Component2._build_component(self.comp_registry) + + def test_check_transform_abstract_to_component(self): + """ Prevent AbstractComponent to be transformed to Component """ + class Component1(AbstractComponent): + _name = 'component1' + + class Component1bis(Component): + _inherit = 'component1' + + Component1._build_component(self.comp_registry) + msg = '.*transforms the abstract component.*into a non-abstract.*' + with self.assertRaisesRegex(TypeError, msg): + Component1bis._build_component(self.comp_registry) diff --git a/ext/3rd-party-addons/component/tests/test_component.py b/ext/3rd-party-addons/component/tests/test_component.py new file mode 100644 index 00000000..ebc04e68 --- /dev/null +++ b/ext/3rd-party-addons/component/tests/test_component.py @@ -0,0 +1,287 @@ +# -*- coding: utf-8 -*- +# Copyright 2017 Camptocamp SA +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html) + +from contextlib import contextmanager +from odoo.addons.component.core import ( + Component, +) +from .common import TransactionComponentRegistryCase +from odoo.addons.component.exception import ( + NoComponentError, + SeveralComponentError, +) + + +class TestComponent(TransactionComponentRegistryCase): + """ Test usage of components + + These tests are a bit more broad that mere unit tests. + We test the chain odoo Model -> generate a WorkContext instance -> Work + with Component. + + Tests are inside Odoo transactions, so we can work + with Odoo's env / models. + """ + + def setUp(self): + super(TestComponent, self).setUp() + self.collection = self.env['collection.base'] + + # create some Component to play with + class Component1(Component): + _name = 'component1' + _collection = 'collection.base' + _usage = 'for.test' + _apply_on = ['res.partner'] + + class Component2(Component): + _name = 'component2' + _collection = 'collection.base' + _usage = 'for.test' + _apply_on = ['res.users'] + + # build the components and register them in our + # test component registry + Component1._build_component(self.comp_registry) + Component2._build_component(self.comp_registry) + + # our collection, in a less abstract use case, it + # could be a record of 'magento.backend' for instance + self.collection_record = self.collection.new() + + @contextmanager + def get_base(): + # Our WorkContext, it will be passed along in every + # components so we can share data transversally. + # We are working with res.partner in the following tests, + # unless we change it in the test. + with self.collection_record.work_on( + 'res.partner', + # we use a custom registry only + # for the sake of the tests + components_registry=self.comp_registry + ) as work: + # We get the 'base' component, handy to test the base + # methods component, many_components, ... + yield work.component_by_name('base') + self.get_base = get_base + + def test_component_attrs(self): + """ Basic access to a Component's attribute """ + with self.get_base() as base: + # as we are working on res.partner, we should get 'component1' + comp = base.work.component(usage='for.test') + # but this is not what we test here, we test the attributes: + self.assertEqual(self.collection_record, comp.collection) + self.assertEqual(base.work, comp.work) + self.assertEqual(self.env, comp.env) + self.assertEqual(self.env['res.partner'], comp.model) + + def test_component_get_by_name_same_model(self): + """ Use component_by_name with current working model """ + with self.get_base() as base: + # we ask a component directly by it's name, considering + # we work with res.partner, we should get 'component1' + # this is ok because it's _apply_on contains res.partner + comp = base.component_by_name('component1') + self.assertEqual('component1', comp._name) + self.assertEqual(self.env['res.partner'], comp.model) + + def test_component_get_by_name_other_model(self): + """ Use component_by_name with another model """ + with self.get_base() as base: + # we ask a component directly by it's name, but we + # want to work with 'res.users', this is ok since + # component2's _apply_on contains res.users + comp = base.component_by_name( + 'component2', model_name='res.users' + ) + self.assertEqual('component2', comp._name) + self.assertEqual(self.env['res.users'], comp.model) + # what happens under the hood, is that a new WorkContext + # has been created for this model, with all the other values + # identical to the previous WorkContext (the one for res.partner) + # We can check that with: + self.assertNotEqual(base.work, comp.work) + self.assertEqual('res.partner', base.work.model_name) + self.assertEqual('res.users', comp.work.model_name) + + def test_component_get_by_name_wrong_model(self): + """ Use component_by_name with a model not in _apply_on """ + msg = ("Component with name 'component2' can't be used " + "for model 'res.partner'.*") + with self.get_base() as base: + with self.assertRaisesRegex(NoComponentError, msg): + # we ask for the model 'component2' but we are working + # with res.partner, and it only accepts res.users + base.component_by_name('component2') + + def test_component_get_by_name_not_exist(self): + """ Use component_by_name on a component that do not exist """ + msg = "No component with name 'foo' found." + with self.get_base() as base: + with self.assertRaisesRegex(NoComponentError, msg): + base.component_by_name('foo') + + def test_component_by_usage_same_model(self): + """ Use component(usage=...) on the same model """ + # we ask for a component having _usage == 'for.test', and + # model being res.partner (the model in the current WorkContext) + with self.get_base() as base: + comp = base.component(usage='for.test') + self.assertEqual('component1', comp._name) + self.assertEqual(self.env['res.partner'], comp.model) + + def test_component_by_usage_other_model(self): + """ Use component(usage=...) on a different model (name) """ + # we ask for a component having _usage == 'for.test', and + # a different model (res.users) + with self.get_base() as base: + comp = base.component(usage='for.test', model_name='res.users') + self.assertEqual('component2', comp._name) + self.assertEqual(self.env['res.users'], comp.model) + # what happens under the hood, is that a new WorkContext + # has been created for this model, with all the other values + # identical to the previous WorkContext (the one for res.partner) + # We can check that with: + self.assertNotEqual(base.work, comp.work) + self.assertEqual('res.partner', base.work.model_name) + self.assertEqual('res.users', comp.work.model_name) + + def test_component_by_usage_other_model_env(self): + """ Use component(usage=...) on a different model (instance) """ + with self.get_base() as base: + comp = base.component(usage='for.test', + model_name=self.env['res.users']) + self.assertEqual('component2', comp._name) + self.assertEqual(self.env['res.users'], comp.model) + + def test_component_error_several(self): + """ Use component(usage=...) when more than one component match """ + # we create a new Component with _usage 'for.test', in the same + # collection and no _apply_on + class Component3(Component): + _name = 'component3' + _collection = 'collection.base' + _usage = 'for.test' + + Component3._build_component(self.comp_registry) + + with self.get_base() as base: + with self.assertRaises(SeveralComponentError): + # When a component has no _apply_on, it means it can be applied + # on *any* model. Here, the candidates components would be: + # component1 (because we are working with res.partner), + # component3 (because it has no _apply_on so apply in any case) + base.component(usage='for.test') + + def test_many_components(self): + """ Use many_components(usage=...) on the same model """ + class Component3(Component): + _name = 'component3' + _collection = 'collection.base' + _usage = 'for.test' + + Component3._build_component(self.comp_registry) + + with self.get_base() as base: + comps = base.many_components(usage='for.test') + + # When a component has no _apply_on, it means it can be applied + # on *any* model. So here, both component1 and component3 match + self.assertEqual( + ['component1', 'component3'], + [c._name for c in comps] + ) + + def test_many_components_other_model(self): + """ Use many_components(usage=...) on a different model (name) """ + class Component3(Component): + _name = 'component3' + _collection = 'collection.base' + _apply_on = 'res.users' + _usage = 'for.test' + + Component3._build_component(self.comp_registry) + + with self.get_base() as base: + comps = base.many_components(usage='for.test', + model_name='res.users') + + self.assertEqual( + ['component2', 'component3'], + [c._name for c in comps] + ) + + def test_many_components_other_model_env(self): + """ Use many_components(usage=...) on a different model (instance) """ + class Component3(Component): + _name = 'component3' + _collection = 'collection.base' + _apply_on = 'res.users' + _usage = 'for.test' + + Component3._build_component(self.comp_registry) + + with self.get_base() as base: + comps = base.many_components(usage='for.test', + model_name=self.env['res.users']) + + self.assertEqual( + ['component2', 'component3'], + [c._name for c in comps] + ) + + def test_no_component(self): + """ No component found for asked usage """ + with self.get_base() as base: + with self.assertRaises(NoComponentError): + base.component(usage='foo') + + def test_no_many_component(self): + """ No component found for asked usage for many_components() """ + with self.get_base() as base: + self.assertEqual([], base.many_components(usage='foo')) + + def test_work_on_component(self): + """ Check WorkContext.component() (shortcut to Component.component) """ + with self.get_base() as base: + comp = base.work.component(usage='for.test') + self.assertEqual('component1', comp._name) + + def test_work_on_many_components(self): + """ Check WorkContext.many_components() + + (shortcut to Component.many_components) + """ + with self.get_base() as base: + comps = base.work.many_components(usage='for.test') + self.assertEqual('component1', comps[0]._name) + + def test_component_match(self): + """ Lookup with match method """ + class Foo(Component): + _name = 'foo' + _collection = 'collection.base' + _usage = 'speaker' + _apply_on = ['res.partner'] + + @classmethod + def _component_match(cls, work): + return False + + class Bar(Component): + _name = 'bar' + _collection = 'collection.base' + _usage = 'speaker' + _apply_on = ['res.partner'] + + self._build_components(Foo, Bar) + + with self.get_base() as base: + # both components would we returned without the + # _component_match method + comp = base.component(usage='speaker', + model_name=self.env['res.partner']) + self.assertEqual('bar', comp._name) diff --git a/ext/3rd-party-addons/component/tests/test_lookup.py b/ext/3rd-party-addons/component/tests/test_lookup.py new file mode 100644 index 00000000..a4ae7071 --- /dev/null +++ b/ext/3rd-party-addons/component/tests/test_lookup.py @@ -0,0 +1,194 @@ +# -*- 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 ( + AbstractComponent, + Component, +) +from .common import ComponentRegistryCase + + +class TestLookup(ComponentRegistryCase): + """ Test the ComponentRegistry + + Tests in this testsuite mainly do: + + * Create new Components (classes inheriting from + :class:`component.core.Component` or + :class:`component.core.AbstractComponent` + * Call :meth:`component.core.Component._build_component` on them + in order to build the 'final class' composed from all the ``_inherit`` + and push it in the components registry (``self.comp_registry`` here) + * Use the lookup method of the components registry and check + that we get the correct result + + """ + + def test_lookup_collection(self): + """ Lookup components of a collection """ + # we register 2 components in foobar and one in other + class Foo(Component): + _name = 'foo' + _collection = 'foobar' + + class Bar(Component): + _name = 'bar' + _collection = 'foobar' + + class Homer(Component): + _name = 'homer' + _collection = 'other' + + self._build_components(Foo, Bar, Homer) + + # we should no see the component in 'other' + components = self.comp_registry.lookup('foobar') + self.assertEqual( + ['foo', 'bar'], + [c._name for c in components] + ) + + def test_lookup_usage(self): + """ Lookup components by usage """ + class Foo(Component): + _name = 'foo' + _collection = 'foobar' + _usage = 'speaker' + + class Bar(Component): + _name = 'bar' + _collection = 'foobar' + _usage = 'speaker' + + class Baz(Component): + _name = 'baz' + _collection = 'foobar' + _usage = 'listener' + + self._build_components(Foo, Bar, Baz) + + components = self.comp_registry.lookup('foobar', usage='listener') + self.assertEqual('baz', components[0]._name) + + components = self.comp_registry.lookup('foobar', usage='speaker') + self.assertEqual( + ['foo', 'bar'], + [c._name for c in components] + ) + + def test_lookup_no_component(self): + """ No component """ + # we just expect an empty list when no component match, the error + # handling is handled at an higher level + self.assertEqual( + [], + self.comp_registry.lookup('something', usage='something') + ) + + def test_get_by_name(self): + """ Get component by name """ + class Foo(AbstractComponent): + _name = 'foo' + _collection = 'foobar' + + self._build_components(Foo) + # this is just a dict access + self.assertEqual('foo', self.comp_registry['foo']._name) + + def test_lookup_abstract(self): + """ Do not include abstract components in lookup """ + class Foo(AbstractComponent): + _name = 'foo' + _collection = 'foobar' + _usage = 'speaker' + + class Bar(Component): + _name = 'bar' + _inherit = 'foo' + + self._build_components(Foo, Bar) + + comp_registry = self.comp_registry + + # we should never have 'foo' in the returned components + # as it is abstract + components = comp_registry.lookup('foobar', usage='speaker') + self.assertEqual('bar', components[0]._name) + + components = comp_registry.lookup('foobar', usage='speaker') + self.assertEqual( + ['bar'], + [c._name for c in components] + ) + + def test_lookup_model_name(self): + """ Lookup with model names """ + class Foo(Component): + _name = 'foo' + _collection = 'foobar' + _usage = 'speaker' + # support list + _apply_on = ['res.partner'] + + class Bar(Component): + _name = 'bar' + _collection = 'foobar' + _usage = 'speaker' + # support string + _apply_on = 'res.users' + + class Any(Component): + # can be used with any model as far as we look it up + # with its usage + _name = 'any' + _collection = 'foobar' + _usage = 'listener' + + self._build_components(Foo, Bar, Any) + + components = self.comp_registry.lookup('foobar', + usage='speaker', + model_name='res.partner') + self.assertEqual('foo', components[0]._name) + + components = self.comp_registry.lookup('foobar', + usage='speaker', + model_name='res.users') + self.assertEqual('bar', components[0]._name) + + components = self.comp_registry.lookup('foobar', + usage='listener', + model_name='res.users') + self.assertEqual('any', components[0]._name) + + def test_lookup_cache(self): + """ Lookup uses a cache """ + class Foo(Component): + _name = 'foo' + _collection = 'foobar' + + self._build_components(Foo) + + components = self.comp_registry.lookup('foobar') + self.assertEqual(['foo'], [c._name for c in components]) + + # we add a new component + class Bar(Component): + _name = 'bar' + _collection = 'foobar' + + self._build_components(Bar) + + # As the lookups are cached, we should still see only foo, + # even if we added a new component. + # We do this for testing, but in a real use case, we can't + # add new Component classes on the fly, and when we install + # new addons, the registry is rebuilt and cache cleared. + components = self.comp_registry.lookup('foobar') + self.assertEqual(['foo'], [c._name for c in components]) + + self.comp_registry._cache.clear() + # now we should find them both as the cache has been cleared + components = self.comp_registry.lookup('foobar') + self.assertEqual(['foo', 'bar'], [c._name for c in components]) diff --git a/ext/3rd-party-addons/component/tests/test_work_on.py b/ext/3rd-party-addons/component/tests/test_work_on.py new file mode 100644 index 00000000..645ff854 --- /dev/null +++ b/ext/3rd-party-addons/component/tests/test_work_on.py @@ -0,0 +1,55 @@ +# -*- 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 WorkContext, ComponentRegistry +from .common import TransactionComponentCase + + +class TestWorkOn(TransactionComponentCase): + """ Test on WorkContext + + This model is mostly a container, so we check the access + to the attributes and properties. + + """ + + def setUp(self): + super(TestWorkOn, self).setUp() + self.collection = self.env['collection.base'] + + def test_collection_work_on(self): + """ Create a new instance and test attributes access """ + collection_record = self.collection.new() + with collection_record.work_on('res.partner') as work: + self.assertEqual(collection_record, work.collection) + self.assertEqual('collection.base', work.collection._name) + self.assertEqual('res.partner', work.model_name) + self.assertEqual(self.env['res.partner'], work.model) + self.assertEqual(self.env, work.env) + + def test_propagate_work_on(self): + """ Check custom attributes and their propagation """ + registry = ComponentRegistry() + work = WorkContext( + model_name='res.partner', + collection=self.collection, + # we can customize the lookup registry, but used mostly for tests + components_registry=registry, + # we can pass our own keyword args that will set as attributes + test_keyword='value', + ) + self.assertIs(registry, work.components_registry) + # check that our custom keyword is set as attribute + self.assertEqual('value', work.test_keyword) + + # when we want to work on another model, work_on() create + # another instance and propagate the attributes to it + work2 = work.work_on('res.users') + self.assertNotEqual(work, work2) + self.assertEqual(self.env, work2.env) + self.assertEqual(self.collection, work2.collection) + self.assertEqual('res.users', work2.model_name) + self.assertIs(registry, work2.components_registry) + # test_keyword has been propagated to the new WorkContext instance + self.assertEqual('value', work2.test_keyword) diff --git a/ext/3rd-party-addons/component_event/README.rst b/ext/3rd-party-addons/component_event/README.rst new file mode 100644 index 00000000..d3d986b2 --- /dev/null +++ b/ext/3rd-party-addons/component_event/README.rst @@ -0,0 +1,106 @@ +.. image:: https://img.shields.io/badge/licence-AGPL--3-blue.svg + :target: http://www.gnu.org/licenses/agpl + :alt: License: AGPL-3 + +=================== +Components - Events +=================== + +This module implements an event system (`Observer pattern`_) and is a +base block for the Connector Framework. It can be used without +using the full Connector though. It is built upon the ``component`` module. + +Documentation: http://odoo-connector.com/ + +.. _Observer pattern: https://en.wikipedia.org/wiki/Observer_pattern + +Installation +============ + +* Install ``component_event`` + +Configuration +============= + +The module does nothing by itself and has no configuration. + +Usage +===== + +As a developer, you have access to a events system. You can find the +documentation in the code or on http://odoo-connector.com + +In a nutshell, you can create trigger events:: + + class Base(models.AbstractModel): + _inherit = 'base' + + @api.model + def create(self, vals): + record = super(Base, self).create(vals) + self._event('on_record_create').notify(record, fields=vals.keys()) + return record + +And subscribe listeners to the events:: + + from odoo.addons.component.core import Component + from odoo.addons.component_event import skip_if + + class MagentoListener(Component): + _name = 'magento.event.listener' + _inherit = 'base.connector.listener' + + @skip_if(lambda self, record, **kwargs: self.no_connector_export(record)) + def on_record_create(self, record, fields=None): + """ Called when a record is created """ + record.with_delay().export_record(fields=fields) + + +This module triggers 3 events: + +* ``on_record_create(record, fields=None)`` +* ``on_record_write(record, fields=None)`` +* ``on_record_unlink(record)`` + + +Known issues / Roadmap +====================== + +Bug Tracker +=========== + +Bugs are tracked on `GitHub Issues +`_. In case of trouble, please +check there if your issue has already been reported. If you spotted it first, +help us smash it by providing detailed and welcomed feedback. + +Credits +======= + +Images +------ + +* Odoo Community Association: `Icon `_. + +Contributors +------------ + +* Guewen Baconnier + +Do not contact contributors directly about support or help with technical issues. + +Maintainer +---------- + +.. image:: https://odoo-community.org/logo.png + :alt: Odoo Community Association + :target: https://odoo-community.org + +This module is maintained by the OCA. + +OCA, or the Odoo Community Association, is a nonprofit organization whose +mission is to support the collaborative development of Odoo features and +promote its widespread use. + +To contribute to this module, please visit https://odoo-community.org. + diff --git a/ext/3rd-party-addons/component_event/__init__.py b/ext/3rd-party-addons/component_event/__init__.py new file mode 100644 index 00000000..47e8136c --- /dev/null +++ b/ext/3rd-party-addons/component_event/__init__.py @@ -0,0 +1,7 @@ +# -*- coding: utf-8 -*- +from . import core +from . import components +from . import models + +# allow public API 'from odoo.addons.component_event import skip_if' +from .components.event import skip_if # noqa diff --git a/ext/3rd-party-addons/component_event/__manifest__.py b/ext/3rd-party-addons/component_event/__manifest__.py new file mode 100644 index 00000000..86c3a1d9 --- /dev/null +++ b/ext/3rd-party-addons/component_event/__manifest__.py @@ -0,0 +1,19 @@ +# -*- coding: utf-8 -*- +# Copyright 2017 Camptocamp SA +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html) + +{'name': 'Components Events', + 'version': '11.0.1.0.0', + 'author': 'Camptocamp,' + 'Odoo Community Association (OCA)', + 'website': 'https://www.camptocamp.com', + 'license': 'AGPL-3', + 'category': 'Generic Modules', + 'depends': ['component', + ], + 'external_dependencies': { + 'python': ['cachetools'], + }, + 'data': [], + 'installable': True, + } diff --git a/ext/3rd-party-addons/component_event/components/__init__.py b/ext/3rd-party-addons/component_event/components/__init__.py new file mode 100644 index 00000000..7351619d --- /dev/null +++ b/ext/3rd-party-addons/component_event/components/__init__.py @@ -0,0 +1,2 @@ +# -*- coding: utf-8 -*- +from . import event diff --git a/ext/3rd-party-addons/component_event/components/event.py b/ext/3rd-party-addons/component_event/components/event.py new file mode 100644 index 00000000..54806934 --- /dev/null +++ b/ext/3rd-party-addons/component_event/components/event.py @@ -0,0 +1,294 @@ +# -*- coding: utf-8 -*- +# Copyright 2017 Camptocamp SA +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html) + +""" +Events +====== + +Events are a notification system. + +On one side, one or many listeners await for an event to happen. On +the other side, when such event happen, a notification is sent to +the listeners. + +An example of event is: 'when a record has been created'. + +The event system allows to write the notification code in only one place, in +one Odoo addon, and to write as many listeners as we want, in different places, +different addons. + +We'll see below how the ``on_record_create`` is implemented. + +Notifier +-------- + +The first thing is to find where/when the notification should be sent. +For the creation of a record, it is in :meth:`odoo.models.BaseModel.create`. +We can inherit from the `'base'` model to add this line: + +:: + + class Base(models.AbstractModel): + _inherit = 'base' + + @api.model + def create(self, vals): + record = super(Base, self).create(vals) + self._event('on_record_create').notify(record, fields=vals.keys()) + return record + +The :meth:`..models.base.Base._event` method has been added to the `'base'` +model, so an event can be notified from any model. The +:meth:`CollectedEvents.notify` method triggers the event and forward the +arguments to the listeners. + +This should be done only once. See :class:`..models.base.Base` for a list of +events that are implemented in the `'base'` model. + +Listeners +--------- + +Listeners are Components that respond to the event names. +The components must have a ``_usage`` equals to ``'event.listener'``, but it +doesn't to be set manually if the component inherits from +``'base.event.listener'`` + +Here is how we would log something each time a record is created:: + + class MyEventListener(Component): + _name = 'my.event.listener' + _inherit = 'base.event.listener' + + def on_record_create(self, record, fields=None): + _logger.info("%r has been created", record) + +Many listeners such as this one could be added for the same event. + + +Collection and models +--------------------- + +In the example above, the listeners is global. It will be executed for any +model and collection. You can also restrict a listener to only a collection or +model, using the ``_collection`` or ``_apply_on`` attributes. + +:: + + class MyEventListener(Component): + _name = 'my.event.listener' + _inherit = 'base.event.listener' + _collection = 'magento.backend' + + def on_record_create(self, record, fields=None): + _logger.info("%r has been created", record) + + + class MyModelEventListener(Component): + _name = 'my.event.listener' + _inherit = 'base.event.listener' + _apply_on = ['res.users'] + + def on_record_create(self, record, fields=None): + _logger.info("%r has been created", record) + + +If you want an event to be restricted to a collection, the +notification must also precise the collection, otherwise all listeners +will be executed:: + + + collection = self.env['magento.backend'] + self._event('on_foo_created', collection=collection).notify(record, vals) + +An event can be skipped based on a condition evaluated from the notified +arguments. See :func:`skip_if` + + +""" + +import logging +import operator + +from collections import defaultdict +from functools import wraps + +from odoo.addons.component.core import AbstractComponent, Component + +_logger = logging.getLogger(__name__) + +try: + from cachetools import LRUCache, cachedmethod, keys +except ImportError: + _logger.debug("Cannot import 'cachetools'.") + +# Number of items we keep in LRU cache when we collect the events. +# 1 item means: for an event name, model_name, collection, return +# the event methods +DEFAULT_EVENT_CACHE_SIZE = 512 + + +def skip_if(cond): + """ Decorator allowing to skip an event based on a condition + + The condition is a python lambda expression, which takes the + same arguments than the event. + + Example:: + + @skip_if(lambda self, *args, **kwargs: + self.env.context.get('connector_no_export')) + def on_record_write(self, record, fields=None): + _logger('I'll delay a job, but only if we didn't disabled ' + ' the export with a context key') + record.with_delay().export_record() + + @skip_if(lambda self, record, kind: kind == 'complete') + def on_record_write(self, record, kind): + _logger("I'll delay a job, but only if the kind is 'complete'") + record.with_delay().export_record() + + """ + def skip_if_decorator(func): + @wraps(func) + def func_wrapper(*args, **kwargs): + if cond(*args, **kwargs): + return + else: + return func(*args, **kwargs) + + return func_wrapper + return skip_if_decorator + + +class CollectedEvents(object): + """ Event methods ready to be notified + + This is a rather internal class. An instance of this class + is prepared by the :class:`EventCollecter` when we need to notify + the listener that the event has been triggered. + + :meth:`EventCollecter.collect_events` collects the events, + feed them to the instance, so we can use the :meth:`notify` method + that will forward the arguments and keyword arguments to the + listeners of the event. + :: + + >>> # collecter is an instance of CollectedEvents + >>> collecter.collect_events('on_record_create').notify(something) + + """ + + def __init__(self, events): + self.events = events + + def notify(self, *args, **kwargs): + """ Forward the arguments to every listeners of an event """ + for event in self.events: + event(*args, **kwargs) + + +class EventCollecter(Component): + """ Component that collects the event from an event name + + For doing so, it searches all the components that respond to the + ``event.listener`` ``_usage`` and having an event of the same + name. + + Then it feeds the events to an instance of :class:`EventCollecter` + and return it to the caller. + + It keeps the results in a cache, the Component is rebuilt when + the Odoo's registry is rebuilt, hence the cache is cleared as well. + + An event always starts with ``on_``. + + Note that the special + :class:`odoo.addons.component_event.core.EventWorkContext` class should be + used for this Component, because it can work + without a collection. + + It is used by :meth:`odoo.addons.component_event.models.base.Base._event`. + + """ + _name = 'base.event.collecter' + + @classmethod + def _complete_component_build(cls): + """ Create a cache on the class when the component is built """ + super(EventCollecter, cls)._complete_component_build() + # the _cache being on the component class, which is + # dynamically rebuild when odoo registry is rebuild, we + # are sure that the result is always the same for a lookup + # until the next rebuild of odoo's registry + cls._cache = LRUCache(maxsize=DEFAULT_EVENT_CACHE_SIZE) + + @cachedmethod(operator.attrgetter('_cache'), + key=lambda self, name: keys.hashkey( + self.work.collection._name + if self.work._collection is not None else None, + self.work.model_name, + name) + ) + def _collect_events(self, name): + events = defaultdict(set) + collection_name = (self.work.collection._name + if self.work._collection is not None + else None) + component_classes = self.work.components_registry.lookup( + collection_name=collection_name, + usage='event.listener', + model_name=self.work.model_name, + ) + for cls in component_classes: + if cls.has_event(name): + events[cls].add(name) + return events + + def _init_collected_events(self, class_events): + events = set() + for cls, names in class_events.items(): + for name in names: + component = cls(self.work) + events.add(getattr(component, name)) + return events + + def collect_events(self, name): + """ Collect the events of a given name """ + if not name.startswith('on_'): + raise ValueError("an event name always starts with 'on_'") + + events = self._init_collected_events(self._collect_events(name)) + return CollectedEvents(events) + + +class EventListener(AbstractComponent): + """ Base Component for the Event listeners + + Events must be methods starting with ``on_``. + + Example: :class:`RecordsEventListener` + + """ + _name = 'base.event.listener' + _usage = 'event.listener' + + @classmethod + def has_event(cls, name): + """ Indicate if the class has an event of this name """ + return name in cls._events + + @classmethod + def _build_event_listener_component(cls): + """ Make a list of events listeners for this class """ + events = set([]) + if not cls._abstract: + for attr_name in dir(cls): + if attr_name.startswith('on_'): + events.add(attr_name) + cls._events = events + + @classmethod + def _complete_component_build(cls): + super(EventListener, cls)._complete_component_build() + cls._build_event_listener_component() diff --git a/ext/3rd-party-addons/component_event/core.py b/ext/3rd-party-addons/component_event/core.py new file mode 100644 index 00000000..fd76375e --- /dev/null +++ b/ext/3rd-party-addons/component_event/core.py @@ -0,0 +1,153 @@ +# -*- coding: utf-8 -*- +# Copyright 2017 Camptocamp SA +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html) + +""" +Events Internals +================ + +Core classes for the events system. + + +""" + + +from odoo.addons.component.core import WorkContext + + +class EventWorkContext(WorkContext): + """ Work context used by the Events internals + + Should not be used outside of the events internals. + The work context to use generally is + :class:`odoo.addons.component.core.WorkContext` or your own + subclass. + + The events are a special kind of components because they are + not attached to any collection (they can but not the main use case). + + So the work context must not need to have a collection, but when + it has no collection, it must at least have an 'env'. + + When no collection is provided, the methods to get the Components + cannot be used, but :meth:`work_on` can be used to switch back to + a :class:`odoo.addons.component.core.WorkContext` with collection. + This is needed when one want to get a component for a collection + from inside an event listener. + + """ + + def __init__(self, model_name=None, collection=None, env=None, + components_registry=None, **kwargs): + if not (collection is not None or env): + raise ValueError('collection or env is required') + if collection and env: + # when a collection is used, the env will be the one of + # the collection + raise ValueError('collection and env cannot both be provided') + + self.env = env + super(EventWorkContext, self).__init__( + model_name=model_name, collection=collection, + components_registry=components_registry, + **kwargs + ) + if self._env: + self._propagate_kwargs.remove('collection') + self._propagate_kwargs.append('env') + + @property + def env(self): + """ Return the current Odoo env """ + if self._env: + return self._env + return super(EventWorkContext, self).env + + @env.setter + def env(self, value): + self._env = value + + @property + def collection(self): + """ Return the current Odoo env """ + if self._collection is not None: + return self._collection + raise ValueError('No collection, it is optional for EventWorkContext') + + @collection.setter + def collection(self, value): + self._collection = value + + def work_on(self, model_name=None, collection=None): + """ Create a new work context for another model keeping attributes + + Used when one need to lookup components for another model. + + Used on an EventWorkContext, it switch back to a normal + WorkContext. It means we are inside an event listener, and + we want to get a component. We need to set a collection + to be able to get components. + """ + if self._collection is None and collection is None: + raise ValueError('you must provide a collection to work with') + if collection is not None: + if self.env is not collection.env: + raise ValueError('the Odoo env of the collection must be ' + 'the same than the current one') + kwargs = {attr_name: getattr(self, attr_name) + for attr_name in self._propagate_kwargs} + kwargs.pop('env', None) + if collection is not None: + kwargs['collection'] = collection + if model_name is not None: + kwargs['model_name'] = model_name + return WorkContext(**kwargs) + + def component_by_name(self, name, model_name=None): + if self._collection is not None: + # switch to a normal WorkContext + work = self.work_on(collection=self._collection, + model_name=model_name) + else: + raise TypeError( + "Can't be used on an EventWorkContext without collection. " + "The collection must be known to find components.\n" + "Hint: you can set the collection and get a component with:\n" + ">>> work.work_on(collection=self.env[...].browse(...))\n" + ">>> work.component_by_name(name, model_name=model_name)" + ) + return work.component_by_name(name, model_name=model_name) + + def component(self, usage=None, model_name=None): + if self._collection is not None: + # switch to a normal WorkContext + work = self.work_on(collection=self._collection, + model_name=model_name) + else: + raise TypeError( + "Can't be used on an EventWorkContext without collection. " + "The collection must be known to find components.\n" + "Hint: you can set the collection and get a component with:\n" + ">>> work.work_on(collection=self.env[...].browse(...))\n" + ">>> work.component(usage=usage, model_name=model_name)" + ) + return work.component(usage=usage, model_name=model_name) + + def many_components(self, usage=None, model_name=None): + if self._collection is not None: + # switch to a normal WorkContext + work = self.work_on(collection=self._collection, + model_name=model_name) + else: + raise TypeError( + "Can't be used on an EventWorkContext without collection. " + "The collection must be known to find components.\n" + "Hint: you can set the collection and get a component with:\n" + ">>> work.work_on(collection=self.env[...].browse(...))\n" + ">>> work.many_components(usage=usage, model_name=model_name)" + ) + return work.component(usage=usage, model_name=model_name) + + def __str__(self): + return ("EventWorkContext(%s,%s)" % + (repr(self._env or self._collection), self.model_name)) diff --git a/ext/3rd-party-addons/component_event/models/__init__.py b/ext/3rd-party-addons/component_event/models/__init__.py new file mode 100644 index 00000000..a61d43eb --- /dev/null +++ b/ext/3rd-party-addons/component_event/models/__init__.py @@ -0,0 +1,2 @@ +# -*- coding: utf-8 -*- +from . import base diff --git a/ext/3rd-party-addons/component_event/models/base.py b/ext/3rd-party-addons/component_event/models/base.py new file mode 100644 index 00000000..e4879f6b --- /dev/null +++ b/ext/3rd-party-addons/component_event/models/base.py @@ -0,0 +1,111 @@ +# -*- coding: utf-8 -*- +# Copyright 2017 Camptocamp SA +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html) + +""" +Base Model +========== + +Extend the 'base' Odoo Model to add Events related features. + + +""" + +from odoo import api, models +from odoo.addons.component.core import _component_databases +from ..components.event import CollectedEvents +from ..core import EventWorkContext + + +class Base(models.AbstractModel): + """ The base model, which is implicitly inherited by all models. + + Add an :meth:`_event` method to all Models. This method allows to + trigger events. + + It also notifies the following events: + + * ``on_record_create(self, record, fields=None)`` + * ``on_record_write(self, record, fields=none)`` + * ``on_record_unlink(self, record)`` + + ``on_record_unlink`` is notified just *before* the unlink is done. + + """ + _inherit = 'base' + + def _event(self, name, collection=None, components_registry=None): + """ Collect events for notifications + + Usage:: + + @api.multi + def button_do_something(self): + for record in self: + # do something + self._event('on_do_something').notify('something') + + With this line, every listener having a ``on_do_something`` method + with be called and receive 'something' as argument. + + See: :mod:`..components.event` + + :param name: name of the event, start with 'on_' + :param collection: optional collection to filter on, only + listeners with similar ``_collection`` will be + notified + :param components_registry: component registry for lookups, + mainly used for tests + :type components_registry: + :class:`odoo.addons.components.core.ComponentRegistry` + + + """ + dbname = self.env.cr.dbname + comp_registry = ( + components_registry or _component_databases.get(dbname) + ) + if not comp_registry or not comp_registry.ready: + # No event should be triggered before the registry has been loaded + # This is a very special case, when the odoo registry is being + # built, it calls odoo.modules.loading.load_modules(). + # This function might trigger events (by writing on records, ...). + # But at this point, the component registry is not guaranteed + # to be ready, and anyway we should probably not trigger events + # during the initialization. Hence we return an empty list of + # events, the 'notify' calls will do nothing. + return CollectedEvents([]) + + model_name = self._name + if collection is not None: + work = EventWorkContext(collection=collection, + model_name=model_name, + components_registry=components_registry) + else: + work = EventWorkContext(env=self.env, model_name=model_name, + components_registry=components_registry) + + collecter = work._component_class_by_name('base.event.collecter')(work) + return collecter.collect_events(name) + + @api.model + def create(self, vals): + record = super(Base, self).create(vals) + fields = list(vals.keys()) + self._event('on_record_create').notify(record, fields=fields) + return record + + @api.multi + def write(self, vals): + result = super(Base, self).write(vals) + fields = list(vals.keys()) + for record in self: + self._event('on_record_write').notify(record, fields=fields) + return result + + @api.multi + def unlink(self): + for record in self: + self._event('on_record_unlink').notify(record) + result = super(Base, self).unlink() + return result diff --git a/ext/3rd-party-addons/component_event/tests/__init__.py b/ext/3rd-party-addons/component_event/tests/__init__.py new file mode 100644 index 00000000..3fa87e4d --- /dev/null +++ b/ext/3rd-party-addons/component_event/tests/__init__.py @@ -0,0 +1,2 @@ +# -*- coding: utf-8 -*- +from . import test_event diff --git a/ext/3rd-party-addons/component_event/tests/test_event.py b/ext/3rd-party-addons/component_event/tests/test_event.py new file mode 100644 index 00000000..e92e532f --- /dev/null +++ b/ext/3rd-party-addons/component_event/tests/test_event.py @@ -0,0 +1,432 @@ +# -*- coding: utf-8 -*- +# Copyright 2017 Camptocamp SA +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html) + +import mock +import unittest + +from odoo.addons.component.tests.common import ( + ComponentRegistryCase, + TransactionComponentRegistryCase, +) +from odoo.addons.component.core import Component +from odoo.addons.component_event.core import EventWorkContext +from odoo.addons.component_event.components.event import skip_if + + +class TestEventWorkContext(unittest.TestCase): + """ Test Events Components """ + + def setUp(self): + super(TestEventWorkContext, self).setUp() + self.env = mock.MagicMock(name='env') + self.record = mock.MagicMock(name='record') + self.components_registry = mock.MagicMock(name='ComponentRegistry') + + def test_env(self): + """ WorkContext with env """ + work = EventWorkContext(model_name='res.users', env=self.env, + components_registry=self.components_registry) + self.assertEqual(self.env, work.env) + self.assertEqual('res.users', work.model_name) + with self.assertRaises(ValueError): + # pylint: disable=W0104 + work.collection # noqa + + def test_collection(self): + """ WorkContext with collection """ + env = mock.MagicMock(name='env') + collection = mock.MagicMock(name='collection') + collection.env = env + work = EventWorkContext(model_name='res.users', collection=collection, + components_registry=self.components_registry) + self.assertEqual(collection, work.collection) + self.assertEqual(env, work.env) + self.assertEqual('res.users', work.model_name) + + def test_env_and_collection(self): + """ WorkContext with collection and env is forbidden """ + env = mock.MagicMock(name='env') + collection = mock.MagicMock(name='collection') + collection.env = env + with self.assertRaises(ValueError): + EventWorkContext(model_name='res.users', collection=collection, + env=env, + components_registry=self.components_registry) + + def test_missing(self): + """ WorkContext with collection and env is forbidden """ + with self.assertRaises(ValueError): + EventWorkContext(model_name='res.users', + components_registry=self.components_registry) + + def test_env_work_on(self): + """ WorkContext propagated through work_on """ + env = mock.MagicMock(name='env') + collection = mock.MagicMock(name='collection') + collection.env = env + work = EventWorkContext(env=env, model_name='res.users', + components_registry=self.components_registry) + work2 = work.work_on(model_name='res.partner', collection=collection) + self.assertEqual('WorkContext', work2.__class__.__name__) + self.assertEqual(env, work2.env) + self.assertEqual('res.partner', work2.model_name) + self.assertEqual(self.components_registry, work2.components_registry) + with self.assertRaises(ValueError): + # pylint: disable=W0104 + work.collection # noqa + + def test_collection_work_on(self): + """ WorkContext propagated through work_on """ + env = mock.MagicMock(name='env') + collection = mock.MagicMock(name='collection') + collection.env = env + work = EventWorkContext(collection=collection, model_name='res.users', + components_registry=self.components_registry) + work2 = work.work_on(model_name='res.partner') + self.assertEqual('WorkContext', work2.__class__.__name__) + self.assertEqual(collection, work2.collection) + self.assertEqual(env, work2.env) + self.assertEqual('res.partner', work2.model_name) + self.assertEqual(self.components_registry, work2.components_registry) + + def test_collection_work_on_collection(self): + """ WorkContext collection changed with work_on """ + env = mock.MagicMock(name='env') + collection = mock.MagicMock(name='collection') + collection.env = env + work = EventWorkContext(model_name='res.users', env=env, + components_registry=self.components_registry) + work2 = work.work_on(collection=collection) + # when work_on is used inside an event component, we want + # to switch back to a normal WorkContext, because we don't + # need anymore the EventWorkContext + self.assertEqual('WorkContext', work2.__class__.__name__) + self.assertEqual(collection, work2.collection) + self.assertEqual(env, work2.env) + self.assertEqual('res.users', work2.model_name) + self.assertEqual(self.components_registry, work2.components_registry) + + +class TestEvent(ComponentRegistryCase): + """ Test Events Components """ + + def setUp(self): + super(TestEvent, self).setUp() + self._load_module_components('component_event') + + # get the collecter to notify the event + # we don't mind about the collection and the model here, + # the events we test are global + env = mock.MagicMock() + self.work = EventWorkContext(model_name='res.users', env=env, + components_registry=self.comp_registry) + self.collecter = self.comp_registry['base.event.collecter'](self.work) + + def test_event(self): + class MyEventListener(Component): + _name = 'my.event.listener' + _inherit = 'base.event.listener' + + def on_record_create(self, recipient, something, fields=None): + recipient.append(('OK', something, fields)) + + MyEventListener._build_component(self.comp_registry) + + something = object() + fields = ['name', 'code'] + + # as there is no return value by the event, we + # modify this recipient to check it has been called + recipient = [] + + # collect the event and notify it + self.collecter.collect_events('on_record_create').notify( + recipient, something, fields=fields + ) + self.assertEqual([('OK', something, fields)], recipient) + + def test_collect_several(self): + class MyEventListener(Component): + _name = 'my.event.listener' + _inherit = 'base.event.listener' + + def on_record_create(self, recipient, something, fields=None): + recipient.append(('OK', something, fields)) + + class MyOtherEventListener(Component): + _name = 'my.other.event.listener' + _inherit = 'base.event.listener' + + def on_record_create(self, recipient, something, fields=None): + recipient.append(('OK', something, fields)) + + MyEventListener._build_component(self.comp_registry) + MyOtherEventListener._build_component(self.comp_registry) + + something = object() + fields = ['name', 'code'] + + # as there is no return value by the event, we + # modify this recipient to check it has been called + recipient = [] + + # collect the event and notify them + collected = self.collecter.collect_events('on_record_create') + self.assertEqual(2, len(collected.events)) + + collected.notify(recipient, something, fields=fields) + self.assertEqual([('OK', something, fields), + ('OK', something, fields)], recipient) + + def test_event_cache(self): + class MyEventListener(Component): + _name = 'my.event.listener' + _inherit = 'base.event.listener' + + def on_record_create(self): + pass + + MyEventListener._build_component(self.comp_registry) + + # collect the event + collected = self.collecter.collect_events('on_record_create') + # CollectedEvents.events contains the collected events + self.assertEqual(1, len(collected.events)) + event = list(collected.events)[0] + self.assertEqual(self.work, event.__self__.work) + self.assertEqual(self.work.env, event.__self__.work.env) + + # build and register a new listener + class MyOtherEventListener(Component): + _name = 'my.other.event.listener' + _inherit = 'base.event.listener' + + def on_record_create(self): + pass + + MyOtherEventListener._build_component(self.comp_registry) + + # get a new collecter and check that we it finds the same + # events even if we built a new one: it means the cache works + env = mock.MagicMock() + work = EventWorkContext(model_name='res.users', env=env, + components_registry=self.comp_registry) + collecter = self.comp_registry['base.event.collecter'](work) + collected = collecter.collect_events('on_record_create') + # CollectedEvents.events contains the collected events + self.assertEqual(1, len(collected.events)) + event = list(collected.events)[0] + self.assertEqual(work, event.__self__.work) + self.assertEqual(env, event.__self__.work.env) + + # if we empty the cache, as it on the class, both collecters + # should now find the 2 events + collecter._cache.clear() + self.comp_registry._cache.clear() + # CollectedEvents.events contains the collected events + self.assertEqual( + 2, + len(collecter.collect_events('on_record_create').events) + ) + self.assertEqual( + 2, + len(self.collecter.collect_events('on_record_create').events) + ) + + def test_event_cache_collection(self): + class MyEventListener(Component): + _name = 'my.event.listener' + _inherit = 'base.event.listener' + + def on_record_create(self): + pass + + MyEventListener._build_component(self.comp_registry) + + # collect the event + collected = self.collecter.collect_events('on_record_create') + # CollectedEvents.events contains the collected events + self.assertEqual(1, len(collected.events)) + + # build and register a new listener + class MyOtherEventListener(Component): + _name = 'my.other.event.listener' + _inherit = 'base.event.listener' + _collection = 'base.collection' + + def on_record_create(self): + pass + + MyOtherEventListener._build_component(self.comp_registry) + + # get a new collecter and check that we it finds the same + # events even if we built a new one: it means the cache works + collection = mock.MagicMock(name='base.collection') + collection._name = 'base.collection' + collection.env = mock.MagicMock() + work = EventWorkContext(model_name='res.users', collection=collection, + components_registry=self.comp_registry) + collecter = self.comp_registry['base.event.collecter'](work) + collected = collecter.collect_events('on_record_create') + # for a different collection, we should not have the same + # cache entry + self.assertEqual(2, len(collected.events)) + + def test_event_cache_model_name(self): + class MyEventListener(Component): + _name = 'my.event.listener' + _inherit = 'base.event.listener' + + def on_record_create(self): + pass + + MyEventListener._build_component(self.comp_registry) + + # collect the event + collected = self.collecter.collect_events('on_record_create') + # CollectedEvents.events contains the collected events + self.assertEqual(1, len(collected.events)) + + # build and register a new listener + class MyOtherEventListener(Component): + _name = 'my.other.event.listener' + _inherit = 'base.event.listener' + _apply_on = ['res.country'] + + def on_record_create(self): + pass + + MyOtherEventListener._build_component(self.comp_registry) + + # get a new collecter and check that we it finds the same + # events even if we built a new one: it means the cache works + env = mock.MagicMock() + work = EventWorkContext(model_name='res.country', env=env, + components_registry=self.comp_registry) + collecter = self.comp_registry['base.event.collecter'](work) + collected = collecter.collect_events('on_record_create') + # for a different collection, we should not have the same + # cache entry + self.assertEqual(2, len(collected.events)) + + def test_skip_if(self): + class MyEventListener(Component): + _name = 'my.event.listener' + _inherit = 'base.event.listener' + + def on_record_create(self, msg): + assert True + + class MyOtherEventListener(Component): + _name = 'my.other.event.listener' + _inherit = 'base.event.listener' + + @skip_if(lambda self, msg: msg == 'foo') + def on_record_create(self, msg): + assert False + + self._build_components(MyEventListener, MyOtherEventListener) + + # collect the event and notify it + collected = self.collecter.collect_events('on_record_create') + self.assertEqual(2, len(collected.events)) + collected.notify('foo') + + +class TestEventFromModel(TransactionComponentRegistryCase): + """ Test Events Components from Models """ + + def setUp(self): + super(TestEventFromModel, self).setUp() + self._load_module_components('component_event') + + def test_event_from_model(self): + class MyEventListener(Component): + _name = 'my.event.listener' + _inherit = 'base.event.listener' + + def on_foo(self, record, name): + record.name = name + + MyEventListener._build_component(self.comp_registry) + + partner = self.env['res.partner'].create({'name': 'test'}) + # Normally you would not pass a components_registry, + # this is for the sake of the test, letting it empty + # will use the global registry. + # In a real code it would look like: + # partner._event('on_foo').notify('bar') + events = partner._event('on_foo', + components_registry=self.comp_registry) + events.notify(partner, 'bar') + self.assertEqual('bar', partner.name) + + def test_event_filter_on_model(self): + class GlobalListener(Component): + _name = 'global.event.listener' + _inherit = 'base.event.listener' + + def on_foo(self, record, name): + record.name = name + + class PartnerListener(Component): + _name = 'partner.event.listener' + _inherit = 'base.event.listener' + _apply_on = ['res.partner'] + + def on_foo(self, record, name): + record.ref = name + + class UserListener(Component): + _name = 'user.event.listener' + _inherit = 'base.event.listener' + _apply_on = ['res.users'] + + def on_foo(self, record, name): + assert False + + self._build_components(GlobalListener, PartnerListener, UserListener) + + partner = self.env['res.partner'].create({'name': 'test'}) + partner._event( + 'on_foo', + components_registry=self.comp_registry + ).notify(partner, 'bar') + self.assertEqual('bar', partner.name) + self.assertEqual('bar', partner.ref) + + def test_event_filter_on_collection(self): + class GlobalListener(Component): + _name = 'global.event.listener' + _inherit = 'base.event.listener' + + def on_foo(self, record, name): + record.name = name + + class PartnerListener(Component): + _name = 'partner.event.listener' + _inherit = 'base.event.listener' + _collection = 'collection.base' + + def on_foo(self, record, name): + record.ref = name + + class UserListener(Component): + _name = 'user.event.listener' + _inherit = 'base.event.listener' + _collection = 'magento.backend' + + def on_foo(self, record, name): + assert False + + self._build_components(GlobalListener, PartnerListener, UserListener) + + partner = self.env['res.partner'].create({'name': 'test'}) + events = partner._event( + 'on_foo', collection=self.env['collection.base'], + components_registry=self.comp_registry + ) + events.notify(partner, 'bar') + self.assertEqual('bar', partner.name) + self.assertEqual('bar', partner.ref) diff --git a/ext/3rd-party-addons/connector/AUTHORS b/ext/3rd-party-addons/connector/AUTHORS new file mode 100644 index 00000000..b311dd43 --- /dev/null +++ b/ext/3rd-party-addons/connector/AUTHORS @@ -0,0 +1,24 @@ +* Guewen Baconnier at Camptocamp +* Alexandre Fayolle at Camptocamp +* Benoit Guillot at Akretion +* Nicolas Bessi at Camptocamp +* Joël Grand-Guillaume at Camptocamp +* Arthur Vuillard at Akretion +* Sebastien Beau at Akretion +* Laurent Mignon at Acsone +* Leonardo Pistone at Camptocamp +* David Béal at Akretion +* Christophe Combelles at Anybox +* Stéphane Bidoul at Acsone +* Malte Jacobi at IBO / HTW +* Laetitia Gangloff at Acsone +* David Lefever at Taktik S.A. +* Jos de Graeve at Apertoso NV +* Jean-Sébastien Suzanne at Anybox +* Leonardo Donelli at MONK Software +* Mathias Colpaert +* Yannick Vaucher at Camptocamp +* Nicolas Piganeau at NDP Systèmes +* Florent Thomas at Mind And Go +* Matthieu Dietrich at Camptocamp +* Olivier Laurent at Acsone diff --git a/ext/3rd-party-addons/connector/CHANGES.rst b/ext/3rd-party-addons/connector/CHANGES.rst new file mode 100644 index 00000000..43bf9adf --- /dev/null +++ b/ext/3rd-party-addons/connector/CHANGES.rst @@ -0,0 +1,201 @@ +Changelog +--------- + +.. Future (?) +.. ~~~~~~~~~~ +.. +.. * + +Future (?) +~~~~~~~~~~ + +* Fix backend_to_m2o to extract id of the binding (https://github.com/OCA/connector/pull/194) +* Remove cancellation of jobs / active flag on jobs, now jobs are only set to + Done when NothingToDoJob is raised. + +9.0.1.0.2 (2016-03-03) +~~~~~~~~~~~~~~~~~~~~~~ + +* Fix: adapt to upstream api change to obtain db connection (https://github.com/OCA/connector/pull/179) + +9.0.1.0.1 (2016-03-03) +~~~~~~~~~~~~~~~~~~~~~~ + +* Enabled the JobRunner by default, with a default channels configuration of root:1 +* Removed the old workers +* Removed the broken dbfilter support (https://github.com/OCA/connector/issues/58) +* Cleaned the methods that have been deprecated in version 3.x + + +8.0.3.3.0 (2016-02-29) +~~~~~~~~~~~~~~~~~~~~~~ + +* Allow to define seconds when raising a RetryableJobError (https://github.com/OCA/connector/pull/124) +* Allow to ignore the retry counter when raising a RetryableJobError (https://github.com/OCA/connector/pull/124) +* Add 'mock_job_delay_to_direct' to ease tests on jobs (https://github.com/OCA/connector/pull/123) +* Add helper function to acquire Posgres advisory locks (https://github.com/OCA/connector/pull/138, https://github.com/OCA/connector/pull/139) +* Improvement of 'is_module_installed' which now uses the registry instead of db + cache (https://github.com/OCA/connector/pull/130) +* Security: Prevent to unpickle globals which are not jobs or whitelisted types (https://github.com/OCA/connector/pull/170) +* Fix: Manage non-ascii Postgres errors (https://github.com/OCA/connector/pull/167) +* Fix: ignore dbfilter containing %d or %h (https://github.com/OCA/connector/pull/166) +* Fix: correctly obtain the list of database with odoo is started with --no-database-list (https://github.com/OCA/connector/pull/164) +* Fix: Set job back to 'pending' in case of exception (https://github.com/OCA/connector/pull/150, https://github.com/OCA/connector/pull/151, https://github.com/OCA/connector/pull/152, https://github.com/OCA/connector/pull/155) +* Fix: Clear environment caches and recomputations upon failures (https://github.com/OCA/connector/pull/131) +* Fix: when a job fails, inactive users are no longer added to its followers (https://github.com/OCA/connector/pull/137) +* Fix: Set job to failed after non-retryable OperationalError (https://github.com/OCA/connector/pull/132) +* Fix: wrong model in connector_base_product's views (https://github.com/OCA/connector/pull/119) +* Various documentation improvements + + +3.2.0 (2015-09-10) +~~~~~~~~~~~~~~~~~~ + +* method 'install_in_connector' is now deprecated (https://github.com/OCA/connector/pull/74) +* Add a retry pattern for jobs (https://github.com/OCA/connector/pull/75, https://github.com/OCA/connector/pull/92) +* Use custom connector environments and instantiate them with needed attributes (https://github.com/OCA/connector/pull/108) +* A new default implementation for the binder (https://github.com/OCA/connector/pull/76) +* Translations are now automatically synchronized from Transifex +* Mapper: add modifier to follow m2o relations with dot notation (https://github.com/OCA/connector/pull/94) +* Mapper: add 'changed_by_fields' which indicates which source fields will output data (https://github.com/OCA/connector/pull/73) +* Allow to assign a default channel on @job functions (https://github.com/OCA/connector/pull/71) +* Fix: connector-runner: manages retryable errors (https://github.com/OCA/connector/pull/87) +* Fix: connector-runner: logging error when a capacity is None (https://github.com/OCA/connector/pull/98) +* Fix: connector-runner: shows a wrong job result on retried jobs (https://github.com/OCA/connector/pull/101) +* Fix: add an index on queue_job.worker_id (https://github.com/OCA/connector/pull/89) +* Fix: Tests: common.DB is gone in 8.0 stable (https://github.com/OCA/connector/pull/79) +* Fix: connector-runner: graceful stop mechanism (https://github.com/OCA/connector/pull/69) +* Fix: connector-runner: Wrong arguments position in a log message (https://github.com/OCA/connector/pull/67) + + +3.1.0 (2015-05-15) +~~~~~~~~~~~~~~~~~~ + +* New jobs runner (details on https://github.com/OCA/connector/pull/52) +* French documentation (https://github.com/OCA/connector/pull/57) +* Add ConnectorSession.from_env() (https://github.com/OCA/connector/pull/66) +* Fix: missing indexes on jobs (https://github.com/OCA/connector/pull/65) + + +3.0.0 (2015-04-01) +~~~~~~~~~~~~~~~~~~ + +/!\ Backwards incompatible changes inside. + +* Add ``openerp.api.Environment`` in ``Session`` + It is accessible in ``self.env`` in ``Session`` and all + ``ConnectorUnit`` instances. + Also in ``ConnectorUnit``, ``model`` returns the current (new api!) model: + + .. code-block:: python + + # On the current model + self.model.search([]) + self.model.browse(ids) + # on another model + self.env['res.users'].search([]) + self.env['res.users'].browse(ids) + +* Deprecate the CRUD methods in ``Session`` + + .. code-block:: python + + # NO + self.session.search('res.partner', []) + self.session.browse('res.partner', ids) + + # YES + self.env['res.partner'].search([]) + self.env['res.partner'].browse(ids) + +* ``Environment.set_lang()`` is removed. It was modifying the context + in place which is not possible with the new frozendict context. It + should be done with: + + .. code-block:: python + + with self.session.change_context(lang=lang_code): + ... + +* Add an argument on the Binders methods to return a browse record + + .. code-block:: python + + binder.to_openerp(magento_id, browse=True) + +* Shorten ``ConnectorUnit.get_binder_for_model`` to + ``ConnectorUnit.binder_for`` +* Shorten ``ConnectorUnit.get_connector_unit_for_model`` to + ``ConnectorUnit.unit_for`` +* Renamed ``Environment`` to ``ConnectorEnvironment`` to avoid + confusion with ``openerp.api.Environment`` +* Renamed the class attribute ``ConnectorUnit.model_name`` to + ``ConnectorUnit.for_model_name``. +* Added ``_base_binder``, ``_base_mapper``, ``_base_backend_adapter`` in + the synchronizers (Importer, Exporter) so it is no longer required to + override the ``binder``, ``mapper``, ``backend_adapter`` property + methods +* ``Session.change_context()`` now supports the same + argument/keyword arguments semantics than + ``openerp.model.BaseModel.with_context()``. +* Renamed ``ExportSynchronizer`` to ``Exporter`` +* Renamed ``ImportSynchronizer`` to ``Importer`` +* Renamed ``DeleteSynchronizer`` to ``Deleter`` +* ``Session.commit`` do not commit when tests are running +* Cleaned the methods that have been deprecated in version 2.x + + +2.2.0 (2014-05-26) +~~~~~~~~~~~~~~~~~~ + +* Job arguments can now contain unicode strings (thanks to Stéphane Bidoul) lp:1288187 +* List view of the jobs improved +* Jobs now support multicompany (thanks to Laurent Mignon) https://lists.launchpad.net/openerp-connector-community/msg00253.html) +* An action can be assigned to a job. The action is called with a button on the job and could be something like open a form view or an url. + +2.1.1 (2014-02-06) +~~~~~~~~~~~~~~~~~~ + +* A user can be blocked because he has no access to the model queue.job when a + job has been delayed. The creation of a job is low level and should not be + restrained by the accesses of the user. (lp:1276182) + +2.1.0 (2014-01-15 - warning: breaks compatibility) +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +* Add a new optional keyword argument 'description' to the delay() function of a + job. If given, the description is used as name of the queue.job record stored + in OpenERP and displayed in the list of jobs. +* Fix: assignment of jobs to workers respect the priority of the jobs (lp:1252681) +* Pass a new parameter to listeners of 'on_record_create' ( vals: field values + of the new record, e.g {'field_name': field_value, ...}) +* Replace the list of updated fields passed to listeners of 'on_record_write' + by a dictionary of updated field values e.g {'field_name': field_value, ...} +* Add the possibility to use 'Modifiers' functions in the 'direct + mappings' (details in the documentation of the Mapper class) +* When a job a delayed, the job's UUID is returned by the delay() function +* Refactoring of mappers. Much details here: + https://code.launchpad.net/~openerp-connector-core-editors/openerp-connector/7.0-connector-mapper-refactor/+merge/194485 + +2.0.1 (2013-09-12) +~~~~~~~~~~~~~~~~~~ + +* Developers of addons do no longer need to create an AbstractModel with a _name 'name_of_the_module.installed', + instead, they just have to call connector.connector.install_in_connector() lp:1196859 +* Added a script `openerp-connector-worker` to start processes for Jobs Workers when running OpenERP is multiprocessing +* Fix: inheritance broken when an orm.Model inherit from an orm.AbstractModel. One effect was that the mail.thread features were no longer working (lp:1233355) +* Fix: do no fail to start when OpenERP has access to a not-OpenERP database (lp:1233388) + + +2.0.0 +~~~~~ + +* First release + + +.. + Model: + 2.0.1 (date of release) + ~~~~~~~~~~~~~~~~~~~~~~~ + + * change 1 + * change 2 diff --git a/ext/3rd-party-addons/connector/README.rst b/ext/3rd-party-addons/connector/README.rst new file mode 100644 index 00000000..ec2be42f --- /dev/null +++ b/ext/3rd-party-addons/connector/README.rst @@ -0,0 +1,86 @@ +.. image:: https://img.shields.io/badge/licence-AGPL--3-blue.svg + :alt: License + +Connector +========= + +This is a framework designed to build connectors with external systems, +usually called ``Backends`` in the documentation. + +Documentation: http://odoo-connector.com + +It features: + +* A jobs queue + + In which the connectors can push functions (synchronization tasks) + to be executed later. + +* An event pattern + + The connectors can subscribe listener functions on the events, + executed when the events are fired. + +* Connector base classes + + Called ``ConnectorUnit``. + + Include base classes for the use in connectors, ready to be extended: + + * ``Synchronizer``: flow of an import or export + * ``Mapper``: transform a record according to mapping rules + * ``Binder``: link external IDs with local IDS + * ``BackendAdapter``: adapter interface for the exchanges with the backend + * But ``ConnectorUnit`` can be extended to accomplish any task + +* A multi-backend support + + Each ``ConnectorUnit`` can be registered amongst a backend type (eg. + Magento) and a backend version (allow to have a different ``Mapper`` + for each backend's version for instance) + +It is used for example used to connect Magento_ and Prestashop_, but +also used with Solr, CMIS, ... + +.. _Magento: http://odoo-magento-connector.com +.. _Prestashop: https://github.com/OCA/connector-prestashop + +Configuration and usage +======================= + +This module does nothing on its own. It is a ground for developing +advanced connector modules. For further information, please go on: +http://odoo-connector.com + + +Bug Tracker +=========== + +Bugs are tracked on `GitHub 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 +`here `_. + + +Credits +======= + +Contributors +------------ + +Read the `contributors list`_ + +.. _contributors list: ./AUTHORS + +Maintainer +---------- + +.. image:: http://odoo-community.org/logo.png + :alt: Odoo Community Association + :target: http://odoo-community.org + +This module is maintained by the OCA. + +OCA, or the Odoo Community Association, is a nonprofit organization whose mission is to support the collaborative development of Odoo features and promote its widespread use. + +To contribute to this module, please visit http://odoo-community.org. diff --git a/ext/3rd-party-addons/connector/__init__.py b/ext/3rd-party-addons/connector/__init__.py new file mode 100644 index 00000000..57a162a3 --- /dev/null +++ b/ext/3rd-party-addons/connector/__init__.py @@ -0,0 +1,3 @@ +# -*- coding: utf-8 -*- +from . import components +from . import models diff --git a/ext/3rd-party-addons/connector/__manifest__.py b/ext/3rd-party-addons/connector/__manifest__.py new file mode 100644 index 00000000..c801e407 --- /dev/null +++ b/ext/3rd-party-addons/connector/__manifest__.py @@ -0,0 +1,25 @@ +# -*- coding: utf-8 -*- +# Copyright 2013-2017 Camptocamp SA +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html) + +{'name': 'Connector', + 'version': '11.0.1.0.0', + 'author': 'Camptocamp,Openerp Connector Core Editors,' + 'Odoo Community Association (OCA)', + 'website': 'http://odoo-connector.com', + 'license': 'AGPL-3', + 'category': 'Generic Modules', + 'depends': ['mail', + 'queue_job', + 'component', + 'component_event', + ], + 'data': ['security/connector_security.xml', + 'security/ir.model.access.csv', + 'views/checkpoint_views.xml', + 'views/connector_menu.xml', + 'views/setting_views.xml', + 'views/res_partner_views.xml', + ], + 'installable': True, + } diff --git a/ext/3rd-party-addons/connector/components/__init__.py b/ext/3rd-party-addons/connector/components/__init__.py new file mode 100644 index 00000000..a8e062d3 --- /dev/null +++ b/ext/3rd-party-addons/connector/components/__init__.py @@ -0,0 +1,7 @@ +# -*- coding: utf-8 -*- +from . import core +from . import backend_adapter +from . import binder +from . import mapper +from . import listener +from . import synchronizer diff --git a/ext/3rd-party-addons/connector/components/backend_adapter.py b/ext/3rd-party-addons/connector/components/backend_adapter.py new file mode 100644 index 00000000..70883056 --- /dev/null +++ b/ext/3rd-party-addons/connector/components/backend_adapter.py @@ -0,0 +1,64 @@ +# -*- coding: utf-8 -*- +# Copyright 2013-2017 Camptocamp SA +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html) + +""" + +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. + +""" + +from odoo.addons.component.core import AbstractComponent + + +class BackendAdapter(AbstractComponent): + """ Base Backend Adapter for the connectors """ + + _name = 'base.backend.adapter' + _inherit = 'base.connector' + _usage = 'backend.adapter' + + +class CRUDAdapter(AbstractComponent): + """ Base External Adapter specialized in the handling + of records on external systems. + + This is an empty shell, Components can inherit and implement their own + implementation for the methods. + + """ + + _name = 'base.backend.adapter.crud' + _inherit = 'base.backend.adapter' + _usage = 'backend.adapter' + + def search(self, *args, **kwargs): + """ Search records according to some criterias + and returns a list of ids """ + raise NotImplementedError + + def read(self, *args, **kwargs): + """ Returns the information of a record """ + raise NotImplementedError + + def search_read(self, *args, **kwargs): + """ Search records according to some criterias + and returns their information""" + raise NotImplementedError + + def create(self, *args, **kwargs): + """ Create a record on the external system """ + raise NotImplementedError + + def write(self, *args, **kwargs): + """ Update records on the external system """ + raise NotImplementedError + + def delete(self, *args, **kwargs): + """ Delete a record on the external system """ + raise NotImplementedError diff --git a/ext/3rd-party-addons/connector/components/binder.py b/ext/3rd-party-addons/connector/components/binder.py new file mode 100644 index 00000000..fd89363c --- /dev/null +++ b/ext/3rd-party-addons/connector/components/binder.py @@ -0,0 +1,140 @@ +# -*- 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 diff --git a/ext/3rd-party-addons/connector/components/core.py b/ext/3rd-party-addons/connector/components/core.py new file mode 100644 index 00000000..e7c32936 --- /dev/null +++ b/ext/3rd-party-addons/connector/components/core.py @@ -0,0 +1,130 @@ +# -*- coding: utf-8 -*- +# Copyright 2017 Camptocamp SA +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html) + +""" + +Base Component +============== + +The connector proposes a 'base' Component, which can be used in +the ``_inherit`` of your own components. This is not a +requirement. It is already inherited by every component +provided by the Connector. + +Components are organized according to different usages. The connector suggests +5 main kinds of Components. Each might have a few different usages. You can be +as creative as you want when it comes to creating new ones though. + +One "usage" is responsible for a specific work, and alongside with the +collection (the backend) and the model, the usage will be used to find the +needed component for a task. + +Some of the Components have an implementation in the ``Connector`` addon, but +some are empty shells that need to be implemented in the different connectors. + +The usual categories are: + +:py:class:`~connector.components.binder.Binder` + The ``binders`` give the external ID or Odoo ID from respectively an + Odoo ID or an external ID. A default implementation is available. + + Most common usages: + + * ``binder`` + +:py:class:`~connector.components.mapper.Mapper` + The ``mappers`` transform a external record into an Odoo record or + conversely. + + Most common usages: + + * ``import.mapper`` + * ``export.mapper`` + +:py:class:`~connector.components.backend_adapter.BackendAdapter` + The ``backend.adapters`` implements the discussion with the ``backend's`` + APIs. They usually adapt their APIs to a common interface (CRUD). + + Most common usages: + + * ``backend.adapter`` + +:py:class:`~connector.components.synchronizer.Synchronizer` + A ``synchronizer`` is the main piece of a synchronization. It + orchestrates the flow of a synchronization and use the other + Components + + Most common usages: + + * ``record.importer`` + * ``record.exporter`` + * ``batch.importer`` + * ``batch.exporter`` + + +""" + +from odoo.addons.component.core import AbstractComponent +from odoo.addons.queue_job.exception import RetryableJobError +from ..database import pg_try_advisory_lock + + +class BaseConnectorComponent(AbstractComponent): + """ Base component for the connector + + Is inherited by every components of the Connector (Binder, Mapper, ...) + and adds a few methods which are of common usage in the connectors. + + """ + + _name = 'base.connector' + + @property + def backend_record(self): + """ Backend record we are working with """ + # backward compatibility + return self.work.collection + + def binder_for(self, model=None): + """ Shortcut to get Binder for a model + + Equivalent to: ``self.component(usage='binder', model_name='xxx')`` + + """ + return self.component(usage='binder', model_name=model) + + def advisory_lock_or_retry(self, lock, retry_seconds=1): + """ Acquire a Postgres transactional advisory lock or retry job + + When the lock cannot be acquired, it raises a + :exc:`odoo.addons.queue_job.exception.RetryableJobError` so the job + is retried after n ``retry_seconds``. + + Usage example: + + .. code-block:: python + + lock_name = 'import_record({}, {}, {}, {})'.format( + self.backend_record._name, + self.backend_record.id, + self.model._name, + self.external_id, + ) + self.advisory_lock_or_retry(lock_name, retry_seconds=2) + + See :func:`odoo.addons.connector.connector.pg_try_advisory_lock` for + details. + + :param lock: The lock name. Can be anything convertible to a + string. It needs to represent what should not be synchronized + concurrently, usually the string will contain at least: the + action, the backend name, the backend id, the model name, the + external id + :param retry_seconds: number of seconds after which a job should + be retried when the lock cannot be acquired. + """ + if not pg_try_advisory_lock(self.env, lock): + raise RetryableJobError('Could not acquire advisory lock', + seconds=retry_seconds, + ignore_retry=True) diff --git a/ext/3rd-party-addons/connector/components/listener.py b/ext/3rd-party-addons/connector/components/listener.py new file mode 100644 index 00000000..bee85528 --- /dev/null +++ b/ext/3rd-party-addons/connector/components/listener.py @@ -0,0 +1,50 @@ +# -*- coding: utf-8 -*- +# Copyright 2013-2017 Camptocamp SA +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html) + +""" +Listeners +========= + +Listeners are Components notified when events happen. +Documentation in :mod:`odoo.addons.component_event.components.event` + +The base listener for the connectors add a method +:meth:`ConnectorListener.no_connector_export` which can be used with +:func:`odoo.addons.component_event.skip_if`. + + +""" + +from odoo.addons.component.core import AbstractComponent + + +class ConnectorListener(AbstractComponent): + """ Base Backend Adapter for the connectors """ + + _name = 'base.connector.listener' + _inherit = ['base.connector', 'base.event.listener'] + + def no_connector_export(self, record): + """ Return if the 'connector_no_export' has been set in context + + To be used with :func:`odoo.addons.component_event.skip_if` + on Events:: + + from odoo.addons.component.core import Component + from odoo.addons.component_event import skip_if + + + class MyEventListener(Component): + _name = 'my.event.listener' + _inherit = 'base.connector.event.listener' + _apply_on = ['magento.res.partner'] + + @skip_if(lambda: self, record, *args, **kwargs: + self.no_connector_export(record)) + def on_record_write(self, record, fields=None): + record.with_delay().export_record() + + """ + return (record.env.context.get('no_connector_export') or + record.env.context.get('connector_no_export')) diff --git a/ext/3rd-party-addons/connector/components/mapper.py b/ext/3rd-party-addons/connector/components/mapper.py new file mode 100644 index 00000000..24d8f745 --- /dev/null +++ b/ext/3rd-party-addons/connector/components/mapper.py @@ -0,0 +1,1011 @@ +# -*- coding: utf-8 -*- +# Copyright 2017 Camptocamp SA +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html) + +""" + +Mappers +======= + +Mappers are the components responsible to transform +external records into Odoo records and conversely. + +""" + +import logging +from collections import namedtuple +from contextlib import contextmanager + +from odoo import models +from odoo.addons.component.core import AbstractComponent +from odoo.addons.component.exception import NoComponentError +from ..exception import MappingError +import collections + + +_logger = logging.getLogger(__name__) + + +def mapping(func): + """ Decorator, declare that a method is a mapping method. + + It is then used by the :py:class:`Mapper` to convert the records. + + Usage:: + + @mapping + def any(self, record): + return {'output_field': record['input_field']} + + """ + func.is_mapping = True + return func + + +def changed_by(*args): + """ Decorator for the mapping methods (:py:func:`mapping`) + + When fields are modified in Odoo, we want to export only the + modified fields. Using this decorator, we can specify which fields + updates should trigger which mapping method. + + If ``changed_by`` is empty, the mapping is always active. + + As far as possible, this decorator should be used for the exports, + thus, when we do an update on only a small number of fields on a + record, the size of the output record will be limited to only the + fields really having to be exported. + + Usage:: + + @changed_by('input_field') + @mapping + def any(self, record): + return {'output_field': record['input_field']} + + :param ``*args``: field names which trigger the mapping when modified + + """ + def register_mapping(func): + func.changed_by = args + return func + return register_mapping + + +def only_create(func): + """ Decorator for the mapping methods (:py:func:`mapping`) + + A mapping decorated with ``only_create`` means that it has to be + used only for the creation of the records. + + Usage:: + + @only_create + @mapping + def any(self, record): + return {'output_field': record['input_field']} + + """ + func.only_create = True + return func + + +def none(field): + """ A modifier intended to be used on the ``direct`` mappings. + + Replace the False-ish values by None. + It can be used in a pipeline of modifiers when . + + Example:: + + direct = [(none('source'), 'target'), + (none(m2o_to_external('rel_id'), 'rel_id')] + + :param field: name of the source field in the record + :param binding: True if the relation is a binding record + """ + def modifier(self, record, to_attr): + if isinstance(field, collections.Callable): + result = field(self, record, to_attr) + else: + result = record[field] + if not result: + return None + return result + return modifier + + +def convert(field, conv_type): + """ A modifier intended to be used on the ``direct`` mappings. + + Convert a field's value to a given type. + + Example:: + + direct = [(convert('source', str), 'target')] + + :param field: name of the source field in the record + :param binding: True if the relation is a binding record + """ + def modifier(self, record, to_attr): + value = record[field] + if not value: + return False + return conv_type(value) + return modifier + + +def m2o_to_external(field, binding=None): + """ A modifier intended to be used on the ``direct`` mappings. + + For a many2one, get the external ID and returns it. + + When the field's relation is not a binding (i.e. it does not point to + something like ``magento.*``), the binding model needs to be provided + in the ``binding`` keyword argument. + + Example:: + + direct = [(m2o_to_external('country_id', + binding='magento.res.country'), 'country'), + (m2o_to_external('magento_country_id'), 'country')] + + :param field: name of the source field in the record + :param binding: name of the binding model is the relation is not a binding + """ + def modifier(self, record, to_attr): + if not record[field]: + return False + column = self.model._fields[field] + if column.type != 'many2one': + raise ValueError('The column %s should be a Many2one, got %s' % + (field, type(column))) + rel_id = record[field].id + if binding is None: + binding_model = column.comodel_name + else: + binding_model = binding + binder = self.binder_for(binding_model) + # if a relation is not a binding, we wrap the record in the + # binding, we'll return the id of the binding + wrap = bool(binding) + value = binder.to_external(rel_id, wrap=wrap) + if not value: + raise MappingError("Can not find an external id for record " + "%s in model %s %s wrapping" % + (rel_id, binding_model, + 'with' if wrap else 'without')) + return value + return modifier + + +def external_to_m2o(field, binding=None): + """ A modifier intended to be used on the ``direct`` mappings. + + For a field from a backend which is an ID, search the corresponding + binding in Odoo and returns it. + + When the field's relation is not a binding (i.e. it does not point to + something like ``magento.*``), the binding model needs to be provided + in the ``binding`` keyword argument. + + Example:: + + direct = [(external_to_m2o('country', binding='magento.res.country'), + 'country_id'), + (external_to_m2o('country'), 'magento_country_id')] + + :param field: name of the source field in the record + :param binding: name of the binding model is the relation is not a binding + """ + def modifier(self, record, to_attr): + if not record[field]: + return False + column = self.model._fields[to_attr] + if column.type != 'many2one': + raise ValueError('The column %s should be a Many2one, got %s' % + (to_attr, type(column))) + rel_id = record[field] + if binding is None: + binding_model = column.comodel_name + else: + binding_model = binding + binder = self.binder_for(binding_model) + # if we want the normal record, not a binding, + # we ask to the binder to unwrap the binding + unwrap = bool(binding) + record = binder.to_internal(rel_id, unwrap=unwrap) + if not record: + raise MappingError("Can not find an existing %s for external " + "record %s %s unwrapping" % + (binding_model, rel_id, + 'with' if unwrap else 'without')) + if isinstance(record, models.BaseModel): + return record.id + else: + _logger.debug( + 'Binder for %s returned an id, ' + 'returning a record should be preferred.', binding_model + ) + return record + return modifier + + +def follow_m2o_relations(field): + """A modifier intended to be used on ``direct`` mappings. + + 'Follows' Many2one relations and return the final field value. + + Examples: + Assuming model is ``product.product``:: + + direct = [ + (follow_m2o_relations('product_tmpl_id.categ_id.name'), 'cat')] + + :param field: field "path", using dots for relations as usual in Odoo + """ + def modifier(self, record, to_attr): + attrs = field.split('.') + value = record + for attr in attrs: + value = getattr(value, attr) + return value + return modifier + + +MappingDefinition = namedtuple('MappingDefinition', + ['changed_by', + 'only_create']) + + +class MapChild(AbstractComponent): + """ MapChild is responsible to convert items. + + Items are sub-records of a main record. + In this example, the items are the records in ``lines``:: + + sales = {'name': 'SO10', + 'lines': [{'product_id': 1, 'quantity': 2}, + {'product_id': 2, 'quantity': 2}]} + + A MapChild is always called from another :py:class:`Mapper` which + provides a ``children`` configuration. + + Considering the example above, the "main" :py:class:`Mapper` would + returns something as follows:: + + {'name': 'SO10', + 'lines': [(0, 0, {'product_id': 11, 'quantity': 2}), + (0, 0, {'product_id': 12, 'quantity': 2})]} + + A MapChild is responsible to: + + * Find the :py:class:`Mapper` to convert the items + * Possibly filter out some lines (can be done by inheriting + :py:meth:`skip_item`) + * Convert the items' records using the found :py:class:`Mapper` + * Format the output values to the format expected by Odoo or the + backend (as seen above with ``(0, 0, {values})`` + + A MapChild can be extended like any other + :py:class:`~component.core.Component`. + However, it is not mandatory to explicitly create a MapChild for + each children mapping, the default one will be used + (:py:class:`ImportMapChild` or :py:class:`ExportMapChild`). + + The implementation by default does not take care of the updates: if + I import a sales order 2 times, the lines will be duplicated. This + is not a problem as long as an importation should only support the + creation (typical for sales orders). It can be implemented on a + case-by-case basis by inheriting :py:meth:`get_item_values` and + :py:meth:`format_items`. + + """ + + _name = 'base.map.child' + _inherit = 'base.connector' + + def _child_mapper(self): + raise NotImplementedError + + def skip_item(self, map_record): + """ Hook to implement in sub-classes when some child + records should be skipped. + + The parent record is accessible in ``map_record``. + If it returns True, the current child record is skipped. + + :param map_record: record that we are converting + :type map_record: :py:class:`MapRecord` + """ + return False + + def get_items(self, items, parent, to_attr, options): + """ Returns the formatted output values of items from a main record + + :param items: list of item records + :type items: list + :param parent: parent record + :param to_attr: destination field (can be used for introspecting + the relation) + :type to_attr: str + :param options: dict of options, herited from the main mapper + :return: formatted output values for the item + + """ + mapper = self._child_mapper() + mapped = [] + for item in items: + map_record = mapper.map_record(item, parent=parent) + if self.skip_item(map_record): + continue + item_values = self.get_item_values(map_record, to_attr, options) + if item_values: + mapped.append(item_values) + return self.format_items(mapped) + + def get_item_values(self, map_record, to_attr, options): + """ Get the raw values from the child Mappers for the items. + + It can be overridden for instance to: + + * Change options + * Use a :py:class:`~connector.connector.Binder` to know if an + item already exists to modify an existing item, rather than to + add it + + :param map_record: record that we are converting + :type map_record: :py:class:`MapRecord` + :param to_attr: destination field (can be used for introspecting + the relation) + :type to_attr: str + :param options: dict of options, herited from the main mapper + + """ + return map_record.values(**options) + + def format_items(self, items_values): + """ Format the values of the items mapped from the child Mappers. + + It can be overridden for instance to add the Odoo + relationships commands ``(6, 0, [IDs])``, ... + + As instance, it can be modified to handle update of existing + items: check if an 'id' has been defined by + :py:meth:`get_item_values` then use the ``(1, ID, {values}``) + command + + :param items_values: mapped values for the items + :type items_values: list + + """ + return items_values + + +class ImportMapChild(AbstractComponent): + """ :py:class:`MapChild` for the Imports """ + + _name = 'base.map.child.import' + _inherit = 'base.map.child' + _usage = 'import.map.child' + + def _child_mapper(self): + return self.component(usage='import.mapper') + + def format_items(self, items_values): + """ Format the values of the items mapped from the child Mappers. + + It can be overridden for instance to add the Odoo + relationships commands ``(6, 0, [IDs])``, ... + + As instance, it can be modified to handle update of existing + items: check if an 'id' has been defined by + :py:meth:`get_item_values` then use the ``(1, ID, {values}``) + command + + :param items_values: list of values for the items to create + :type items_values: list + + """ + return [(0, 0, values) for values in items_values] + + +class ExportMapChild(AbstractComponent): + """ :py:class:`MapChild` for the Exports """ + + _name = 'base.map.child.export' + _inherit = 'base.map.child' + _usage = 'export.map.child' + + def _child_mapper(self): + return self.component(usage='export.mapper') + + +class Mapper(AbstractComponent): + """ A Mapper translates an external record to an Odoo record and + conversely. The output of a Mapper is a ``dict``. + + 3 types of mappings are supported: + + Direct Mappings + Example:: + + direct = [('source', 'target')] + + Here, the ``source`` field will be copied in the ``target`` field. + + A modifier can be used in the source item. + The modifier will be applied to the source field before being + copied in the target field. + It should be a closure function respecting this idiom:: + + def a_function(field): + ''' ``field`` is the name of the source field. + + Naming the arg: ``field`` is required for the conversion''' + def modifier(self, record, to_attr): + ''' self is the current Mapper, + record is the current record to map, + to_attr is the target field''' + return record[field] + return modifier + + And used like that:: + + direct = [ + (a_function('source'), 'target'), + ] + + A more concrete example of modifier:: + + def convert(field, conv_type): + ''' Convert the source field to a defined ``conv_type`` + (ex. str) before returning it''' + def modifier(self, record, to_attr): + value = record[field] + if not value: + return None + return conv_type(value) + return modifier + + And used like that:: + + direct = [ + (convert('myfield', float), 'target_field'), + ] + + More examples of modifiers: + + * :py:func:`convert` + * :py:func:`m2o_to_external` + * :py:func:`external_to_m2o` + + Method Mappings + A mapping method allows to execute arbitrary code and return one + or many fields:: + + @mapping + def compute_state(self, record): + # compute some state, using the ``record`` or not + state = 'pending' + return {'state': state} + + We can also specify that a mapping methods should be applied + only when an object is created, and never applied on further + updates:: + + @only_create + @mapping + def default_warehouse(self, record): + # get default warehouse + warehouse_id = ... + return {'warehouse_id': warehouse_id} + + Submappings + When a record contains sub-items, like the lines of a sales order, + we can convert the children using another Mapper:: + + children = [('items', 'line_ids', 'model.name')] + + It allows to create the sales order and all its lines with the + same call to :py:meth:`odoo.models.BaseModel.create()`. + + When using ``children`` for items of a record, we need to create + a :py:class:`Mapper` for the model of the items, and optionally a + :py:class:`MapChild`. + + Usage of a Mapper:: + + >>> mapper = self.component(usage='mapper') + >>> map_record = mapper.map_record(record) + >>> values = map_record.values() + >>> values = map_record.values(only_create=True) + >>> values = map_record.values(fields=['name', 'street']) + + """ + + _name = 'base.mapper' + _inherit = 'base.connector' + _usage = 'mapper' + + direct = [] # direct conversion of a field to another (from_attr, to_attr) + children = [] # conversion of sub-records (from_attr, to_attr, model) + + _map_methods = None + + _map_child_usage = None + _map_child_fallback = None + + @classmethod + def _build_mapper_component(cls): + """ Build a Mapper component + + When a Mapper component is built, we will look into every of its bases + and look for methods decorated by ``@mapping`` or ``@changed_by``. We + keep the definitions in a ``_map_methods`` attribute for later use by + the Mapper instances. + + The ``__bases__`` of a newly generated Component are of 2 kinds: + + * other dynamically generated components (below 'base' and + 'second.mapper') + * "real" Python classes applied on top of existing components (here + ThirdMapper) + + :: + + >>> cls.__bases__ + (, + , + ) + + This method traverses these bases, from the bottom to the top, and + merges the mapping definitions. It reuses the computed definitions + for the generated components (for which this code already ran), and + inspect the real classes to find mapping methods. + + """ + + map_methods = {} + for base in reversed(cls.__bases__): + if hasattr(base, '_map_methods'): + # this is already a dynamically generated Component, so we can + # use it's existing mappings + base_map_methods = base._map_methods or {} + for attr_name, definition in base_map_methods.items(): + if attr_name in map_methods: + # Update the existing @changed_by with the content + # of each base (it is mutated in place). + mapping_changed_by = map_methods[attr_name].changed_by + mapping_changed_by.update(definition.changed_by) + # keep the last value for @only_create + if definition.only_create: + new_definition = MappingDefinition( + mapping_changed_by, + definition.only_create, + ) + map_methods[attr_name] = new_definition + else: + map_methods[attr_name] = definition + else: + # this is a real class that needs to be applied upon + # the base Components + for attr_name in dir(base): + attr = getattr(base, attr_name, None) + if not getattr(attr, 'is_mapping', None): + continue + has_only_create = getattr(attr, 'only_create', False) + mapping_changed_by = set(getattr(attr, 'changed_by', ())) + + # if already existing, it has been defined in an previous + # base, extend the @changed_by set + if map_methods.get(attr_name) is not None: + definition = map_methods[attr_name] + mapping_changed_by.update(definition.changed_by) + + # keep the last choice for only_create + definition = MappingDefinition(mapping_changed_by, + has_only_create) + map_methods[attr_name] = definition + + cls._map_methods = map_methods + + @classmethod + def _complete_component_build(cls): + super(Mapper, cls)._complete_component_build() + cls._build_mapper_component() + + def __init__(self, work): + super(Mapper, self).__init__(work) + self._options = None + + def _map_direct(self, record, from_attr, to_attr): + """ Apply the ``direct`` mappings. + + :param record: record to convert from a source to a target + :param from_attr: name of the source attribute or a callable + :type from_attr: callable | str + :param to_attr: name of the target attribute + :type to_attr: str + """ + raise NotImplementedError + + def _map_children(self, record, attr, model): + raise NotImplementedError + + @property + def map_methods(self): + """ Yield all the methods decorated with ``@mapping`` """ + for meth, definition in self._map_methods.items(): + yield getattr(self, meth), definition + + def _get_map_child_component(self, model_name): + try: + mapper_child = self.component(usage=self._map_child_usage, + model_name=model_name) + except NoComponentError: + assert self._map_child_fallback is not None, ( + "_map_child_fallback required") + # does not force developers to use a MapChild -> + # will use the default one if not explicitely defined + mapper_child = self.component_by_name( + self._map_child_fallback, + model_name=model_name + ) + return mapper_child + + def _map_child(self, map_record, from_attr, to_attr, model_name): + """ Convert items of the record as defined by children """ + assert self._map_child_usage is not None, "_map_child_usage required" + child_records = map_record.source[from_attr] + mapper_child = self._get_map_child_component(model_name) + items = mapper_child.get_items(child_records, map_record, + to_attr, options=self.options) + return items + + @contextmanager + def _mapping_options(self, options): + """ Change the mapping options for the Mapper. + + Context Manager to use in order to alter the behavior + of the mapping, when using ``_apply`` or ``finalize``. + + """ + current = self._options + self._options = options + yield + self._options = current + + @property + def options(self): + """ Options can be accessed in the mapping methods with + ``self.options``. """ + return self._options + + def changed_by_fields(self): + """ Build a set of fields used by the mapper + + It takes in account the ``direct`` fields and the fields used by + the decorator: ``changed_by``. + """ + changed_by = set() + if getattr(self, 'direct', None): + for from_attr, __ in self.direct: + fieldname = self._direct_source_field_name(from_attr) + changed_by.add(fieldname) + + for method_name, method_def in self._map_methods.items(): + changed_by |= method_def.changed_by + return changed_by + + def _direct_source_field_name(self, direct_entry): + """ Get the mapping field name. Goes through the function modifiers. + + Ex:: + + [(none(convert(field_name, str)), out_field_name)] + + It assumes that the modifier has ``field`` as first argument like:: + + def modifier(field, args): + + """ + fieldname = direct_entry + if isinstance(direct_entry, collections.Callable): + # Map the closure entries with variable names + cells = dict(list(zip( + direct_entry.__code__.co_freevars, + (c.cell_contents for c in direct_entry.__closure__)))) + assert 'field' in cells, "Modifier without 'field' argument." + if isinstance(cells['field'], collections.Callable): + fieldname = self._direct_source_field_name(cells['field']) + else: + fieldname = cells['field'] + return fieldname + + def map_record(self, record, parent=None): + """ Get a :py:class:`MapRecord` with record, ready to be + converted using the current Mapper. + + :param record: record to transform + :param parent: optional parent record, for items + + """ + return MapRecord(self, record, parent=parent) + + def _apply(self, map_record, options=None): + """ Apply the mappings on a :py:class:`MapRecord` + + :param map_record: source record to convert + :type map_record: :py:class:`MapRecord` + + """ + if options is None: + options = {} + with self._mapping_options(options): + return self._apply_with_options(map_record) + + def _apply_with_options(self, map_record): + """ Apply the mappings on a :py:class:`MapRecord` with + contextual options (the ``options`` given in + :py:meth:`MapRecord.values()` are accessible in + ``self.options``) + + :param map_record: source record to convert + :type map_record: :py:class:`MapRecord` + + """ + assert self.options is not None, ( + "options should be defined with '_mapping_options'") + _logger.debug('converting record %s to model %s', + map_record.source, self.model) + + fields = self.options.fields + for_create = self.options.for_create + result = {} + for from_attr, to_attr in self.direct: + if isinstance(from_attr, collections.Callable): + attr_name = self._direct_source_field_name(from_attr) + else: + attr_name = from_attr + + if (not fields or attr_name in fields): + value = self._map_direct(map_record.source, + from_attr, + to_attr) + result[to_attr] = value + + for meth, definition in self.map_methods: + mapping_changed_by = definition.changed_by + if (not fields or not mapping_changed_by or + mapping_changed_by.intersection(fields)): + if definition.only_create and not for_create: + continue + values = meth(map_record.source) + if not values: + continue + if not isinstance(values, dict): + raise ValueError('%s: invalid return value for the ' + 'mapping method %s' % (values, meth)) + result.update(values) + + for from_attr, to_attr, model_name in self.children: + if (not fields or from_attr in fields): + result[to_attr] = self._map_child(map_record, from_attr, + to_attr, model_name) + + return self.finalize(map_record, result) + + def finalize(self, map_record, values): + """ Called at the end of the mapping. + + Can be used to modify the values generated by all the mappings before + returning them. + + :param map_record: source map_record + :type map_record: :py:class:`MapRecord` + :param values: mapped values + :returns: mapped values + :rtype: dict + """ + return values + + +class ImportMapper(AbstractComponent): + """ :py:class:`Mapper` for imports. + + Transform a record from a backend to an Odoo record + + """ + + _name = 'base.import.mapper' + _inherit = 'base.mapper' + _usage = 'import.mapper' + + _map_child_usage = 'import.map.child' + _map_child_fallback = 'base.map.child.import' + + def _map_direct(self, record, from_attr, to_attr): + """ Apply the ``direct`` mappings. + + :param record: record to convert from a source to a target + :param from_attr: name of the source attribute or a callable + :type from_attr: callable | str + :param to_attr: name of the target attribute + :type to_attr: str + """ + if isinstance(from_attr, collections.Callable): + return from_attr(self, record, to_attr) + + value = record.get(from_attr) + if not value: + return False + + # Backward compatibility: when a field is a relation, and a modifier is + # not used, we assume that the relation model is a binding. + # Use an explicit modifier external_to_m2o in the 'direct' mappings to + # change that. + field = self.model._fields[to_attr] + if field.type == 'many2one': + mapping_func = external_to_m2o(from_attr) + value = mapping_func(self, record, to_attr) + return value + + +class ExportMapper(AbstractComponent): + """ :py:class:`Mapper` for exports. + + Transform a record from Odoo to a backend record + + """ + + _name = 'base.export.mapper' + _inherit = 'base.mapper' + _usage = 'export.mapper' + + _map_child_usage = 'export.map.child' + _map_child_fallback = 'base.map.child.export' + + def _map_direct(self, record, from_attr, to_attr): + """ Apply the ``direct`` mappings. + + :param record: record to convert from a source to a target + :param from_attr: name of the source attribute or a callable + :type from_attr: callable | str + :param to_attr: name of the target attribute + :type to_attr: str + """ + if isinstance(from_attr, collections.Callable): + return from_attr(self, record, to_attr) + + value = record[from_attr] + if not value: + return False + + # Backward compatibility: when a field is a relation, and a modifier is + # not used, we assume that the relation model is a binding. + # Use an explicit modifier m2o_to_external in the 'direct' mappings to + # change that. + field = self.model._fields[from_attr] + if field.type == 'many2one': + mapping_func = m2o_to_external(from_attr) + value = mapping_func(self, record, to_attr) + return value + + +class MapRecord(object): + """ A record prepared to be converted using a :py:class:`Mapper`. + + MapRecord instances are prepared by :py:meth:`Mapper.map_record`. + + Usage:: + + >>> map_record = mapper.map_record(record) + >>> output_values = map_record.values() + + See :py:meth:`values` for more information on the available arguments. + + """ + + def __init__(self, mapper, source, parent=None): + self._source = source + self._mapper = mapper + self._parent = parent + self._forced_values = {} + + @property + def source(self): + """ Source record to be converted """ + return self._source + + @property + def parent(self): + """ Parent record if the current record is an item """ + return self._parent + + def values(self, for_create=None, fields=None, **kwargs): + """ Build and returns the mapped values according to the options. + + Usage:: + + >>> map_record = mapper.map_record(record) + >>> output_values = map_record.values() + + Creation of records + When using the option ``for_create``, only the mappings decorated + with ``@only_create`` will be mapped. + + :: + + >>> output_values = map_record.values(for_create=True) + + Filter on fields + When using the ``fields`` argument, the mappings will be + filtered using either the source key in ``direct`` arguments, + either the ``changed_by`` arguments for the mapping methods. + + :: + + >>> output_values = map_record.values( + fields=['name', 'street'] + ) + + Custom options + Arbitrary key and values can be defined in the ``kwargs`` + arguments. They can later be used in the mapping methods + using ``self.options``. + + :: + + >>> output_values = map_record.values(tax_include=True) + + :param for_create: specify if only the mappings for creation + (``@only_create``) should be mapped. + :type for_create: boolean + :param fields: filter on fields + :type fields: list + :param ``**kwargs``: custom options, they can later be used in the + mapping methods + + """ + options = MapOptions(for_create=for_create, fields=fields, **kwargs) + values = self._mapper._apply(self, options=options) + values.update(self._forced_values) + return values + + def update(self, *args, **kwargs): + """ Force values to be applied after a mapping. + + Usage:: + + >>> map_record = mapper.map_record(record) + >>> map_record.update(a=1) + >>> output_values = map_record.values() + # output_values will at least contain {'a': 1} + + The values assigned with ``update()`` are in any case applied, + they have a greater priority than the mapping values. + + """ + self._forced_values.update(*args, **kwargs) + + +class MapOptions(dict): + """ Container for the options of mappings. + + Options can be accessed using attributes of the instance. When an + option is accessed and does not exist, it returns None. + + """ + + def __getitem__(self, key): + try: + return super(MapOptions, self).__getitem__(key) + except KeyError: + return None + + def __getattr__(self, key): + return self[key] + + def __setattr__(self, key, value): + self[key] = value diff --git a/ext/3rd-party-addons/connector/components/synchronizer.py b/ext/3rd-party-addons/connector/components/synchronizer.py new file mode 100644 index 00000000..7c00fc87 --- /dev/null +++ b/ext/3rd-party-addons/connector/components/synchronizer.py @@ -0,0 +1,112 @@ +# -*- coding: utf-8 -*- +# Copyright 2013-2017 Camptocamp SA +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html) + +""" + +Synchronizer +============ + +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. + +""" + +from odoo.addons.component.core import AbstractComponent + + +class Synchronizer(AbstractComponent): + """ Base class for synchronizers """ + + _name = 'base.synchronizer' + _inherit = 'base.connector' + + _base_mapper_usage = 'mapper' + _base_backend_adapter_usage = 'backend.adapter' + + def __init__(self, work_context): + super(Synchronizer, self).__init__(work_context) + self._backend_adapter = None + self._binder = None + self._mapper = None + + def run(self): + """ Run the synchronization """ + raise NotImplementedError + + @property + def mapper(self): + """ Return an instance of ``Mapper`` for the synchronization. + + The instanciation is delayed because some synchronisations do + not need such an unit and the unit may not exist. + + It looks for a Component with ``_usage`` being equal to + ``_base_mapper_usage``. + + :rtype: :py:class:`odoo.addons.component.core.Component` + """ + if self._mapper is None: + self._mapper = self.component(usage=self._base_mapper_usage) + return self._mapper + + @property + def binder(self): + """ Return an instance of ``Binder`` for the synchronization. + + The instanciation is delayed because some synchronisations do + not need such an unit and the unit may not exist. + + :rtype: :py:class:`odoo.addons.component.core.Component` + """ + if self._binder is None: + self._binder = self.binder_for() + return self._binder + + @property + def backend_adapter(self): + """ Return an instance of ``BackendAdapter`` for the + synchronization. + + The instanciation is delayed because some synchronisations do + not need such an unit and the unit may not exist. + + It looks for a Component with ``_usage`` being equal to + ``_base_backend_adapter_usage``. + + :rtype: :py:class:`odoo.addons.component.core.Component` + """ + if self._backend_adapter is None: + self._backend_adapter = self.component( + usage=self._base_backend_adapter_usage + ) + return self._backend_adapter + + +class Exporter(AbstractComponent): + """ Synchronizer for exporting data from Odoo to a backend """ + + _name = 'base.exporter' + _inherit = 'base.synchronizer' + _usage = 'exporter' + _base_mapper_usage = 'export.mapper' + + +class Importer(AbstractComponent): + """ Synchronizer for importing data from a backend to Odoo """ + + _name = 'base.importer' + _inherit = 'base.synchronizer' + _usage = 'importer' + _base_mapper_usage = 'import.mapper' + + +class Deleter(AbstractComponent): + """ Synchronizer for deleting a record on the backend """ + + _name = 'base.deleter' + _inherit = 'base.synchronizer' + _usage = 'deleter' diff --git a/ext/3rd-party-addons/connector/database.py b/ext/3rd-party-addons/connector/database.py new file mode 100644 index 00000000..a3297326 --- /dev/null +++ b/ext/3rd-party-addons/connector/database.py @@ -0,0 +1,79 @@ +# -*- coding: utf-8 -*- +# Copyright 2013-2017 Camptocamp SA +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html) + +import hashlib +import logging +import struct + +_logger = logging.getLogger(__name__) + + +def pg_try_advisory_lock(env, lock): + """ Try to acquire a Postgres transactional advisory lock. + + The function tries to acquire a lock, returns a boolean indicating + if it could be obtained or not. An acquired lock is released at the + end of the transaction. + + A typical use is to acquire a lock at the beginning of an importer + to prevent 2 jobs to do the same import at the same time. Since the + record doesn't exist yet, we can't put a lock on a record, so we put + an advisory lock. + + Example: + - Job 1 imports Partner A + - Job 2 imports Partner B + - Partner A has a category X which happens not to exist yet + - Partner B has a category X which happens not to exist yet + - Job 1 import category X as a dependency + - Job 2 import category X as a dependency + + Since both jobs are executed concurrently, they both create a record + for category X so we have duplicated records. With this lock: + + - Job 1 imports Partner A, it acquires a lock for this partner + - Job 2 imports Partner B, it acquires a lock for this partner + - Partner A has a category X which happens not to exist yet + - Partner B has a category X which happens not to exist yet + - Job 1 import category X as a dependency, it acquires a lock for + this category + - Job 2 import category X as a dependency, try to acquire a lock + but can't, Job 2 is retried later, and when it is retried, it + sees the category X created by Job 1. + + The lock is acquired until the end of the transaction. + + Usage example: + + :: + + lock_name = 'import_record({}, {}, {}, {})'.format( + self.backend_record._name, + self.backend_record.id, + self.model._name, + self.external_id, + ) + if pg_try_advisory_lock(lock_name): + # do sync + else: + raise RetryableJobError('Could not acquire advisory lock', + seconds=2, + ignore_retry=True) + + :param env: the Odoo Environment + :param lock: The lock name. Can be anything convertible to a + string. It needs to represents what should not be synchronized + concurrently so usually the string will contain at least: the + action, the backend type, the backend id, the model name, the + external id + :return True/False whether lock was acquired. + """ + hasher = hashlib.sha1(str(lock).encode()) + # pg_lock accepts an int8 so we build an hash composed with + # contextual information and we throw away some bits + int_lock = struct.unpack('q', hasher.digest()[:8]) + + env.cr.execute('SELECT pg_try_advisory_xact_lock(%s);', (int_lock,)) + acquired = env.cr.fetchone()[0] + return acquired diff --git a/ext/3rd-party-addons/connector/doc/Makefile b/ext/3rd-party-addons/connector/doc/Makefile new file mode 100644 index 00000000..58156b0c --- /dev/null +++ b/ext/3rd-party-addons/connector/doc/Makefile @@ -0,0 +1,153 @@ +# Makefile for Sphinx documentation +# + +# You can set these variables from the command line. +SPHINXOPTS = +SPHINXBUILD = sphinx-build +PAPER = +BUILDDIR = _build + +# Internal variables. +PAPEROPT_a4 = -D latex_paper_size=a4 +PAPEROPT_letter = -D latex_paper_size=letter +ALLSPHINXOPTS = -d $(BUILDDIR)/doctrees $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) . +# the i18n builder cannot share the environment and doctrees with the others +I18NSPHINXOPTS = $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) . + +.PHONY: help clean html dirhtml singlehtml pickle json htmlhelp qthelp devhelp epub latex latexpdf text man changes linkcheck doctest gettext + +help: + @echo "Please use \`make ' where is one of" + @echo " html to make standalone HTML files" + @echo " dirhtml to make HTML files named index.html in directories" + @echo " singlehtml to make a single large HTML file" + @echo " pickle to make pickle files" + @echo " json to make JSON files" + @echo " htmlhelp to make HTML files and a HTML help project" + @echo " qthelp to make HTML files and a qthelp project" + @echo " devhelp to make HTML files and a Devhelp project" + @echo " epub to make an epub" + @echo " latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter" + @echo " latexpdf to make LaTeX files and run them through pdflatex" + @echo " text to make text files" + @echo " man to make manual pages" + @echo " texinfo to make Texinfo files" + @echo " info to make Texinfo files and run them through makeinfo" + @echo " gettext to make PO message catalogs" + @echo " changes to make an overview of all changed/added/deprecated items" + @echo " linkcheck to check all external links for integrity" + @echo " doctest to run all doctests embedded in the documentation (if enabled)" + +clean: + -rm -rf $(BUILDDIR)/* + +html: + $(SPHINXBUILD) -b html $(ALLSPHINXOPTS) $(BUILDDIR)/html + @echo + @echo "Build finished. The HTML pages are in $(BUILDDIR)/html." + +dirhtml: + $(SPHINXBUILD) -b dirhtml $(ALLSPHINXOPTS) $(BUILDDIR)/dirhtml + @echo + @echo "Build finished. The HTML pages are in $(BUILDDIR)/dirhtml." + +singlehtml: + $(SPHINXBUILD) -b singlehtml $(ALLSPHINXOPTS) $(BUILDDIR)/singlehtml + @echo + @echo "Build finished. The HTML page is in $(BUILDDIR)/singlehtml." + +pickle: + $(SPHINXBUILD) -b pickle $(ALLSPHINXOPTS) $(BUILDDIR)/pickle + @echo + @echo "Build finished; now you can process the pickle files." + +json: + $(SPHINXBUILD) -b json $(ALLSPHINXOPTS) $(BUILDDIR)/json + @echo + @echo "Build finished; now you can process the JSON files." + +htmlhelp: + $(SPHINXBUILD) -b htmlhelp $(ALLSPHINXOPTS) $(BUILDDIR)/htmlhelp + @echo + @echo "Build finished; now you can run HTML Help Workshop with the" \ + ".hhp project file in $(BUILDDIR)/htmlhelp." + +qthelp: + $(SPHINXBUILD) -b qthelp $(ALLSPHINXOPTS) $(BUILDDIR)/qthelp + @echo + @echo "Build finished; now you can run "qcollectiongenerator" with the" \ + ".qhcp project file in $(BUILDDIR)/qthelp, like this:" + @echo "# qcollectiongenerator $(BUILDDIR)/qthelp/Connectors.qhcp" + @echo "To view the help file:" + @echo "# assistant -collectionFile $(BUILDDIR)/qthelp/Connectors.qhc" + +devhelp: + $(SPHINXBUILD) -b devhelp $(ALLSPHINXOPTS) $(BUILDDIR)/devhelp + @echo + @echo "Build finished." + @echo "To view the help file:" + @echo "# mkdir -p $$HOME/.local/share/devhelp/Connectors" + @echo "# ln -s $(BUILDDIR)/devhelp $$HOME/.local/share/devhelp/Connectors" + @echo "# devhelp" + +epub: + $(SPHINXBUILD) -b epub $(ALLSPHINXOPTS) $(BUILDDIR)/epub + @echo + @echo "Build finished. The epub file is in $(BUILDDIR)/epub." + +latex: + $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex + @echo + @echo "Build finished; the LaTeX files are in $(BUILDDIR)/latex." + @echo "Run \`make' in that directory to run these through (pdf)latex" \ + "(use \`make latexpdf' here to do that automatically)." + +latexpdf: + $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex + @echo "Running LaTeX files through pdflatex..." + $(MAKE) -C $(BUILDDIR)/latex all-pdf + @echo "pdflatex finished; the PDF files are in $(BUILDDIR)/latex." + +text: + $(SPHINXBUILD) -b text $(ALLSPHINXOPTS) $(BUILDDIR)/text + @echo + @echo "Build finished. The text files are in $(BUILDDIR)/text." + +man: + $(SPHINXBUILD) -b man $(ALLSPHINXOPTS) $(BUILDDIR)/man + @echo + @echo "Build finished. The manual pages are in $(BUILDDIR)/man." + +texinfo: + $(SPHINXBUILD) -b texinfo $(ALLSPHINXOPTS) $(BUILDDIR)/texinfo + @echo + @echo "Build finished. The Texinfo files are in $(BUILDDIR)/texinfo." + @echo "Run \`make' in that directory to run these through makeinfo" \ + "(use \`make info' here to do that automatically)." + +info: + $(SPHINXBUILD) -b texinfo $(ALLSPHINXOPTS) $(BUILDDIR)/texinfo + @echo "Running Texinfo files through makeinfo..." + make -C $(BUILDDIR)/texinfo info + @echo "makeinfo finished; the Info files are in $(BUILDDIR)/texinfo." + +gettext: + $(SPHINXBUILD) -b gettext $(I18NSPHINXOPTS) $(BUILDDIR)/locale + @echo + @echo "Build finished. The message catalogs are in $(BUILDDIR)/locale." + +changes: + $(SPHINXBUILD) -b changes $(ALLSPHINXOPTS) $(BUILDDIR)/changes + @echo + @echo "The overview file is in $(BUILDDIR)/changes." + +linkcheck: + $(SPHINXBUILD) -b linkcheck $(ALLSPHINXOPTS) $(BUILDDIR)/linkcheck + @echo + @echo "Link check complete; look for any errors in the above output " \ + "or in $(BUILDDIR)/linkcheck/output.txt." + +doctest: + $(SPHINXBUILD) -b doctest $(ALLSPHINXOPTS) $(BUILDDIR)/doctest + @echo "Testing of doctests in the sources finished, look at the " \ + "results in $(BUILDDIR)/doctest/output.txt." diff --git a/ext/3rd-party-addons/connector/doc/_static/09_datamodel.png b/ext/3rd-party-addons/connector/doc/_static/09_datamodel.png new file mode 100644 index 00000000..4bf0bee3 Binary files /dev/null and b/ext/3rd-party-addons/connector/doc/_static/09_datamodel.png differ diff --git a/ext/3rd-party-addons/connector/doc/_static/connector_style.css b/ext/3rd-party-addons/connector/doc/_static/connector_style.css new file mode 100644 index 00000000..cde10417 --- /dev/null +++ b/ext/3rd-party-addons/connector/doc/_static/connector_style.css @@ -0,0 +1,4 @@ +.navbar span.navbar-text { + visibility: hidden; +} + diff --git a/ext/3rd-party-addons/connector/doc/_static/img/LogicSupply_Orange_260x80_transparent.png b/ext/3rd-party-addons/connector/doc/_static/img/LogicSupply_Orange_260x80_transparent.png new file mode 100644 index 00000000..046f4ee8 Binary files /dev/null and b/ext/3rd-party-addons/connector/doc/_static/img/LogicSupply_Orange_260x80_transparent.png differ diff --git a/ext/3rd-party-addons/connector/doc/_static/img/akretion_logo.png b/ext/3rd-party-addons/connector/doc/_static/img/akretion_logo.png new file mode 100644 index 00000000..6b298965 Binary files /dev/null and b/ext/3rd-party-addons/connector/doc/_static/img/akretion_logo.png differ diff --git a/ext/3rd-party-addons/connector/doc/_static/img/c2c_square_baseline_192.jpg b/ext/3rd-party-addons/connector/doc/_static/img/c2c_square_baseline_192.jpg new file mode 100644 index 00000000..1b3d6b62 Binary files /dev/null and b/ext/3rd-party-addons/connector/doc/_static/img/c2c_square_baseline_192.jpg differ diff --git a/ext/3rd-party-addons/connector/doc/_static/img/logo-debonix.jpg b/ext/3rd-party-addons/connector/doc/_static/img/logo-debonix.jpg new file mode 100644 index 00000000..9986555d Binary files /dev/null and b/ext/3rd-party-addons/connector/doc/_static/img/logo-debonix.jpg differ diff --git a/ext/3rd-party-addons/connector/doc/_static/img/magentoerpconnect.png b/ext/3rd-party-addons/connector/doc/_static/img/magentoerpconnect.png new file mode 100644 index 00000000..8480511a Binary files /dev/null and b/ext/3rd-party-addons/connector/doc/_static/img/magentoerpconnect.png differ diff --git a/ext/3rd-party-addons/connector/doc/_static/img/magentoerpconnect150.png b/ext/3rd-party-addons/connector/doc/_static/img/magentoerpconnect150.png new file mode 100644 index 00000000..3f59d00b Binary files /dev/null and b/ext/3rd-party-addons/connector/doc/_static/img/magentoerpconnect150.png differ diff --git a/ext/3rd-party-addons/connector/doc/_static/img/prestashoperpconnect.png b/ext/3rd-party-addons/connector/doc/_static/img/prestashoperpconnect.png new file mode 100644 index 00000000..288ea769 Binary files /dev/null and b/ext/3rd-party-addons/connector/doc/_static/img/prestashoperpconnect.png differ diff --git a/ext/3rd-party-addons/connector/doc/_static/img/prestashoperpconnect150.png b/ext/3rd-party-addons/connector/doc/_static/img/prestashoperpconnect150.png new file mode 100644 index 00000000..30f407ed Binary files /dev/null and b/ext/3rd-party-addons/connector/doc/_static/img/prestashoperpconnect150.png differ diff --git a/ext/3rd-party-addons/connector/doc/_templates/layout.html b/ext/3rd-party-addons/connector/doc/_templates/layout.html new file mode 100644 index 00000000..466ea49d --- /dev/null +++ b/ext/3rd-party-addons/connector/doc/_templates/layout.html @@ -0,0 +1,14 @@ +{% extends "!layout.html" %} + +{%- block extrahead %} +{{ super() }} + +{% endblock %} diff --git a/ext/3rd-party-addons/connector/doc/_templates/navbar.html b/ext/3rd-party-addons/connector/doc/_templates/navbar.html new file mode 100644 index 00000000..2fba04f1 --- /dev/null +++ b/ext/3rd-party-addons/connector/doc/_templates/navbar.html @@ -0,0 +1,31 @@ +{% extends "!navbar.html" %} + +{% block navbartoc %} + + + {{ super() }} +{% endblock %} diff --git a/ext/3rd-party-addons/connector/doc/_themes/.gitignore b/ext/3rd-party-addons/connector/doc/_themes/.gitignore new file mode 100644 index 00000000..66b6e4c2 --- /dev/null +++ b/ext/3rd-party-addons/connector/doc/_themes/.gitignore @@ -0,0 +1,3 @@ +*.pyc +*.pyo +.DS_Store diff --git a/ext/3rd-party-addons/connector/doc/api/api_backend.rst b/ext/3rd-party-addons/connector/doc/api/api_backend.rst new file mode 100644 index 00000000..af656a0a --- /dev/null +++ b/ext/3rd-party-addons/connector/doc/api/api_backend.rst @@ -0,0 +1,26 @@ +###### +Models +###### + +.. _api-backend-model: + +************* +Backend Model +************* + + +.. autoclass:: connector.backend_model.ConnectorBackend + :members: + :undoc-members: + :show-inheritance: + +.. _api-binding-model: + +************* +Binding Model +************* + +.. autoclass:: connector.backend_model.ExternalBinding + :members: + :undoc-members: + :show-inheritance: diff --git a/ext/3rd-party-addons/connector/doc/api/api_channels.rst b/ext/3rd-party-addons/connector/doc/api/api_channels.rst new file mode 100644 index 00000000..e7e9254d --- /dev/null +++ b/ext/3rd-party-addons/connector/doc/api/api_channels.rst @@ -0,0 +1,14 @@ +######## +Channels +######## + +This is the API documentation for the job channels and the +scheduling mechanisms of the job runner. + +These classes are not intended for use by module developers. + +.. automodule:: odoo.addons.queue_job.jobrunner.channels + :members: + :undoc-members: + :show-inheritance: + diff --git a/ext/3rd-party-addons/connector/doc/api/api_components.rst b/ext/3rd-party-addons/connector/doc/api/api_components.rst new file mode 100644 index 00000000..e8be1aa0 --- /dev/null +++ b/ext/3rd-party-addons/connector/doc/api/api_components.rst @@ -0,0 +1,91 @@ +.. _api-component: + +########## +Components +########## + +Components are the blocks allowing to build a flexible and +well decoupled code. They are based on the ``component`` addon, which +can as well be used separately. + + +*************** +Core Components +*************** + +.. automodule:: connector.components.core + :members: + :undoc-members: + :show-inheritance: + :private-members: + + +******************** +Connector Components +******************** + +.. automodule:: connector.components.binder + :members: + :undoc-members: + :show-inheritance: + :private-members: + +.. automodule:: connector.components.mapper + :members: + :undoc-members: + :show-inheritance: + :private-members: + +.. automodule:: connector.components.backend_adapter + :members: + :undoc-members: + :show-inheritance: + :private-members: + +.. automodule:: connector.components.synchronizer + :members: + :undoc-members: + :show-inheritance: + :private-members: + +.. automodule:: connector.components.listener + :members: + :undoc-members: + :show-inheritance: + :private-members: + + +*************************** +Components Collection Model +*************************** + +.. automodule:: odoo.addons.component.models.collection + :members: + :undoc-members: + :show-inheritance: + + +********************* +Components Exceptions +********************* + +.. automodule:: odoo.addons.component.exception + :members: + :undoc-members: + :show-inheritance: + +******************** +Components Internals +******************** + +Low-level APIs of the Components. + +.. automodule:: odoo.addons.component.core + :members: + :undoc-members: + :show-inheritance: + +.. automodule:: odoo.addons.component.builder + :members: + :undoc-members: + :show-inheritance: diff --git a/ext/3rd-party-addons/connector/doc/api/api_event.rst b/ext/3rd-party-addons/connector/doc/api/api_event.rst new file mode 100644 index 00000000..0ae53fb2 --- /dev/null +++ b/ext/3rd-party-addons/connector/doc/api/api_event.rst @@ -0,0 +1,37 @@ +.. _api-event: + +###### +Events +###### + +Events is an implementation of an Observer pattern for Odoo. + + +********** +Components +********** + +.. automodule:: odoo.addons.component_event.components.event + :members: + :undoc-members: + :show-inheritance: + + +********************** +Odoo Models Extensions +********************** + +.. automodule:: odoo.addons.component_event.models.base + :members: + :undoc-members: + :show-inheritance: + + +********* +Internals +********* + +.. automodule:: odoo.addons.component_event.core + :members: + :undoc-members: + :show-inheritance: diff --git a/ext/3rd-party-addons/connector/doc/api/api_exception.rst b/ext/3rd-party-addons/connector/doc/api/api_exception.rst new file mode 100644 index 00000000..bdc0e56b --- /dev/null +++ b/ext/3rd-party-addons/connector/doc/api/api_exception.rst @@ -0,0 +1,8 @@ +Exceptions +========== + +.. automodule:: connector.exception + :members: + :undoc-members: + :show-inheritance: + diff --git a/ext/3rd-party-addons/connector/doc/api/api_queue.rst b/ext/3rd-party-addons/connector/doc/api/api_queue.rst new file mode 100644 index 00000000..9b0dc9f9 --- /dev/null +++ b/ext/3rd-party-addons/connector/doc/api/api_queue.rst @@ -0,0 +1,28 @@ +.. _api-queue: + +##### +Queue +##### + +*** +Job +*** + +.. automodule:: odoo.addons.queue_job.job + :members: + :undoc-members: + :show-inheritance: + +****** +Models +****** + +.. automodule:: odoo.addons.queue_job.models.base + :members: + :undoc-members: + :show-inheritance: + +.. automodule:: odoo.addons.queue_job.models.queue_job + :members: + :undoc-members: + :show-inheritance: diff --git a/ext/3rd-party-addons/connector/doc/bazaar b/ext/3rd-party-addons/connector/doc/bazaar new file mode 100644 index 00000000..be7f109f --- /dev/null +++ b/ext/3rd-party-addons/connector/doc/bazaar @@ -0,0 +1,27 @@ +# This viminfo file was generated by Vim 7.4. +# You may edit it if you're careful! + +# Value of 'encoding' when this file was written +*encoding=utf-8 + + +# hlsearch on (H) or off (h): +~h +# Command Line History (newest to oldest): +:q! + +# Search String History (newest to oldest): + +# Expression History (newest to oldest): + +# Input Line History (newest to oldest): + +# Input Line History (newest to oldest): + +# Registers: + +# File marks: + +# Jumplist (newest first): + +# History of marks within files (newest to oldest): diff --git a/ext/3rd-party-addons/connector/doc/conf.py b/ext/3rd-party-addons/connector/doc/conf.py new file mode 100644 index 00000000..f7b22c60 --- /dev/null +++ b/ext/3rd-party-addons/connector/doc/conf.py @@ -0,0 +1,381 @@ +# -*- coding: utf-8 -*- +# +# Connectors documentation build configuration file, created by +# sphinx-quickstart on Mon Feb 4 11:35:44 2013. +# +# This file is execfile()d with the current directory set to its containing dir. +# +# Note that not all possible configuration values are present in this +# autogenerated file. +# +# All configuration values have a default; values that are commented out +# serve to show the default. + +# flake8: noqa + +import sys +import os +import sphinx_bootstrap_theme + +# If extensions (or modules to document with autodoc) are in another directory, +# add these directories to sys.path here. If the directory is relative to the +# documentation root, use os.path.abspath to make it absolute, like shown here. +#sys.path.insert(0, os.path.abspath('.')) +sys.path.append(os.path.abspath('_themes')) + +MANIFEST_FILES = [ + '__manifest__.py', + '__odoo__.py', + '__openerp__.py', +] + + +def is_module(path): + """return False if the path doesn't contain an odoo module, and the full + path to the module manifest otherwise""" + + if not os.path.isdir(path): + return False + files = os.listdir(path) + filtered = [x for x in files if x in (MANIFEST_FILES + ['__init__.py'])] + if len(filtered) == 2 and '__init__.py' in filtered: + return os.path.join( + path, next(x for x in filtered if x != '__init__.py')) + else: + return False + + +def is_installable_module(path): + """return False if the path doesn't contain an installable odoo module, + and the full path to the module manifest otherwise""" + manifest_path = is_module(path) + if manifest_path: + manifest = ast.literal_eval(open(manifest_path).read()) + if manifest.get('installable', True): + return manifest_path + return False + + +if os.environ.get('TRAVIS_BUILD_DIR') and os.environ.get('VERSION'): + # build from travis + repos_home = os.environ['HOME'] + deps_path = os.path.join(repos_home, 'dependencies') + odoo_folder = 'odoo-11.0' + odoo_root = os.path.join(repos_home, odoo_folder) + build_path = os.environ['TRAVIS_BUILD_DIR'] +else: + # build from dev + odoo_root = os.path.abspath('../../../../src') + deps_path = os.path.abspath('../../..') + build_path = os.path.abspath('../..') + +addons_paths = [] + +def add_path(*paths): + addons_paths.append( + os.path.join(*paths) + ) + + +add_path(odoo_root, 'odoo', 'addons') +add_path(odoo_root, 'addons') +add_path(build_path) + +deps_repos = [repo for repo in os.listdir(deps_path) + if os.path.isdir(os.path.join(deps_path, repo)) and + not repo.startswith('.')] + +for repo in deps_repos: + add_path(deps_path, repo) + +addons = [x for x in os.listdir(build_path) + if not x.startswith(('.', '__')) and + is_installable_module(x)] + + +# sphinxodoo.ext.autodoc variables +sphinxodoo_root_path = odoo_root +sphinxodoo_addons = addons +sphinxodoo_addons_path = addons_paths +sys.path.append(build_path) + + +# -- General configuration ----------------------------------------------- + +# If your documentation needs a minimal Sphinx version, state it here. +#needs_sphinx = '1.0' + +# Add any Sphinx extension module names here, as strings. They can be extensions +# coming with Sphinx (named 'sphinx.ext.*') or your custom ones. +extensions = ['sphinx.ext.autodoc', 'sphinx.ext.intersphinx', + 'sphinx.ext.todo', 'sphinx.ext.viewcode', + 'sphinxodoo.ext.autodoc'] + +todo_include_todos = False + +# Add any paths that contain templates here, relative to this directory. +templates_path = ['_templates'] + +# The suffix of source filenames. +source_suffix = '.rst' + +# The encoding of source files. +#source_encoding = 'utf-8-sig' + +# The master toctree document. +master_doc = 'index' + +# autodoc options +autodoc_member_order = 'bysource' + +# General information about the project. +project = 'Connector' +copyright = '2013, Camptocamp SA' + +# The version info for the project you're documenting, acts as replacement for +# |version| and |release|, also used in various other places throughout the +# built documents. +# +# The short X.Y version. +version = '' +# The full version, including alpha/beta/rc tags. +release = '' + +# The language for content autogenerated by Sphinx. Refer to documentation +# for a list of supported languages. +language = 'en' +locale_dirs = ['locale'] +gettext_compact = True + +# There are two options for replacing |today|: either, you set today to some +# non-false value, then it is used: +#today = '' +# Else, today_fmt is used as the format for a strftime call. +#today_fmt = '%B %d, %Y' + +# List of patterns, relative to source directory, that match files and +# directories to ignore when looking for source files. +exclude_patterns = ['_build'] + +# The reST default role (used for this markup: `text`) to use for all documents. +#default_role = None + +# If true, '()' will be appended to :func: etc. cross-reference text. +#add_function_parentheses = True + +# If true, the current module name will be prepended to all description +# unit titles (such as .. function::). +#add_module_names = True + +# If true, sectionauthor and moduleauthor directives will be shown in the +# output. They are ignored by default. +#show_authors = False + +# The name of the Pygments (syntax highlighting) style to use. +pygments_style = 'sphinx' + +# A list of ignored prefixes for module index sorting. +#modindex_common_prefix = [] + + +# -- Options for HTML output --------------------------------------------- + +# The theme to use for HTML and HTML Help pages. See the documentation for +# a list of builtin themes. +html_theme = 'bootstrap' + +# Theme options are theme-specific and customize the look and feel of a theme +# further. For a list of options available for each theme, see the +# documentation. +html_theme_options = { + # Navigation bar title. (Default: ``project`` value) + 'navbar_title': "Odoo Connector", + + # Tab name for entire site. (Default: "Site") + 'navbar_site_name': "Site", + + # Global TOC depth for "site" navbar tab. (Default: 1) + # Switching to -1 shows all levels. + 'globaltoc_depth': 2, + + # Include hidden TOCs in Site navbar? + # + # Note: If this is "false", you cannot have mixed ``:hidden:`` and + # non-hidden ``toctree`` directives in the same page, or else the build + # will break. + # + # Values: "true" (default) or "false" + 'globaltoc_includehidden': "true", + + # HTML navbar class (Default: "navbar") to attach to
element. + # For black navbar, do "navbar navbar-inverse" + 'navbar_class': "navbar", + + # Fix navigation bar to top of page? + # Values: "true" (default) or "false" + 'navbar_fixed_top': "true", + + # Location of link to source. + # Options are "nav" (default), "footer" or anything else to exclude. + 'source_link_position': "footer", + + # Bootswatch (http://bootswatch.com/) theme. + # + # Options are nothing with "" (default) or the name of a valid theme + # such as "amelia" or "cosmo". + # + # Note that this is served off CDN, so won't be available offline. + 'bootswatch_theme': "united", +} + +# Add any paths that contain custom themes here, relative to this directory. +html_theme_path = sphinx_bootstrap_theme.get_html_theme_path() + +# The name for this set of Sphinx documents. If None, it defaults to +# " v documentation". +#html_title = None + +# A shorter title for the navigation bar. Default is the same as html_title. +#html_short_title = None + +# The name of an image file (relative to this directory) to place at the top +# of the sidebar. +#html_logo = None + +# The name of an image file (within the static path) to use as favicon of the +# docs. This file should be a Windows icon file (.ico) being 16x16 or 32x32 +# pixels large. +#html_favicon = None + +# Add any paths that contain custom static files (such as style sheets) here, +# relative to this directory. They are copied after the builtin static files, +# so a file named "default.css" will overwrite the builtin "default.css". +html_static_path = ['_static'] + +# If not '', a 'Last updated on:' timestamp is inserted at every page bottom, +# using the given strftime format. +#html_last_updated_fmt = '%b %d, %Y' + +# If true, SmartyPants will be used to convert quotes and dashes to +# typographically correct entities. +#html_use_smartypants = True + +# Custom sidebar templates, maps document names to template names. +#html_sidebars = {} + +# Additional templates that should be rendered to pages, maps page names to +# template names. +#html_additional_pages = {} + +# If false, no module index is generated. +#html_domain_indices = True + +# If false, no index is generated. +#html_use_index = True + +# If true, the index is split into individual pages for each letter. +#html_split_index = False + +# If true, links to the reST sources are added to the pages. +#html_show_sourcelink = True + +# If true, "Created using Sphinx" is shown in the HTML footer. Default is True. +#html_show_sphinx = True + +# If true, "(C) Copyright ..." is shown in the HTML footer. Default is True. +#html_show_copyright = True + +# If true, an OpenSearch description file will be output, and all pages will +# contain a tag referring to it. The value of this option must be the +# base URL from which the finished HTML is served. +#html_use_opensearch = '' + +# This is the file name suffix for HTML files (e.g. ".xhtml"). +#html_file_suffix = None + +# Output file base name for HTML help builder. +htmlhelp_basename = 'connector-doc' + + +# -- Options for LaTeX output -------------------------------------------- + +latex_elements = { + # The paper size ('letterpaper' or 'a4paper'). + #'papersize': 'letterpaper', + + # The font size ('10pt', '11pt' or '12pt'). + #'pointsize': '10pt', + + # Additional stuff for the LaTeX preamble. + #'preamble': '', +} + +# Grouping the document tree into LaTeX files. List of tuples +# (source start file, target name, title, author, documentclass [howto/manual]). +latex_documents = [ + ('index', 'Connector.tex', 'Connector Documentation', + 'Camptocamp SA', 'manual'), +] + +# The name of an image file (relative to this directory) to place at the top of +# the title page. +#latex_logo = None + +# For "manual" documents, if this is true, then toplevel headings are parts, +# not chapters. +#latex_use_parts = False + +# If true, show page references after internal links. +#latex_show_pagerefs = False + +# If true, show URL addresses after external links. +#latex_show_urls = False + +# Documents to append as an appendix to all manuals. +#latex_appendices = [] + +# If false, no module index is generated. +#latex_domain_indices = True + + +# -- Options for manual page output -------------------------------------- + +# One entry per manual page. List of tuples +# (source start file, name, description, authors, manual section). +man_pages = [ + ('index', 'connector', 'Connector Documentation', + ['Camptocamp SA'], 1) +] + +# If true, show URL addresses after external links. +#man_show_urls = False + + +# -- Options for Texinfo output ------------------------------------------ + +# Grouping the document tree into Texinfo files. List of tuples +# (source start file, target name, title, author, +# dir menu entry, description, category) +texinfo_documents = [ + ('index', 'Connector', 'Connector Documentation', + 'Camptocamp SA', 'Connector', 'Framework for Odoo Connectors.', + 'Miscellaneous'), +] + +# Documents to append as an appendix to all manuals. +#texinfo_appendices = [] + +# If false, no module index is generated. +#texinfo_domain_indices = True + +# How to display URL addresses: 'footnote', 'no', or 'inline'. +#texinfo_show_urls = 'footnote' + + +# Example configuration for intersphinx: refer to the Python standard library. +intersphinx_mapping = { + 'http://docs.python.org/': None, + 'odooweb': ('https://www.odoo.com/documentation/10.0/', None), + 'odoodev': ('https://www.odoo.com/documentation/10.0/', None), + 'connectormagento': ('http://www.odoo-magento-connector.com', None), +} diff --git a/ext/3rd-party-addons/connector/doc/guides/bootstrap_connector.rst b/ext/3rd-party-addons/connector/doc/guides/bootstrap_connector.rst new file mode 100644 index 00000000..734de188 --- /dev/null +++ b/ext/3rd-party-addons/connector/doc/guides/bootstrap_connector.rst @@ -0,0 +1,153 @@ +.. _bootstrap-connector: + + +######################## +Boostrapping a connector +######################## + +We'll see the steps to bootstrap a new connector. + +Besides that, you may want to use the existing connectors to have some +real implementation examples: + +* `Odoo Magento Connector`_ +* `Odoo Prestashop Connector`_ + +Be aware that the connector API has changed in Odoo 10.0, so the examples +might be outdated. + +Some boilerplate is necessary, so this document will guide you through +some steps. Please also take a look on the :ref:`naming-convention`. + +For the sake of the example, we'll imagine we have to synchronize +Odoo with a coffee machine. + +************* +Odoo Manifest +************* + +As we want to synchronize Odoo with a coffee machine, we'll name +our connector connector_coffee. + +First, we need to create the Odoo addons itself, editing the +``connector_coffee/__manifest__.py`` manifest. + + +.. code-block:: python + :emphasize-lines: 4,5 + + # -*- coding: utf-8 -*- + {'name': 'Coffee Connector', + 'version': '1.0.0', + 'category': 'Connector', + 'depends': ['connector', + ], + 'author': 'Myself', + 'license': 'AGPL-3', + 'description': """ + Coffee Connector + ================ + + Connect Odoo to my coffee machine. + + Features: + + * Poor a coffee when Odoo is busy for too long + """, + 'data': [], + 'installable': True, + } + +Nothing special but 2 things to note: + +* It depends from ``connector``. ``connector`` itself depends from + ``queue_job``, ``component`` and ``component_event``. ``queue_job`` is in the + `OCA/queue`_ repository. +* The module category should be ``Connector``. + +Of course, we also need to create the ``__init__.py`` file where we will +put the imports of our python modules. + +.. _OCA/queue: https://github.com/OCA/queue + + +************* +Backend Model +************* + +Reference: :ref:`api-backend-model` + +We need to create a Backend representing the external service. Every record we +synchronize will be linked with a record of ``coffee.backend``. This backend +is our *collection* of Components. + +The ``coffee.backend`` model is an ``_inherit`` of ``connector.backend``. In +``connector_coffee/models/coffee_binding.py``:: + + from odoo import api, fields, models + + + class CoffeeBackend(models.Model): + _name = 'coffee.backend' + _description = 'Coffee Backend' + _inherit = 'connector.backend' + + location = fields.Char(string='Location') + username = fields.Char(string='Username') + password = fields.Char(string='Password') + +Notes: + +* We can other fields for the configuration of the connection or the + synchronizations. + +**************** +Abstract Binding +**************** + +Reference: :ref:`api-binding-model` + +In order to share common features between all the bindings (see +:ref:`binding`), create an abstract binding model. + +It can be as follows (in ``connector_coffee/models/coffee_binding.py``):: + + from odoo import models, fields + + + class CoffeeBinding(models.AbstractModel): + _name = 'coffee.binding' + _inherit = 'external.binding' + _description = 'Coffee Binding (abstract)' + + # odoo_id = odoo-side id must be declared in concrete model + backend_id = fields.Many2one( + comodel_name='coffee.backend', + string='Coffee Backend', + required=True, + ondelete='restrict', + ) + coffee_id = fields.Integer(string='ID in the Coffee Machine', + index=True) + +Notes: + +* This model inherit from ``external.binding`` +* Any number of fields or methods can be added + + +********** +Components +********** + +Reference: :ref:`api-component` + +We'll probably need to create synchronizers, mappers, backend adapters, +binders and maybe our own kind of components. + +Their implementation can vary from a project to another. Have a look on the +`Odoo Magento Connector`_ and `Odoo Prestashop Connector`_ projects. + + +.. _`Odoo Magento Connector`: https://github.com/OCA/connector-magento +.. _`Odoo Prestashop Connector`: https://github.com/OCA/connector-prestashop diff --git a/ext/3rd-party-addons/connector/doc/guides/code_overview.rst b/ext/3rd-party-addons/connector/doc/guides/code_overview.rst new file mode 100644 index 00000000..3ecc22e6 --- /dev/null +++ b/ext/3rd-party-addons/connector/doc/guides/code_overview.rst @@ -0,0 +1,188 @@ +.. _code-overview: + +############# +Code Overview +############# + +Some simple code examples. + +*************************** +Trigger and listen an event +*************************** + +.. code-block:: python + + class AccountInvoice(models.Model): + _inherit = 'account.invoice' + + @api.multi + def action_invoice_paid(self): + res = super(AccountInvoice, self).action_invoice_paid() + for record in self: + self._event('on_invoice_paid').notify(record) + return res + + + +.. code-block:: python + + from odoo.addons.component.core import Component + + + class MyEventListener(Component): + _name = 'my.event.listener' + _inherit = 'base.event.listener' + + def on_invoice_paid(self, record): + _logger.info('invoice %s has been paid!', record.name) + +Ref: :ref:`api-event` + + +************************* +Delay an Asynchronous Job +************************* + +.. code-block:: python + + from odoo.addons.queue_job.job import job + + + class AccountInvoice(models.Model): + _inherit = 'account.invoice' + + @job + @api.multi + def export_payment(self): + self.ensure_one() + _logger.info("I'm exporting the payment for %s", self.name) + + @api.multi + def action_invoice_paid(self): + res = super(AccountInvoice, self).action_invoice_paid() + for record in self: + record.with_delay(priority=5).export_payment() + return res + +Ref: :ref:`api-queue` + +******************** +Work with components +******************** + +This is a highly simplified version of a micro-connector, without using +events or jobs, for the sake of the example. + +.. code-block:: python + + from odoo.addons.component.core import AbstractComponent + + + class MagentoBackend(models.Model): + _name = 'magento.backend' + _description = 'Magento Backend' + _inherit = 'connector.backend' + + location = fields.Char(string='Location', required=True) + username = fields.Char(string='Username') + password = fields.Char(string='Password') + + def import_partner(self, external_id): + with self.work_on(model_name='magento.res.partner') as work: + importer = work.component(usage='record.importer') + # returns an instance of PartnerImporter, which has been + # found with:the collection name (magento.backend, the model, + # and the usage). + importer.run(partner_id) + + # the next 2 components are abstract and are used by inheritance + # by the others + class BaseMagentoConnectorComponent(AbstractComponent): + # same inheritance than Odoo models + _name = 'base.magento.connector' + _inherit = 'base.connector' + # subscribe to: + _collection = 'magento.backend' + # the collection will be inherited to the components below, + # because they inherit from this component + + + class GenericAdapter(AbstractComponent): + # same inheritance than Odoo models + _name = 'magento.adapter' + _inherit = ['base.backend.adapter', 'base.magento.connector'] + # usage is used for lookups of components + _usage = 'backend.adapter' + + _magento_model = None + + def _call(self, *args, **kwargs): + location = self.backend_record.location + # use client API + + def read(self, fields=None): + """ Search records according to some criterias + and returns a list of ids + + :rtype: list + """ + return self._call('%s.info' % self._magento_model, fields) + + + # these are the components we need for our synchronization + class PartnerAdapter(Component): + _name = 'magento.partner.adapter' + _inherit = 'magento.adapter' + _apply_on = ['magento.res.partner'] + _magento_model = 'customer' + + + class PartnerMapper(Component): + _name = 'magento.partner.import.mapper' + _inherit = 'magento.import.mapper' # parent component omitted for brevity + _apply_on = ['magento.res.partner'] + _usage = 'import.mapper' + + + class PartnerBinder(Component): + _name = 'magento.partner.binder' + _inherit = 'magento.binder' # parent component omitted for brevity + _apply_on = ['magento.res.partner'] + _usage = 'binder' + + + class PartnerImporter(Component): + _name = 'magento.partner.importer' + _inherit = 'magento.importer' # parent component omitted for brevity + _apply_on = ['magento.res.partner'] + _usage = 'record.importer' + + def run(self, external_id): + # get the components we need for the sync + + # this one knows how to speak to magento + backend_adapter = self.component(usage='backend.adapter') + # this one knows how to convert magento data to odoo data + mapper = self.component(usage='import.mapper') + # this one knows how to link magento/odoo records + binder = self.component(usage='binder') + + # read external data from magento + external_data = backend_adapter.read(external_id) + # convert to odoo data + internal_data = mapper.map_record(external_data).values() + # find if the magento id already exists in odoo + binding = binder.to_internal(external_id) + if binding: + # if yes, we update it + binding.write(internal_data) + else: + # or we create it + binding = self.model.create(internal_data) + # finally, we bind both, so the next time we import + # the record, we'll update the same record instead of + # creating a new one + binder.bind(external_id, binding) + + +Ref: :ref:`api-component` diff --git a/ext/3rd-party-addons/connector/doc/guides/concepts.rst b/ext/3rd-party-addons/connector/doc/guides/concepts.rst new file mode 100644 index 00000000..50602293 --- /dev/null +++ b/ext/3rd-party-addons/connector/doc/guides/concepts.rst @@ -0,0 +1,255 @@ +.. _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 diff --git a/ext/3rd-party-addons/connector/doc/guides/jobrunner.rst b/ext/3rd-party-addons/connector/doc/guides/jobrunner.rst new file mode 100644 index 00000000..d10cc1ea --- /dev/null +++ b/ext/3rd-party-addons/connector/doc/guides/jobrunner.rst @@ -0,0 +1,39 @@ +.. _jobrunner: + + +####################################### +Configuring channels and the job runner +####################################### + +.. automodule:: odoo.addons.queue_job.jobrunner.runner + + +What is a channel? +------------------ + +.. autoclass:: odoo.addons.queue_job.jobrunner.channels.Channel + :noindex: + +How to configure Channels? +-------------------------- + +The ``ODOO_QUEUE_JOB_CHANNELS`` environment variable must be +set before starting Odoo in order to enable the job runner +and configure the capacity of the channels. + +The general syntax is ``channel(.subchannel)*(:capacity(:key(=value)?)*)?,...``. + +Intermediate subchannels which are not configured explicitly are autocreated +with an unlimited capacity (except the root channel which if not configured gets +a default capacity of 1). + +A delay in seconds between jobs can be set at the channel level with +the ``throttle`` key. + +Example ``ODOO_QUEUE_JOB_CHANNELS``: + +* ``root:4``: allow up to 4 concurrent jobs in the root channel. +* ``root:4,root.sub:2``: allow up to 4 concurrent jobs in the root channel and + up to 2 concurrent jobs in the channel named ``root.sub``. +* ``sub:2``: the same. +* ``root:4:throttle=2``: wait at least 2 seconds before starting the next job diff --git a/ext/3rd-party-addons/connector/doc/guides/migration_guide.rst b/ext/3rd-party-addons/connector/doc/guides/migration_guide.rst new file mode 100644 index 00000000..4b18c54f --- /dev/null +++ b/ext/3rd-party-addons/connector/doc/guides/migration_guide.rst @@ -0,0 +1,900 @@ +.. _migration-guide: + +######################################## +Migration Guide to the new Connector API +######################################## + +During the year 2017, the connector evolved greatly. +We can recognize three different aspect of the framework, they all have been +rewritten: + +* The Job Queue API (:ref:`api-queue`) +* The Event API (:ref:`api-event`) +* The ``ConnectorUnit`` API, which is the core of the composability + of the Connector. It has been replaced by a standalone addon + called ``component``. (:ref:`api-component`) + +The Connector has been splitted in different addons: + +* ``queue_job`` in https://github.com/OCA/queue +* ``component`` in the same repository +* ``component_event`` in the same repository +* ``connector`` uses the 3 addons and the parts specifics to the connectors + +This guide will show how to migrate from the old API to the new one. + +The previous API will stay until the migration to Odoo 11.0. + +.. contents:: Sections: + :local: + :backlinks: top + :depth: 2 + +************** +Migrating Jobs +************** + +Jobs are now more integrated within the Odoo API. They are no longer +standalone functions but are applied on methods of Models. Another change is +that they have been extracted into their own addon, so obviously the Python +paths change. + +Declaration of a job +==================== + +Before +------ + +.. code-block:: python + + from odoo.addons.connector.queue.job import job, related_action + from ..related_action import unwrap_binding, link + + # function at module-level + @job(default_channel='root.magento') + @related_action(action=link) + def import_record(session, model_name, backend_id, magento_id, force=False): + """ Import a record from Magento """ + # ... + + @job(default_channel='root.magento') + @related_action(action=unwrap_binding) + def export_record(session, model_name, binding_id, fields=None): + """ Import a record from Magento """ + # ... + + +After +----- + +.. code-block:: python + + from odoo.addons.queue_job.job import job, related_action + from odoo import api, models + + + class MagentoBinding(models.AbstractModel): + _name = 'magento.binding' + _inherit = 'external.binding' + _description = 'Magento Binding (abstract)' + + @job(default_channel='root.magento') + @related_action(action='related_action_magento_link') + @api.model + def import_record(self, backend, external_id, force=False): + """ Import a Magento record """ + backend.ensure_one() + # ... + + @job(default_channel='root.magento') + @related_action(action='related_action_unwrap_binding') + @api.multi + def export_record(self, fields=None): + """ Export a record on Magento """ + self.ensure_one() + # ... + + +Observations +------------ + +* The job is declared on the generic abstract binding model from which all + bindings inherit. This is not a requirement, but for this kind of job it is + the perfect fit. +* ``session``, ``model_name`` and ``binding_id`` are no longer required as they + are already known in ``self``. Jobs can be used as well on ``@api.multi`` and + ``@api.model``. +* Passing arguments as records is supported, in the new version of + ``import_record``, no need to browse on the backend if a record was passed +* The action of a related action is now the name of a method on the + ``queue.job`` model. +* If you need to share a job between several models, put them in an + AbstractModel and add an ``_inherit`` on the models. + +Links +----- + +* :meth:`odoo.addons.queue_job.job.job` +* :meth:`odoo.addons.queue_job.job.related_action` + + +Invocation of a job +=================== + +Before +------ + +.. code-block:: python + + from odoo.addons.connector.session import ConnectorSession + from .unit.export_synchronizer import export_record + + + class MyBinding(models.Model): + _name = 'my.binding' + _inherit = 'magento.binding' + + @api.multi + def button_trigger_export_sync(self): + session = ConnectorSession.from_env(self.env) + export_record(session, binding._name, self.id, fields=['name']) + + @api.multi + def button_trigger_export_async(self): + session = ConnectorSession.from_env(self.env) + export_record.delay(session, self._name, self.id, + fields=['name'], priority=12) + + +After +----- + +.. code-block:: python + + class MyBinding(models.Model): + _name = 'my.binding' + + @api.multi + def button_trigger_export_sync(self): + self.export_record(fields=['name']) + + @api.multi + def button_trigger_export_async(self): + self.with_delay(priority=12).export_record(fields=['name']) + +Observations +------------ + +* No more imports are needed for the invocation +* ``ConnectorSession`` is now dead +* Arguments for the job (such as ``priority``) are no longer mixed with the + arguments passed to the method +* When the job is called on a "browse" record, the job will be executed + on an instance of this record: + + .. code-block:: python + + >>> binding = self.env['my.binding'].browse(1) + >>> binding.button_trigger_export_async() + + In the execution of the job: + + .. code-block:: python + + @job + def export_record(self, fields=None): + print self + print fields + # => + # my.binding,1 + # ['name'] + +Links +----- + +* :meth:`odoo.addons.queue_job.job.job` +* :meth:`odoo.addons.queue_job.models.base.Base.with_delay` + +**************** +Migrating Events +**************** + +Events are now handled by the ``component_event`` addon. + +Triggering an event +=================== + +Before +------ + +First you had to create an :class:`~odoo.addons.connector.event.Event` instance: + +.. code-block:: python + + on_record_create = Event() + +And then import and trigger it, passing a lot of arguments to it: + +.. code-block:: python + + from odoo.addons.connector.event import on_record_create + + class Base(models.AbstractModel): + """ The base model, which is implicitly inherited by all models. """ + _inherit = 'base' + + @api.model + def create(self, vals): + record = super(Base, self).create(vals) + on_record_create.fire(self.env, self._name, record.id, vals) + return record + + +After +----- + +.. code-block:: python + + class Base(models.AbstractModel): + _inherit = 'base' + + @api.model + def create(self, vals): + record = super(Base, self).create(vals) + self._event('on_record_create').notify(record, fields=vals.keys()) + return record + +Observations +------------ + +* No more imports are needed for the invocation + Only the arguments you want to pass should be passed to + :meth:`odoo.addons.component_event.components.event.CollectedEvents.notify`. +* The name of the event must start with ``'on_'`` + +Links +----- + +* :mod:`odoo.addons.component_event.components.event` + + +Listening to an event +===================== + +Before +------ + +.. code-block:: python + + from odoo.addons.connector.event import on_record_create + + @on_record_create + def delay_export(env, model_name, record_id, vals): + if session.context.get('connector_no_export'): + return + fields = vals.keys() + export_record.delay(session, model_name, record_id, fields=fields) + + @on_something + def do_anything(env, model_name, record_id): + # ... + +After +----- + +.. code-block:: python + + from odoo.addons.component.core import Component + from odoo.addons.component_event import skip_if + + class MagentoListener(Component): + _name = 'magento.event.listener' + _inherit = 'base.connector.listener' + + @skip_if(lambda self, record, **kwargs: self.no_connector_export(record)) + def on_record_create(self, record, fields=None): + """ Called when a record is created """ + record.with_delay().export_record(fields=fields) + + def on_something(self, record): + # ... + +Observations +------------ + +* The listeners are now components +* The name of the method is the same than the one notified in the previous + section +* A listener Component might container several listener methods +* It must inherit from ``'base.event.listener'``, or one of its descendants. +* The check of the key ``connector_no_export`` in the context can + be replaced by the decorator :func:`odoo.addons.component_event.skip_if` + +Links +----- + +* :mod:`odoo.addons.component_event.components.event` + + +Listening to an event only for some Models +========================================== + +Before +------ + +.. code-block:: python + + from odoo.addons.connector.event import on_record_create + + @on_record_create(model_names=['magento.address', 'magento.res.partner']) + def delay_export(env, model_name, record_id, vals): + if session.context.get('connector_no_export'): + return + fields = vals.keys() + export_record.delay(session, model_name, record_id, fields=fields) + +After +----- + +.. code-block:: python + + from odoo.addons.component.core import Component + from odoo.addons.component_event import skip_if + + class MagentoListener(Component): + _name = 'magento.event.listener' + _inherit = 'base.event.listener' + _apply_on = ['magento.address', 'magento.res.partner'] + + @skip_if(lambda self, record, **kwargs: self.no_connector_export(record)) + def on_record_create(self, record, fields=None): + """ Called when a record is created """ + record.with_delay().export_record(fields=fields) + +Observations +------------ + +* Same than previous example but we added ``_apply_on`` on the Component. + +Links +----- + +* :mod:`odoo.addons.component_event.components.event` + + +******************** +Migrating Components +******************** + +Backends +======== + +Before +------ + +You could have several versions for a backend: + +.. code-block:: python + + magento = backend.Backend('magento') + """ Generic Magento Backend """ + + magento1700 = backend.Backend(parent=magento, version='1.7') + """ Magento Backend for version 1.7 """ + + magento1900 = backend.Backend(parent=magento, version='1.9') + """ Magento Backend for version 1.9 """ + + + +It was linked with a Backend model such as: + +.. code-block:: python + + class MagentoBackend(models.Model): + _name = 'magento.backend' + _description = 'Magento Backend' + _inherit = 'connector.backend' + + _backend_type = 'magento' + + @api.model + def select_versions(self): + """ Available versions in the backend. + Can be inherited to add custom versions. Using this method + to add a version from an ``_inherit`` does not constrain + to redefine the ``version`` field in the ``_inherit`` model. + """ + return [('1.7', '1.7+')] + + version = fields.Selection(selection='select_versions', required=True) + + + +After +----- + +All the :class:`backend.Backend` instances must be deleted. + +And the ``_backend_type`` must be removed from the Backend model. + +.. code-block:: python + + class MagentoBackend(models.Model): + _name = 'magento.backend' + _description = 'Magento Backend' + _inherit = 'connector.backend' + + @api.model + def select_versions(self): + """ Available versions in the backend. + Can be inherited to add custom versions. Using this method + to add a version from an ``_inherit`` does not constrain + to redefine the ``version`` field in the ``_inherit`` model. + """ + return [('1.7', '1.7+')] + + version = fields.Selection(selection='select_versions', required=True) + + +Observations +------------ + +* The version is now optional in the Backend Models. +* Backend Models are based on Component's Collections: + :class:`odoo.addons.component.models.collection.Collection` + +Links +----- + +* :ref:`api-component` +* :class:`odoo.addons.component.models.collection.Collection` + + +Inheritance +=========== + +Before +------ + +You could inherit a ``ConnectorUnit`` by creating a custom Backend +version and decorating your class with it + +.. code-block:: python + + magento_custom = backend.Backend(parent=magento1700, version='custom') + """ Custom Magento Backend """ + + +.. code-block:: python + + # base one + @magento + class MagentoPartnerAdapter(GenericAdapter): + # ... + + # other file... + + from .backend import magento_custom + + # custom one + @magento_custom + class MyPartnerAdapter(MagentoPartnerAdapter): + # ... + + def do_something(self): + # do it this way + +You could also replace an existing class, this is mentionned in `Replace or +unregister a component`_. + + +After +----- + +For an existing component: + +.. code-block:: python + + from odoo.addons.component.core import Component + + class MagentoPartnerAdapter(Component): + _name = 'magento.partner.adapter' + _inherit = 'magento.adapter' + + def do_something(self): + # do it this way + +You can extend it: + +.. code-block:: python + + from odoo.addons.component.core import Component + + class MyPartnerAdapter(Component): + _inherit = 'magento.partner.adapter' + + def do_something(self): + # do it this way + +Or create a new different component with the existing one as base: + +.. code-block:: python + + from odoo.addons.component.core import Component + + class MyPartnerAdapter(Component): + _name = 'my.magento.partner.adapter' + _inherit = 'magento.partner.adapter' + + def do_something(self): + # do it this way + + +Observations +------------ + +* The inheritance is similar to the Odoo's one (without ``_inherits``. +* All components have a Python inheritance on + :class:`~odoo.addons.component.core.AbstractComponent` or + :class:`~odoo.addons.component.core.Component` +* The names are global (as in Odoo), so you should prefix them with a namespace +* The name of the classes has no effect +* As in Odoo Models, a Component can ``_inherit`` from a list of Components +* All components implicitly inherits from a ``'base'`` component + +Links +----- + +* :ref:`api-component` +* :class:`odoo.addons.component.core.AbstractComponent` + + + +Entrypoint for working with components +====================================== + +Before +------ + +Previously, when you had to work with ``ConnectorUnit`` from a Model or from a job, +depending of the Odoo version you to: + +.. code-block:: python + + from odoo.addons.connector.connector import ConnectorEnvironment + + # ... + + backend_record = session.env['magento.backend'].browse(backend_id) + env = ConnectorEnvironment(backend_record, 'magento.res.partner') + importer = env.get_connector_unit(MagentoImporter) + importer.run(magento_id, force=force) + +Or: + +.. code-block:: python + + from odoo.addons.connector.connector import ConnectorEnvironment + from odoo.addons.connector.session import ConnectorSession + + #... + + backend_record = session.env['magento.backend'].browse(backend_id) + session = ConnectorSession.from_env(self.env) + env = ConnectorEnvironment(backend_record, session, 'magento.res.partner') + importer = env.get_connector_unit(MagentoImporter) + importer.run(external_id, force=force) + +Which was commonly abstracted in a helper function such as: + + +.. code-block:: python + + def get_environment(session, model_name, backend_id): + """ Create an environment to work with. """ + backend_record = session.env['magento.backend'].browse(backend_id) + env = ConnectorEnvironment(backend_record, session, 'magento.res.partner') + lang = backend_record.default_lang_id + lang_code = lang.code if lang else 'en_US' + if lang_code == session.context.get('lang'): + return env + else: + with env.session.change_context(lang=lang_code): + return env + +After +----- + +.. code-block:: python + + # ... + backend_record = self.env['magento.backend'].browse(backend_id) + with backend_record.work_on('magento.res.partner') as work: + importer = work.component(usage='record.importer') + importer.run(external_id, force=force) + +Observations +------------ + +* And when you are already in a Component, refer to `Find a component`_ + +Links +----- + +* :class:`~odoo.addons.component.core.WorkContext` + + +Find a component +================ + +Before +------ + +To find a ``ConnectorUnit``, you had to ask for given class or subclass: + +.. code-block:: python + + # our ConnectorUnit to find + @magento + class MagentoPartnerAdapter(GenericAdapter): + _model_name = ['magent.res.partner'] + + # other file... + + def run(self, record): + backend_adapter = self.unit_for(GenericAdapter) + +It was searched for the current model and the current backend. + +After +----- + +For an existing component: + +.. code-block:: python + + from odoo.addons.component.core import Component + + class MagentoPartnerAdapter(Component): + _name = 'magento.partner.adapter' + _inherit = 'magento.adapter' + + _usage = 'backend.adapter' + _collection = 'magento.backend' + _apply_on = ['res.partner'] + + # other file... + + def run(self, record): + backend_adapter = self.component(usage='backend.adapter') + + + +Observations +------------ + +* The model is compared with the ``_apply_on`` attribute +* The Backend is compared with the ``_collection`` attribute, it must + have the same name than the Backend Model. +* The ``_usage`` indicates what the purpose of the component is, and + allow to find the correct one for our task. It allow more dynamic + usages than the previous usage of a class. +* Usually, the ``_usage`` and the ``_collection`` will be ``_inherit`` 'ed from + a component (here from ``'magento.adapter``), so they won't need to be + repeated in all Components. +* A good idea is to have a base abstract Component for the Collection, then + an abstract Component for every usage:: + + class BaseMagentoConnectorComponent(AbstractComponent): + + _name = 'base.magento.connector' + _inherit = 'base.connector' + _collection = 'magento.backend' + + class MagentoBaseExporter(AbstractComponent): + """ Base exporter for Magento """ + + _name = 'magento.base.exporter' + _inherit = ['base.exporter', 'base.magento.connector'] + _usage = 'record.exporter' + + class MagentoImportMapper(AbstractComponent): + _name = 'magento.import.mapper' + _inherit = ['base.magento.connector', 'base.import.mapper'] + _usage = 'import.mapper' + + # ... + +* The main usages are: + * import.mapper + * export.mapper + * backend.adapter + * importer + * exporter + * binder + * event.listener +* But for the importer and exporter, I recommend to use more precise ones in + the connectors: record.importer, record.exporter, batch.importer, + batch.exporter +* You are allowed to be creative with the ``_usage``, it's the key that will + allow you to find the right one component you need. (e.g. on + ``stock.picking`` you need to 1. export the record, 2. export the tracking. + Then use ``record.exporter`` and ``tracking.exporter``). +* AbstractComponent will never be returned by a lookup + + +Links +----- + +* :ref:`api-component` +* :class:`odoo.addons.component.core.AbstractComponent` + + +Backend Versions +================ + +Before +------ + +You could have several versions for a backend: + +.. code-block:: python + + magento = backend.Backend('magento') + """ Generic Magento Backend """ + + magento1700 = backend.Backend(parent=magento, version='1.7') + """ Magento Backend for version 1.7 """ + + magento1900 = backend.Backend(parent=magento, version='1.9') + """ Magento Backend for version 1.9 """ + + +And use them for a class-level dynamic dispatch + +.. code-block:: python + + from odoo.addons.magentoerpconnect.backend import magento1700, magento1900 + + @magento1700 + class PartnerAdapter1700(GenericAdapter): + # ... + + def do_something(self): + # do it this way + + @magento1900 + class PartnerAdapter1900(GenericAdapter): + # ... + + def do_something(self): + # do it that way + + +After +----- + +This feature has been removed, it introduced a lot of complexity (notably +regarding inheritance) for few gain. The version is now optional on the +backends and the version dispatch, if needed, should be handled manually. + +In methods: + +.. code-block:: python + + from odoo.addons.component.core import Component + + class PartnerAdapter(Component): + # ... + + def do_something(self): + if self.backend_record.version == '1.7': + # do it this way + else: + # do it that way + +Or with a factory: + +.. code-block:: python + + from odoo.addons.component.core import Component + + class PartnerAdapterFactory(Component): + # ... + + def get_component(self, version): + if self.backend_record.version == '1.7': + return self.component(usage='backend.adapter.1.7') + else: + return self.component(usage='backend.adapter.1.9') + +Observations +------------ + +* None + +Links +----- + +* :ref:`api-component` + + +Replace or unregister a component +================================= + +Before +------ + +You could replace a ``ConnectorUnit`` with the ``replace`` argument passed to +the backend decorator: + +.. code-block:: python + + @magento(replacing=product.ProductImportMapper) + class ProductImportMapper(product.ProductImportMapper): + + +After +----- + +First point: this should hardly be needed now, as you can inherit a component +like Odoo Models. Still, if you need to totally replace a component by +another, let's say there is this component: + +.. code-block:: python + + from odoo.addons.component.core import Component + + class ProductImportMapper(Component): + _name = 'magento.product.import.mapper' + _inherit = 'magento.import.mapper' + + _apply_on = ['magento.product.product'] + # normally the following attrs are inherited from the _inherit + _usage = 'import.mapper' + _collection = 'magento.backend' + + +Then you can remove the usage of the component: it will never be used: + +.. code-block:: python + + from odoo.addons.component.core import Component + + class ProductImportMapper(Component): + _inherit = 'magento.product.import.mapper' + _usage = None + +And create your own, that will be picked up instead of the base one: + +.. code-block:: python + + from odoo.addons.component.core import Component + + class MyProductImportMapper(Component): + _name = 'my.magento.product.import.mapper' + _inherit = 'magento.import.mapper' + + _apply_on = ['magento.product.product'] + # normally the following attrs are inherited from the _inherit + _usage = 'import.mapper' + _collection = 'magento.backend' + + +Observations +------------ + +* None + +Links +----- + +* :ref:`api-component` + + +Various hints +============= + +* The components and the jobs know how to work with Model instances, + so prefer them over ids in parameters. diff --git a/ext/3rd-party-addons/connector/doc/index.rst b/ext/3rd-party-addons/connector/doc/index.rst new file mode 100644 index 00000000..c148435a --- /dev/null +++ b/ext/3rd-party-addons/connector/doc/index.rst @@ -0,0 +1,125 @@ +.. Connectors documentation master file, created by + sphinx-quickstart on Mon Feb 4 11:35:44 2013. + You can adapt this file completely to your liking, but it should at least + contain the root `toctree` directive. + +############## +Odoo Connector +############## + +Odoo Connector is a powerful framework to develop any kind of +bi-directional connector between `Odoo`_ (Open Source ERP) and any other +software or service. + +This Odoo add-on has a modular and generic core, with the +ability to be extended with additional modules for new features or +customizations. + +The development of Odoo Connector has been started by `Camptocamp`_ and is now +maintained by `Camptocamp`_, `Akretion`_, `Acsone`_ and several :ref:`contributors`. + +It got a major overhaul in 2017 (Odoo 10.0). A :ref:`migration-guide` is +available. + +*Subscribe to the* `project's mailing list (name: Connectors)`_ + +*Learn how to* :ref:`contribute` + +************* +Core Features +************* + +* **100% Open Source** (`AGPL version 3`_): the full `source code is available + on GitHub`_ +* Not only designed to connect Odoo with e-commerce backends, + rather it is **adaptable** to connect Odoo with any type of service. +* **Robust for high volumetries** and **easy to monitor** thanks to a :ref:`jobs-queue`. +* A flexible set of building blocks, it does not force to a certain + implementation but leaves the final choice to the + developer on how to use the proposed pieces. +* See a :ref:`code-overview` with examples of code + +.. _Odoo: https://www.odoo.com +.. _Camptocamp: https://www.camptocamp.com +.. _Akretion: http://www.akretion.com +.. _Acsone: https://www.acsone.eu +.. _`source code is available on GitHub`: https://github.com/OCA/connector +.. _`AGPL version 3`: https://www.gnu.org/licenses/agpl-3.0.html +.. _`project's mailing list (name: Connectors)`: https://odoo-community.org/groups + +***************** +Developer's guide +***************** + +.. toctree:: + :maxdepth: 2 + + guides/migration_guide.rst + guides/code_overview.rst + guides/concepts.rst + guides/bootstrap_connector.rst + guides/jobrunner.rst + +API Reference +============= + +.. toctree:: + :maxdepth: 1 + + api/api_components.rst + api/api_backend.rst + api/api_event.rst + api/api_queue.rst + api/api_exception.rst + api/api_channels.rst + +******* +Project +******* + +.. toctree:: + :maxdepth: 1 + + project/contribute + project/contributors + project/license + project/changes + project/roadmap + +********************************* +Connectors based on the framework +********************************* + +* `Magento Connector `_ +* `Prestashop Connector `_ +* `Search Engine Connector `_ +* `CMIS `_ +* `Odoo Asynchronous import module `_ +* `Salesforce Connector `_ +* `JIRA Connector `_ +* `Google Spreadsheet Connector `_ +* `Connector Exchange `_ +* Develop easily and rapidly your own connector based on this powerful + framework and list your project on this page! Examples: + + * E-Commerce: Odoo OsCommerce connector, Odoo Drupal Commerce connector, Odoo Spree connector, Odoo Ebay connector, Odoo Amazon connector… + * CMS: Odoo Wordpress connector… + * CRM: Odoo SugarCRM connector, Odoo Zabbix connector… + * Project Management: Odoo Redmine connector… + * Ticketing: Odoo Request Tracker connector, Odoo GLPI connector… + + +***** +Talks +***** + +* `A jobs queue for processing tasks asynchronously. Leonardo Pistone & Guewen Baconnier (2015) `_ +* `E-commerce: the new Magento - OpenERP Connector: a generic connector to any apps. Luc Maurer & Guewen Baconnier, Camptocamp (2013) `_ + +****************** +Indices and tables +****************** + +* :ref:`genindex` +* :ref:`modindex` +* :ref:`search` diff --git a/ext/3rd-party-addons/connector/doc/locale/fr/LC_MESSAGES/api.po b/ext/3rd-party-addons/connector/doc/locale/fr/LC_MESSAGES/api.po new file mode 100644 index 00000000..9786275a --- /dev/null +++ b/ext/3rd-party-addons/connector/doc/locale/fr/LC_MESSAGES/api.po @@ -0,0 +1,2946 @@ +# +msgid "" +msgstr "" +"Project-Id-Version: Connector\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2015-04-15 22:28+0300\n" +"PO-Revision-Date: 2015-04-17 13:54+0200\n" +"Last-Translator: Christophe Combelles \n" +"Language-Team: fr \n" +"Language: fr\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Generator: Poedit 1.6.10\n" + +#: ../../api/api_backend.rst:2 +msgid "Backend" +msgstr "Backend" + +#: ../../api/api_backend.rst:4 +msgid "" +"A backend for a version (for instance Magento 1.7), is represented by an " +"instance of the :py:class:`~connector.backend.Backend` class." +msgstr "" +"Le backend pour une version (par exemple Magento 1.7) est représenté par une" +" instance de la classe :py:class:`~connector.backend.Backend`." + +#: ../../api/api_backend.rst:7 +msgid "" +"Each connector will also create a ``connector.backend`` which allows the " +"users to register their backends. For instance, the Magento connector has " +"``magento.backend`` (``_inherit`` " +":py:class:`connector.backend_model.connector_backend`). This model contains" +" a ``version`` field which should have the same list of versions (with the " +"exact same name) than the instances of " +":py:class:`~connector.backend.Backend`." +msgstr "" +"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`` " +":py:class:`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 " +":py:class:`~connector.backend.Backend`." + +#: ../../api/api_backend.rst:14 +msgid "Example with the Magento Connector::" +msgstr "Exemple avec le connecteur Magento ::" + +#: ../../api/api_backend.rst:54 +msgid "" +"In the code above, '1.7' is the matching key between the " +":py:class:`~connector.backend.Backend` instance (``magento1700``) and the " +"``magento_backend`` record." +msgstr "" +"Dans le code ci-dessus, '1.7' est la clé de correspondance entre l'instance " +"de :py:class:`~connector.backend.Backend` (``magento1700``) et " +"l'enregistrement ``magento_backend``." + +#: ../../../backend.pydocstring of connector.backend.Backend:1 +#: ../../../connector.pydocstring of +#: connector.connector.ConnectorEnvironment:1 ../../../connector.pydocstring +#: of connector.connector.ConnectorUnit:1 ../../../event.pydocstring of +#: connector.event.Event:1 ../../../unit/mapper.pydocstring of +#: connector.unit.mapper.MapRecord:1 ../../../queue/job.pydocstring of +#: connector.queue.job.Job:1 ../../../queue/job.pydocstring of +#: connector.queue.job.JobStorage:1 ../../../queue/queue.pydocstring of +#: connector.queue.queue.JobsQueue:1 ../../../session.pydocstring of +#: connector.session.ConnectorSession:1 ../../../session.pydocstring of +#: connector.session.ConnectorSessionHandler:1 +msgid "Bases: :class:`object`" +msgstr "Bases : :class:`object`" + +#: ../../../backend.pydocstring of connector.backend.Backend:1 +msgid "" +"A backend represents a system to interact with, like Magento, Prestashop, " +"Redmine, ..." +msgstr "" +"Un backend représente un système avec lequel interagir, comme Magento, " +"Prestashop, Redmine, ..." + +#: ../../../backend.pydocstring of connector.backend.Backend:4 +msgid "It owns 3 properties:" +msgstr "Il possède trois propriétés :" + +#: ../../../backend.pydocstring of connector.backend.Backend:8 +msgid "Name of the service, for instance 'magento'" +msgstr "Le nom du service, par exemple 'magento'" + +#: ../../../backend.pydocstring of connector.backend.Backend:12 +msgid "The version of the service. For instance: '1.7'" +msgstr "La version du service. Par exemple '1.7'" + +#: ../../../backend.pydocstring of connector.backend.Backend:16 +msgid "" +"A parent backend. When no :py:class:`~connector.connector.ConnectorUnit` is " +"found for a backend, it will search it in the `parent`." +msgstr "" +"Un backend parent. Lorsqu'aucune classe " +":py:class:`~connector.connector.ConnectorUnit` n'est trouvée pour un " +"backend, elle est cherchée dans le `parent`." + +#: ../../../backend.pydocstring of connector.backend.Backend:20 +msgid "" +"The Backends structure is a key part of the framework, but is rather simple." +msgstr "" +"La structure des Backends est la partie clé du framework, mais elle est " +"plutôt simple." + +#: ../../../backend.pydocstring of connector.backend.Backend:23 +msgid "" +"A ``Backend`` instance holds a registry of " +":py:class:`~connector.connector.ConnectorUnit` classes" +msgstr "" +"Une instance de ``Backend`` contient un registre de classes " +":py:class:`~connector.connector.ConnectorUnit`" + +#: ../../../backend.pydocstring of connector.backend.Backend:25 +msgid "" +"It can return the appropriate :py:class:`~connector.connector.ConnectorUnit`" +" to use for a task" +msgstr "" +"Il peut renvoyer la classe :py:class:`~connector.connector.ConnectorUnit` à " +"utiliser pour une tâche" + +#: ../../../backend.pydocstring of connector.backend.Backend:27 +msgid "" +"If no :py:class:`~connector.connector.ConnectorUnit` is registered for a " +"task, it will ask it to its direct parent (and so on)" +msgstr "" +"Si aucune :py:class:`~connector.connector.ConnectorUnit` n'est inscrite pour" +" une tâche, le parent direct est interrogé (et ainsi de suite)" + +#: ../../../backend.pydocstring of connector.backend.Backend:31 +msgid "" +"The Backends support 2 different extension mechanisms. One is more vertical " +"- across the versions - and the other would be more horizontal as it allows " +"to modify the behavior for 1 version of backend." +msgstr "" +"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." + +#: ../../../backend.pydocstring of connector.backend.Backend:35 +msgid "" +"For the sake of the example, let's say we have theses backend versions::" +msgstr "" +"Pour l'exemple, disons que nous avons les versions suivantes de backend ::" + +#: ../../../backend.pydocstring of connector.backend.Backend:45 +msgid "And here is the way they are declared in Python::" +msgstr "Et voici la façon dont elles sont déclarées en Python ::" + +#: ../../../backend.pydocstring of connector.backend.Backend:53 +msgid "" +"In the graph above, ```` will hold all the classes shared between " +"all the versions. Each Magento version (````, ````) will use the classes defined on ````, excepted if they " +"registered their own ones instead. That's the same for ```` but this one contains customizations which are specific to an " +"instance (typically you want specific mappings for one instance)." +msgstr "" +"Dans le graphe ci-dessus, ```` va contenir toutes les classes " +"partagées entre toutes les versions. Chaque version de Magento (````, ````) va utiliser les classes définies sur " +"````, sauf si elles ont inscrit leur propres classes. C'est la même" +" chose pour ```` mais celui-ci contient des " +"personnalisations qui sont spécifiques à une instance (typiquement pour " +"mettre en place des mappeurs spécifiques à une instance)." + +#: ../../../backend.pydocstring of connector.backend.Backend:60 +msgid "" +"Here is how you would register classes on ```` and another on " +"````::" +msgstr "" +"Voici comment inscrire des classes sur ```` et une autre sur " +"```` ::" + +#: ../../../backend.pydocstring of connector.backend.Backend:75 +msgid "" +"Here, the :py:meth:`~get_class` called on ``magento1700`` would return::" +msgstr "" +"Ici, la méthode :py:meth:`~get_class` appelé sur ``magento1700`` renverrait " +"::" + +#: ../../../backend.pydocstring of connector.backend.Backend:82 +msgid "" +"This is the vertical extension mechanism, it says that each child version is" +" able to extend or replace the behavior of its parent." +msgstr "" +"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." + +#: ../../../backend.pydocstring of connector.backend.Backend:85 +msgid "when using the framework, you won't need to call" +msgstr "en utilisant le framework, vous n'aurez pas besoin d'appeler" + +#: ../../../backend.pydocstring of connector.backend.Backend:86 +msgid "" +":py:meth:`~get_class`, usually, you will call " +":py:meth:`connector.connector.ConnectorEnvironment.get_connector_unit`." +msgstr "" +":py:meth:`~get_class`, habituellement vous appellerez " +":py:meth:`connector.connector.ConnectorEnvironment.get_connector_unit`." + +#: ../../../backend.pydocstring of connector.backend.Backend:89 +msgid "" +"The vertical extension is the one you will probably use the most, because " +"most of the things you will change concern your custom adaptations or " +"different behaviors between the versions of the backend." +msgstr "" +"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." + +#: ../../../backend.pydocstring of connector.backend.Backend:93 +msgid "" +"However, some time, we need to change the behavior of a connector, by " +"installing an addon. For example, say that we already have an " +"``ImportMapper`` for the products in the Magento Connector. We create a - " +"generic - addon to handle the catalog in a more advanced manner. We redefine" +" an ``AdvancedImportMapper``, which should be used when the addon is " +"installed. This is the horizontal extension mechanism." +msgstr "" +"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 un ``AdvancedImportMapper`` qui devrait " +"être utilisé quand le module est installé. Ceci est le mécanisme d'extension" +" horizontal." + +#: ../../../backend.pydocstring of connector.backend.Backend:100 +msgid "" +"Replace a :py:class:`~connector.connector.ConnectorUnit` by another one in a" +" backend::" +msgstr "" +"Remplace une clase :py:class:`~connector.connector.ConnectorUnit` par une " +"autre dans le backend ::" + +#: ../../../backend.pydocstring of connector.backend.Backend:107 +msgid "" +"The horizontal extension should be used sparingly and cautiously since as " +"soon as 2 addons want to replace the same class, you'll have a conflict " +"(which would need to create a third addon to glue them, ``replacing`` can " +"take a tuple of classes to replace and this is exponential). This mechanism " +"should be used only in some well placed circumstances for generic addons." +msgstr "" +"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." + +#: ../../../backend.pydocstring of connector.backend.Backend.get_class:1 +msgid "Find a matching subclass of ``base_class`` in the registered classes." +msgstr "" +"Trouve une sous-classe correspondante à ``base_class`` dans les classes " +"inscrites." + +#: ../../../backend.pydocstring of connector.backend.Backend.get_class:4 +msgid "class (and its subclass) to search in the registry" +msgstr "Classe (et sous-classe) à rechercher dans le registre" + +#: ../../../backend.pydocstring of connector.backend.Backend.get_class:6 +#: ../../../connector.pydocstring of connector.connector.ConnectorUnit.match:4 +#: ../../../event.pydocstring of connector.event.Event.fire:7 +msgid "current session" +msgstr "session en cours" + +#: ../../../backend.pydocstring of connector.backend.Backend.match:1 +msgid "Used to find the backend for a service and a version" +msgstr "Utilisé pour trouver le backend pour un service et une version" + +#: ../../../backend.pydocstring of connector.backend.Backend.register_class:1 +msgid "Register a class in the backend." +msgstr "Inscrit une classe dans le backend" + +#: ../../../backend.pydocstring of connector.backend.Backend.register_class:3 +msgid "the ConnectorUnit class class to register" +msgstr "la classe ConnectorUnit à inscrire" + +#: ../../../backend.pydocstring of connector.backend.Backend.register_class:5 +msgid "optional, the ConnectorUnit class to replace" +msgstr "optionnel, la classe ConnectorUnit à remplacer" + +#: ../../api/api_backend.rst:64 +msgid "Backend Models" +msgstr "Modèles du backend" + +#: ../../../backend_model.pydocstring of +#: connector.backend_model.ConnectorBackend:1 +#: ../../../backend_model.pydocstring of +#: connector.backend_model.ExternalBinding:1 +msgid "Bases: :class:`odoo.models.AbstractModel`" +msgstr "Bases : :class:`odoo.models.AbstractModel`" + +#: ../../../backend_model.pydocstring of +#: connector.backend_model.ConnectorBackend:1 +msgid "An instance of an external backend to synchronize with." +msgstr "Une instance d'un backend externe auquel se synchroniser" + +#: ../../../backend_model.pydocstring of +#: connector.backend_model.ConnectorBackend:3 +msgid "" +"The backends have to ``_inherit`` this model in the connectors modules." +msgstr "" +"Les backends doivent ``_inherit`` ce modèle dans les modules des " +"connecteurs." + +#: ../../../backend_model.pydocstring of +#: connector.backend_model.ConnectorBackend.get_backend:1 +msgid "" +"For a record of backend, returns the appropriate instance of " +":py:class:`~connector.backend.Backend`." +msgstr "" +"Pour un enregistrement d'un backend, renvoie l'instance appropriée de " +":py:class:`~connector.backend.Backend`." + +#: ../../../backend_model.pydocstring of +#: connector.backend_model.ConnectorBackend.name:1 +#: ../../../queue/model.pydocstring of +#: connector.queue.model.QueueJob.func_string:1 +#: ../../../queue/model.pydocstring of +#: connector.queue.model.QueueJob.model_name:1 +#: ../../../queue/model.pydocstring of connector.queue.model.QueueJob.name:1 +#: ../../../queue/model.pydocstring of connector.queue.model.QueueJob.uuid:1 +#: ../../../queue/model.pydocstring of connector.queue.model.QueueWorker.pid:1 +#: ../../../queue/model.pydocstring of +#: connector.queue.model.QueueWorker.uuid:1 +msgid "" +"Basic string field, can be length-limited, usually displayed as a single-" +"line string in clients" +msgstr "" +"Champ chaîne de caractère basique, peut être limité en longeur, " +"habituellement affiché comme ligne unique dans les clients" + +#: ../../../backend_model.pydocstring of +#: connector.backend_model.ConnectorBackend.name:4 +#: ../../../queue/model.pydocstring of +#: connector.queue.model.QueueJob.func_string:4 +#: ../../../queue/model.pydocstring of +#: connector.queue.model.QueueJob.model_name:4 +#: ../../../queue/model.pydocstring of connector.queue.model.QueueJob.name:4 +#: ../../../queue/model.pydocstring of connector.queue.model.QueueJob.uuid:4 +#: ../../../queue/model.pydocstring of connector.queue.model.QueueWorker.pid:4 +#: ../../../queue/model.pydocstring of +#: connector.queue.model.QueueWorker.uuid:4 +msgid "the maximum size of values stored for that field" +msgstr "la taille maximum des valeurs stockées dans ce champ" + +#: ../../../backend_model.pydocstring of +#: connector.backend_model.ConnectorBackend.name:5 +#: ../../../queue/model.pydocstring of +#: connector.queue.model.QueueJob.func_string:5 +#: ../../../queue/model.pydocstring of +#: connector.queue.model.QueueJob.model_name:5 +#: ../../../queue/model.pydocstring of connector.queue.model.QueueJob.name:5 +#: ../../../queue/model.pydocstring of connector.queue.model.QueueJob.uuid:5 +#: ../../../queue/model.pydocstring of connector.queue.model.QueueWorker.pid:5 +#: ../../../queue/model.pydocstring of +#: connector.queue.model.QueueWorker.uuid:5 +msgid "whether the values of this field can be translated" +msgstr "si les valeurs de ce champ peuvent être traduites" + +#: ../../../backend_model.pydocstring of +#: connector.backend_model.ConnectorBackend.version:1 +#: ../../../queue/model.pydocstring of connector.queue.model.QueueJob.state:1 +msgid "" +"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." +msgstr "" +"précise les valeurs possible de ce champs. C'est donné soit comme liste de " +"paires (`valeur`, `chaîne`), soit comme méthode de modèle, soit comme nom de" +" méthode." + +#: ../../../backend_model.pydocstring of +#: connector.backend_model.ConnectorBackend.version:4 +#: ../../../queue/model.pydocstring of connector.queue.model.QueueJob.state:4 +msgid "" +"provides an extension of the selection in the case of an overridden field. " +"It is a list of pairs (`value`, `string`)." +msgstr "" +"fournit une extension de la sélection dans le cas d'un champ surchargé. " +"C'est une liste de paires (`value`, `string`)." + +#: ../../../backend_model.pydocstring of +#: connector.backend_model.ConnectorBackend.version:7 +#: ../../../queue/model.pydocstring of connector.queue.model.QueueJob.state:7 +msgid "" +"The attribute `selection` is mandatory except in the case of :ref:`related " +"fields ` or :ref:`field extensions `." +msgstr "" +"L'attribut `selection` est obligatoire sauf dans le cas de :ref:`related " +"fields ` ou :ref:`field extensions `." + +#: ../../../backend_model.pydocstring of +#: connector.backend_model.ExternalBinding:1 +msgid "An abstract model for bindings to external records." +msgstr "Un modèle abstrait pour une liaison à des enregistrements externes" + +#: ../../../backend_model.pydocstring of +#: connector.backend_model.ExternalBinding:3 +msgid "" +"An external binding is a binding between a backend and Odoo. For " +"example, for a partner, it could be ``magento.res.partner`` or for a " +"product, ``magento.product``." +msgstr "" +"Un binding externe est une liaison entre un backend et Odoo. Par exemple," +" pour un `partner`, cela peut être ``magento.res.partner`` ou pour un " +"article, ``magento.product``." + +#: ../../../backend_model.pydocstring of +#: connector.backend_model.ExternalBinding:7 +msgid "" +"The final model, will be an ``_inherits`` of the Odoo model and will " +"``_inherit`` this model." +msgstr "" +"Le modèle final sera un ``_inherits`` du modèle Odoo et va ``_inherit`` " +"ce modèle." + +#: ../../../backend_model.pydocstring of +#: connector.backend_model.ExternalBinding:10 +msgid "" +"It will have a relation to the record (via ``_inherits``) and to the " +"concrete backend model (``magento.backend`` for instance)." +msgstr "" +"Il aura une relation vers l'enregistrement (via ``_inherits``) et vers le " +"modèle backend concret (par exemple ``magento.backend``)." + +#: ../../../backend_model.pydocstring of +#: connector.backend_model.ExternalBinding:13 +msgid "" +"It will also contains all the data relative to the backend for the record." +msgstr "" +"Il contiendra également toutes les données relatives aux backend pour " +"l'enregistrement." + +#: ../../../backend_model.pydocstring of +#: connector.backend_model.ExternalBinding:16 +msgid "It needs to implements at least these fields:" +msgstr "Il nécessite d'implémenter au moins ces champs :" + +#: ../../../backend_model.pydocstring of +#: connector.backend_model.ExternalBinding:18 +msgid "odoo_id" +msgstr "odoo_id" + +#: ../../../backend_model.pydocstring of +#: connector.backend_model.ExternalBinding:20 +msgid "The many2one to the record it links (used by ``_inherits``)." +msgstr "Le many2one vers l'enregistrement lié (utilisé par ``_inherits``)." + +#: ../../../backend_model.pydocstring of +#: connector.backend_model.ExternalBinding:22 +msgid "backend_id" +msgstr "backend_id" + +#: ../../../backend_model.pydocstring of +#: connector.backend_model.ExternalBinding:24 +msgid "The many2one to the backend (for instance ``magento.backend``)." +msgstr "Le many2one vers le backend (par exemple ``magento.backend``)." + +#: ../../../backend_model.pydocstring of +#: connector.backend_model.ExternalBinding:26 +msgid "magento_id or prestashop_id or ..." +msgstr "magento_id ou prestashop_id ou ..." + +#: ../../../backend_model.pydocstring of +#: connector.backend_model.ExternalBinding:28 +msgid "The ID on the backend." +msgstr "L'ID sur le backend." + +#: ../../../backend_model.pydocstring of +#: connector.backend_model.ExternalBinding:30 +msgid "sync_date" +msgstr "sync_date" + +#: ../../../backend_model.pydocstring of +#: connector.backend_model.ExternalBinding:32 +msgid "Last date of synchronization" +msgstr "Dernière date de synchronisation" + +#: ../../../backend_model.pydocstring of +#: connector.backend_model.ExternalBinding:35 +msgid "" +"The definition of the relations in ``_columns`` is to be done in the " +"concrete classes because the relations themselves do not exist in this " +"addon." +msgstr "" +"La 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." + +#: ../../../backend_model.pydocstring of +#: connector.backend_model.ExternalBinding:39 +msgid "" +"For example, for a ``res.partner.category`` from Magento, I would have (this" +" is a consolidation of all the columns from the abstract models, in " +"``magentoerpconnect`` you would not find that)::" +msgstr "" +"Par exemple, pour un ``res.partner.category`` depuis Magento, J'aurais (ceci" +" est une consolidation de toutes les colonnes des modèles abstraits. Dans " +"``magentoerpconnect`` vous ne trouveriez pas ça) ::" + +#: ../../api/api_backend_adapter.rst:2 +msgid "Backend Adapter" +msgstr "Adaptateur de backend" + +#: ../../../unit/backend_adapter.pydocstring of +#: connector.unit.backend_adapter.BackendAdapter:1 +#: ../../../connector.pydocstring of connector.connector.Binder:1 +#: ../../../unit/mapper.pydocstring of connector.unit.mapper.MapChild:1 +#: ../../../unit/mapper.pydocstring of connector.unit.mapper.Mapper:1 +#: ../../../unit/synchronizer.pydocstring of +#: connector.unit.synchronizer.Synchronizer:1 +msgid "Bases: :class:`connector.connector.ConnectorUnit`" +msgstr "Bases : :class:`connector.connector.ConnectorUnit`" + +#: ../../../unit/backend_adapter.pydocstring of +#: connector.unit.backend_adapter.BackendAdapter:1 +msgid "Base Backend Adapter for the connectors" +msgstr "Adaptateur de backend de base pour les connecteurs" + +#: ../../../unit/backend_adapter.pydocstring of +#: connector.unit.backend_adapter.CRUDAdapter:1 +msgid "Bases: :class:`connector.unit.backend_adapter.BackendAdapter`" +msgstr "Bases : :class:`connector.unit.backend_adapter.BackendAdapter`" + +#: ../../../unit/backend_adapter.pydocstring of +#: connector.unit.backend_adapter.CRUDAdapter:1 +msgid "" +"Base External Adapter specialized in the handling of records on external " +"systems." +msgstr "" +"Adaptateur externe de base spécialisé dans la gestion des enregistrements " +"des systèmes externes." + +#: ../../../unit/backend_adapter.pydocstring of +#: connector.unit.backend_adapter.CRUDAdapter:4 +msgid "Subclasses can implement their own implementation for the methods." +msgstr "Sous-classes qui ont leur propre implémentation pour les méthodes." + +#: ../../../unit/backend_adapter.pydocstring of +#: connector.unit.backend_adapter.CRUDAdapter.create:1 +msgid "Create a record on the external system" +msgstr "Crée un enregistrement dans le système externe" + +#: ../../../unit/backend_adapter.pydocstring of +#: connector.unit.backend_adapter.CRUDAdapter.delete:1 +msgid "Delete a record on the external system" +msgstr "Supprime un enregistrement sur le système externe" + +#: ../../../unit/backend_adapter.pydocstring of +#: connector.unit.backend_adapter.CRUDAdapter.read:1 +msgid "Returns the information of a record" +msgstr "Renvoie des informations sur l'enregistrement" + +#: ../../../unit/backend_adapter.pydocstring of +#: connector.unit.backend_adapter.CRUDAdapter.search:1 +msgid "Search records according to some criterias and returns a list of ids" +msgstr "" +"Recherche des enregistrements correspondant à certains critères et renvoie " +"une liste d'IDs" + +#: ../../../unit/backend_adapter.pydocstring of +#: connector.unit.backend_adapter.CRUDAdapter.search_read:1 +msgid "" +"Search records according to some criterias and returns their information" +msgstr "" +"Recherche des enregistrements correspondant à certains critères et renvoie " +"leurs données" + +#: ../../../unit/backend_adapter.pydocstring of +#: connector.unit.backend_adapter.CRUDAdapter.write:1 +msgid "Update records on the external system" +msgstr "Met à jour les enregistrements sur le système externe" + +#: ../../api/api_binder.rst:2 +msgid "Binder" +msgstr "Binder (Liant)" + +#: ../../api/api_connector.rst:2 +msgid "Connector" +msgstr "Connecteur" + +#: ../../../connector.pydocstring of connector.connector.Binder:1 +msgid "" +"For one record of a model, capable to find an external or internal id, or " +"create the binding (link) between them" +msgstr "" +"Pour un enregistrement d'un modèle, capable de trouver un ID externe ou " +"interne, ou crée la liaison entre eux" + +#: ../../../connector.pydocstring of connector.connector.Binder:4 +msgid "The Binder should be implemented in the connectors." +msgstr "Le Binder devrait être implémenté dans les connecteurs." + +#: ../../../connector.pydocstring of connector.connector.Binder.bind:1 +msgid "Create the link between an external ID and an Odoo ID" +msgstr "Crée le lien entre un ID externe et un ID Odoo" + +#: ../../../connector.pydocstring of connector.connector.Binder.bind:3 +msgid "external id to bind" +msgstr "ID externe à lier" + +#: ../../../connector.pydocstring of connector.connector.Binder.bind:4 +msgid "Odoo ID to bind" +msgstr "ID Odoo à lier" + +#: ../../../connector.pydocstring of connector.connector.Binder.to_backend:1 +msgid "" +"Give the external ID for an Odoo binding ID (ID in a model magento.*)" +msgstr "" +"Donne l'ID externe pour un ID de liaison Odoo (ID dans un modèle " +"magento.*)" + +#: ../../../connector.pydocstring of connector.connector.Binder.to_backend:4 +msgid "Odoo binding ID for which we want the backend id" +msgstr "ID de liaison Odoo pour lequel on veut l'ID du backend" + +#: ../../../connector.pydocstring of connector.connector.Binder.to_backend:5 +msgid "" +"if False, binding_id is the ID of the binding, if True, binding_id is the ID" +" of the normal record, the method will search the corresponding binding and " +"returns the backend id of the binding" +msgstr "" +"si Faux, binding_id est l'ID de la liaison, si Vrai, binding_id est l'ID de " +"l'enregistrement normal, la méthode va chercher la liaison correspondante et" +" renvoyer l'ID de backend de la liaison." + +#: ../../../connector.pydocstring of connector.connector.Binder.to_backend:9 +msgid "external ID of the record" +msgstr "ID externe de l'enregistrement" + +#: ../../../connector.pydocstring of connector.connector.Binder.to_odoo:1 +msgid "Give the Odoo ID for an external ID" +msgstr "Donne l'ID Odoo pour un ID externe" + +#: ../../../connector.pydocstring of connector.connector.Binder.to_odoo:3 +msgid "external ID for which we want the Odoo ID" +msgstr "ID externe pour lequel on veut l'ID Odoo" + +#: ../../../connector.pydocstring of connector.connector.Binder.to_odoo:5 +msgid "if True, returns the odoo_id else return the id of the binding" +msgstr "si Vrai, renvoie l'odoo_id, sinon renvoie l'ID de la liaison" + +#: ../../../connector.pydocstring of connector.connector.Binder.to_odoo:7 +msgid "if True, returns a recordset" +msgstr "si Vrai, renvoie un `recordset`" + +#: ../../../connector.pydocstring of connector.connector.Binder.to_odoo:8 +msgid "" +"a record ID, depending on the value of unwrap, or None if the external_id is" +" not mapped" +msgstr "" +"un ID d'enregistrement, en fonction de la valeur à déballer, ou None si " +"l'external_id n'est pas mappé" + +#: ../../../connector.pydocstring of +#: connector.connector.Binder.unwrap_binding:1 +msgid "For a binding record, gives the normal record." +msgstr "Pour un enregistrement de liaison, donne l'enregistrement normal" + +#: ../../../connector.pydocstring of +#: connector.connector.Binder.unwrap_binding:3 +msgid "" +"Example: when called with a ``magento.product.product`` id, it will return " +"the corresponding ``product.product`` id." +msgstr "" +"Exemple : si appelé avec un ID de ``magento.product.product``, il va " +"renvoyer l'ID correspondant du ``product.product``." + +#: ../../../connector.pydocstring of +#: connector.connector.Binder.unwrap_binding:6 +msgid "when True, returns a browse_record instance rather than an ID" +msgstr "si Vrai, renvoie une instance de `browse_record` à la place d'un ID" + +#: ../../../connector.pydocstring of connector.connector.Binder.unwrap_model:1 +msgid "For a binding model, gives the normal model." +msgstr "Pour un modèle de liaison, donne le modèle normal." + +#: ../../../connector.pydocstring of connector.connector.Binder.unwrap_model:3 +msgid "" +"Example: when called on a binder for ``magento.product.product``, it will " +"return ``product.product``." +msgstr "" +"Exemple : si appelé sur une binder pour ``magento.product.product``, il va " +"renvoyer ``product.product``." + +#: ../../../connector.pydocstring of +#: connector.connector.ConnectorEnvironment:1 +msgid "Environment used by the different units for the synchronization." +msgstr "" +"Environnement utilisé par les différentes unités pour la synchronisation." + +#: ../../../connector.pydocstring of +#: connector.connector.ConnectorEnvironment:5 +msgid "" +"Current backend we are working with. Obtained with " +"``backend_record.get_backend()``." +msgstr "" +"Backend en cours sur lesquels on travaille. Obtenu avec " +"``backend_record.get_backend()``." + +#: ../../../connector.pydocstring of +#: connector.connector.ConnectorEnvironment:8 +msgid "Instance of: :py:class:`connector.backend.Backend`" +msgstr "Instance de : :py:class:`connector.backend.Backend`" + +#: ../../../connector.pydocstring of +#: connector.connector.ConnectorEnvironment:12 +msgid "" +"Browsable record of the backend. The backend is inherited from the model " +"``connector.backend`` and have at least a ``type`` and a ``version``." +msgstr "" +"Enregistrement de type `browse` pour le backend. Le backend est hérité du " +"modèle ``connector.backend`` et a au moins un ``type`` et une ``version``." + +#: ../../../connector.pydocstring of +#: connector.connector.ConnectorEnvironment:18 +msgid "" +"Current session we are working in. It contains the Odoo cr, uid and " +"context." +msgstr "" +"Session en cours sur laquelle on travaille. Elle contient les ``cr``, " +"``uid`` et ``context`` d'Odoo." + +#: ../../../connector.pydocstring of +#: connector.connector.ConnectorEnvironment:23 +msgid "Name of the Odoo model to work with." +msgstr "Nom du modèle Odoo avec lequel travailler." + +#: ../../../connector.pydocstring of +#: connector.connector.ConnectorEnvironment.get_connector_unit:1 +msgid "" +"Searches and returns an instance of the " +":py:class:`~connector.connector.ConnectorUnit` for the current model and " +"being a class or subclass of ``base_class``." +msgstr "" +"Recherche et renvoie une instance de " +":py:class:`~connector.connector.ConnectorUnit` pour le modèle en cours et " +"étant une classe ou sous-classe de ``base_class``." + +#: ../../../connector.pydocstring of +#: connector.connector.ConnectorEnvironment.get_connector_unit:5 +msgid "The returned instance is built with ``self`` for its environment." +msgstr "" +"L'instance renvoyée est construite avec ``self`` pour son environnement." + +#: ../../../connector.pydocstring of +#: connector.connector.ConnectorEnvironment.get_connector_unit:7 +#: ../../../connector.pydocstring of +#: connector.connector.ConnectorUnit.unit_for:11 +msgid "``ConnectorUnit`` to search (class or subclass)" +msgstr "``ConnectorUnit`` à rechercher (classe ou sous-classe)" + +#: ../../../connector.pydocstring of +#: connector.connector.ConnectorEnvironment.set_lang:1 +msgid "Change the working language in the environment." +msgstr "Change la langue de travail dans l'environnement." + +#: ../../../connector.pydocstring of +#: connector.connector.ConnectorEnvironment.set_lang:3 +msgid "It changes the ``lang`` key in the session's context." +msgstr "Ceci change la clé ``lang`` dans le ``context`` de la session." + +#: ../../../connector.pydocstring of connector.connector.ConnectorUnit:1 +msgid "Abstract class for each piece of the connector:" +msgstr "Classe abstraite pour chaque composant du connecteur :" + +#: ../../../connector.pydocstring of connector.connector.ConnectorUnit:7 +msgid "Examples:" +msgstr "Exemples :" + +#: ../../../connector.pydocstring of connector.connector.ConnectorUnit:4 +msgid ":py:class:`connector.connector.Binder`" +msgstr ":py:class:`connector.connector.Binder`" + +#: ../../../connector.pydocstring of connector.connector.ConnectorUnit:5 +#: ../../../unit/synchronizer.pydocstring of +#: connector.unit.synchronizer.Synchronizer.mapper:6 +msgid ":py:class:`connector.unit.mapper.Mapper`" +msgstr ":py:class:`connector.unit.mapper.Mapper`" + +#: ../../../connector.pydocstring of connector.connector.ConnectorUnit:6 +msgid ":py:class:`connector.unit.synchronizer.Synchronizer`" +msgstr ":py:class:`connector.unit.synchronizer.Synchronizer`" + +#: ../../../connector.pydocstring of connector.connector.ConnectorUnit:7 +#: ../../../unit/synchronizer.pydocstring of +#: connector.unit.synchronizer.Synchronizer.backend_adapter:7 +msgid ":py:class:`connector.unit.backend_adapter.BackendAdapter`" +msgstr ":py:class:`connector.unit.backend_adapter.BackendAdapter`" + +#: ../../../connector.pydocstring of connector.connector.ConnectorUnit:9 +msgid "" +"Or basically any class intended to be registered in a " +":py:class:`~connector.backend.Backend`." +msgstr "" +"Ou en gros n'importe quelle classe destinée à être inscrite dans un " +":py:class:`~connector.backend.Backend`." + +#: ../../../connector.pydocstring of +#: connector.connector.ConnectorUnit.binder_for:1 +#: ../../../connector.pydocstring of +#: connector.connector.ConnectorUnit.get_binder_for_model:1 +msgid "Returns an new instance of the correct ``Binder`` for a model" +msgstr "Renvoie une nouvelle instance du bon ``Binder`` pour un modèle" + +#: ../../../connector.pydocstring of connector.connector.ConnectorUnit.env:1 +msgid "Returns the odoo.api.environment" +msgstr "Renvoie le odoo.api.environment" + +#: ../../../connector.pydocstring of +#: connector.connector.ConnectorUnit.get_binder_for_model:4 +msgid "Deprecated, use ``binder_for`` now." +msgstr "Déprécié, utilisez maintenant ``binder_for``." + +#: ../../../connector.pydocstring of +#: connector.connector.ConnectorUnit.get_connector_unit_for_model:1 +msgid "Deprecated in favor of :meth:`~unit_for`" +msgstr "Déprécié en faveur de :meth:`~unit_for`" + +#: ../../../connector.pydocstring of +#: connector.connector.ConnectorUnit.localcontext:1 +msgid "It is there for compatibility." +msgstr "Présent pour une question de compatibilité." + +#: ../../../connector.pydocstring of +#: connector.connector.ConnectorUnit.localcontext:3 +msgid "" +":func:`odoo.tools.translate._` searches for this attribute in the classes" +" do be able to translate the strings." +msgstr "" +":func:`odoo.tools.translate._` recherche cet attribut dans les classes " +"pour être capable de traduire les chaînes." + +#: ../../../connector.pydocstring of +#: connector.connector.ConnectorUnit.localcontext:6 +msgid "There is no reason to use this attribute for other purposes." +msgstr "Il n'y a aucune raison d'utiliser cet attribut à d'autres fins." + +#: ../../../connector.pydocstring of connector.connector.ConnectorUnit.match:1 +msgid "Returns True if the current class correspond to the searched model." +msgstr "Renvoie True si la classe en cours correspond au modèle recherché" + +#: ../../../connector.pydocstring of connector.connector.ConnectorUnit.match:6 +msgid "model to match" +msgstr "modèle à rechercher" + +#: ../../../connector.pydocstring of +#: connector.connector.ConnectorUnit.unit_for:1 +msgid "" +"According to the current " +":py:class:`~connector.connector.ConnectorEnvironment`, search and returns an" +" instance of the :py:class:`~connector.connector.ConnectorUnit` for the " +"current model and being a class or subclass of ``connector_unit_class``." +msgstr "" +"Selon le :py:class:`~connector.connector.ConnectorEnvironment` en cours, " +"recherche et renvoie une instance de " +":py:class:`~connector.connector.ConnectorUnit` pour le modèle actuel et " +"étant une classe ou sous-classe de ``connector_unit_class``." + +#: ../../../connector.pydocstring of +#: connector.connector.ConnectorUnit.unit_for:7 +msgid "" +"If a different ``model`` is given, a new " +":py:class:`~connector.connector.ConnectorEnvironment` is built for this " +"model." +msgstr "" +"Si un ``model`` différent est donné, un nouveau " +":py:class:`~connector.connector.ConnectorEnvironment` est construit pour ce " +"modèle." + +#: ../../../connector.pydocstring of +#: connector.connector.ConnectorUnit.unit_for:14 +msgid "" +"to give if the ``ConnectorUnit`` is for another model than the current one" +msgstr "" +"à donner si le ``ConnectorUnit`` est pour un autre modèle que le modèle " +"actuel" + +#: ../../../connector.pydocstring of connector.connector.MetaConnectorUnit:1 +msgid "Bases: :class:`type`" +msgstr "Bases : :class:`type`" + +#: ../../../connector.pydocstring of connector.connector.MetaConnectorUnit:1 +msgid "Metaclass for ConnectorUnit." +msgstr "Metaclass pour ConnectorUnit." + +#: ../../../connector.pydocstring of connector.connector.MetaConnectorUnit:3 +msgid "" +"Keeps a ``_module`` attribute on the classes, the same way Odoo does it " +"for the Model classes. It is then used to filter them according to the state" +" of the module (installed or not)." +msgstr "" +"Conserve un attribut ``_module`` sur les classes, de la même façon " +"qu'Odoo pour les classes de modèles. Il est utilisé ensuite pour les " +"filtrer en fonction de l'état du module (installé ou non)." + +#: ../../../connector.pydocstring of +#: connector.connector.MetaConnectorUnit.for_model_names:1 +msgid "" +"Returns the list of models on which a " +":class:`~connector.connector.ConnectorUnit` is usable" +msgstr "" +"Renvoie une liste de modèles sur lesquels une " +":class:`~connector.connector.ConnectorUnit` est utilisable" + +#: ../../../connector.pydocstring of +#: connector.connector.MetaConnectorUnit.for_model_names:4 +msgid "" +"It is used in :meth:`~connector.connector.ConnectorUnit.match` when we " +"search the correct ``ConnectorUnit`` for a model." +msgstr "" +"Utilisé dans :meth:`~connector.connector.ConnectorUnit.match` lorsqu'on " +"recherche la bonne ``ConnectorUnit`` pour un modèle." + +#: ../../../connector.pydocstring of connector.connector.get_odoo_module:1 +msgid "" +"For a top level function or class, returns the name of the Odoo module " +"where it lives." +msgstr "" +"Pour une fonction ou classe de niveau supérieur, renvoie le nom du module " +"Odoo où elle réside." + +#: ../../../connector.pydocstring of connector.connector.get_odoo_module:4 +msgid "" +"So we will be able to filter them according to the modules installation " +"state." +msgstr "" +"Ainsi nous serons capable de les filtrer en fonction de l'état " +"d'installation des modules." + +#: ../../api/api_event.rst:2 +msgid "Event" +msgstr "Événement" + +#: ../../../event.pydocstring of connector.event.Event:1 +msgid "An event contains consumers called when the event is fired." +msgstr "" +"Un événement contient des consommateurs qui sont appelés lorsque l'événement" +" survient." + +#: ../../../event.pydocstring of connector.event.Event:3 +msgid "The events are able to filter the consumers to execute by model name." +msgstr "" +"Les événements sont capables de filtrer par nom de modèle les consommateurs " +"à exécuter." + +#: ../../../event.pydocstring of connector.event.Event:5 +msgid "The usage of an event is to instantiate an `Event` object::" +msgstr "L'usage classique d'un événement est d'instancier un objet `Event` ::" + +#: ../../../event.pydocstring of connector.event.Event:9 +msgid "An event always have at least the 2 following arguments:" +msgstr "Un événement a toujours au moins les deux arguments suivants :" + +#: ../../../event.pydocstring of connector.event.Event:11 +#: ../../../queue/job.pydocstring of connector.queue.job.job:13 +msgid "session" +msgstr "session" + +#: ../../../event.pydocstring of connector.event.Event:12 +#: ../../../queue/job.pydocstring of connector.queue.job.job:16 +msgid "model_name" +msgstr "model_name" + +#: ../../../event.pydocstring of connector.event.Event:40 +msgid "Finally, we fire the event::" +msgstr "Finalement, on déclenche l'événement ::" + +#: ../../../event.pydocstring of connector.event.Event:44 +msgid "A consumer can be subscribed using a decorator::" +msgstr "Un consommateur peut être inscrit grâce à un décorateur ::" + +#: ../../../event.pydocstring of connector.event.Event.fire:1 +msgid "" +"Call each consumer subscribed on the event with the given arguments and " +"keyword arguments." +msgstr "" +"Appelle chaque consommateur inscrit à l'événement avec les arguments " +"positionnels et arguments nommés fournis." + +#: ../../../event.pydocstring of connector.event.Event.fire:4 +msgid "" +"All the consumers which were subscribed globally (no model name) or which " +"are subscribed on the same model" +msgstr "" +"Tous les consommateurs qui sont abonnés de manière globale (sans nom de " +"modèle) ou qui sont abonnés au même modèle" + +#: ../../../event.pydocstring of connector.event.Event.fire:9 +msgid "name of the model" +msgstr "nom du modèle" + +#: ../../../event.pydocstring of connector.event.Event.fire:11 +msgid "" +"arguments propagated to the consumer The second argument of `args` is the " +"model name. The first argument is the session." +msgstr "" +"arguments propagés au consommateur. Le deuxième argument de `args` est le " +"nom de modèle. Le premier argument est la session." + +#: ../../../event.pydocstring of connector.event.Event.fire:14 +msgid "keyword arguments propagated to the consumer" +msgstr "arguments nommés propagés au consommateur" + +#: ../../../event.pydocstring of connector.event.Event.has_consumer_for:1 +msgid "Return True if at least one consumer is registered for the model." +msgstr "Renvoie True si au moins un consommateur est abonné pour ce modèle." + +#: ../../../event.pydocstring of connector.event.Event.subscribe:1 +msgid "Subscribe a consumer on the event" +msgstr "Abonne un consommateur à l'événement" + +#: ../../../event.pydocstring of connector.event.Event.subscribe:3 +msgid "the function to register on the event" +msgstr "la fonction à abonner à l'événement" + +#: ../../../event.pydocstring of connector.event.Event.subscribe:4 +msgid "" +"the consumer will be active only on these models, active on all models if " +"``None``" +msgstr "" +"le consommateur sera actif seulement sur ces modèles ou, si ``None``, actifs" +" sur tous les modèles" + +#: ../../../event.pydocstring of connector.event.Event.subscribe:6 +msgid "the function beeing replaced by this new one." +msgstr "la fonction à remplacer par la nouvelle." + +#: ../../../event.pydocstring of connector.event.Event.unsubscribe:1 +msgid "Remove a consumer from the event" +msgstr "Retire un consommateur d'un événement" + +#: ../../../event.pydocstring of connector.event.Event.unsubscribe:3 +msgid "the function to unsubscribe" +msgstr "la fonction à désinscrire" + +#: ../../../event.pydocstring of connector.event.Event.unsubscribe:4 +msgid "" +"remove only for these models or remove a consumer which is active on all " +"models if ``None``." +msgstr "" +"retire seulement pour ces modèles ou, si ``None``, retire un consommateur " +"qui est actif sur tous les modèles" + +#: ../../../event.pydocstring of connector.event.on_record_create:1 +msgid "``on_record_create`` is fired when one record has been created." +msgstr "``on_record_create`` est déclenché à la création d'un enregistrement." + +#: ../../../event.pydocstring of connector.event.on_record_create:3 +#: ../../../event.pydocstring of connector.event.on_record_unlink:3 +#: ../../../event.pydocstring of connector.event.on_record_write:3 +msgid "Listeners should take the following arguments:" +msgstr "Les abonnés doivent prendre les arguments suivants :" + +#: ../../../event.pydocstring of connector.event.on_record_create:5 +#: ../../../event.pydocstring of connector.event.on_record_unlink:5 +#: ../../../event.pydocstring of connector.event.on_record_write:5 +msgid "session: :py:class:`~connector.session.ConnectorSession` object" +msgstr "session : objet :py:class:`~connector.session.ConnectorSession`" + +#: ../../../event.pydocstring of connector.event.on_record_create:6 +#: ../../../event.pydocstring of connector.event.on_record_unlink:6 +#: ../../../event.pydocstring of connector.event.on_record_write:6 +msgid "model_name: name of the model" +msgstr "model_name : nom du modèle" + +#: ../../../event.pydocstring of connector.event.on_record_create:7 +msgid "record_id: id of the created record" +msgstr "record_id : Id de l'enregistrement créé" + +#: ../../../event.pydocstring of connector.event.on_record_create:8 +msgid "vals: field values updated, e.g {'field_name': field_value, ...}" +msgstr "" +"vals : valeurs des champs mis à jour, par ex. {'field_name': field_value, " +"...}" + +#: ../../../event.pydocstring of connector.event.on_record_unlink:1 +msgid "``on_record_unlink`` is fired when one record has been deleted." +msgstr "" +"``on_record_unlink`` est déclenché à la suppression d'un enregistrement." + +#: ../../../event.pydocstring of connector.event.on_record_unlink:7 +#: ../../../event.pydocstring of connector.event.on_record_write:7 +msgid "record_id: id of the record" +msgstr "record_id : Id de l'enregistrement" + +#: ../../../event.pydocstring of connector.event.on_record_write:1 +msgid "``on_record_write`` is fired when one record has been updated." +msgstr "" +"``on_record_write`` est déclenché à la mise à jour d'un enregistrement." + +#: ../../../event.pydocstring of connector.event.on_record_write:8 +msgid "" +"vals: field values of the new record, e.g {'field_name': field_value, ...}" +msgstr "" +"vals : valeurs des champ pour le nouvel enregistrement, par ex. " +"{'field_name': field_value, ...}" + +#: ../../api/api_exception.rst:2 +msgid "Exceptions" +msgstr "Exceptions" + +#: ../../../exception.pydocstring of connector.exception.ConnectorException:1 +msgid "Bases: :class:`exceptions.RuntimeError`" +msgstr "Bases : :class:`exceptions.RuntimeError`" + +#: ../../../exception.pydocstring of connector.exception.ConnectorException:1 +msgid "Base Exception for the connectors" +msgstr "Exception de base pour les connecteurs" + +#: ../../../exception.pydocstring of connector.exception.FailedJobError:1 +#: ../../../exception.pydocstring of connector.exception.IDMissingInBackend:1 +#: ../../../exception.pydocstring of connector.exception.ManyIDSInBackend:1 +#: ../../../exception.pydocstring of connector.exception.NoSuchJobError:1 +#: ../../../exception.pydocstring of connector.exception.NotReadableJobError:1 +#: ../../../exception.pydocstring of connector.exception.NothingToDoJob:1 +#: ../../../exception.pydocstring of connector.exception.RetryableJobError:1 +msgid "Bases: :class:`connector.exception.JobError`" +msgstr "Bases : :class:`connector.exception.JobError`" + +#: ../../../exception.pydocstring of connector.exception.FailedJobError:1 +msgid "A job had an error having to be resolved." +msgstr "Un job a eu une erreur qui doit être résolue" + +#: ../../../exception.pydocstring of connector.exception.InvalidDataError:1 +#: ../../../exception.pydocstring of connector.exception.JobError:1 +#: ../../../exception.pydocstring of connector.exception.MappingError:1 +#: ../../../exception.pydocstring of +#: connector.exception.NoConnectorUnitError:1 +msgid "Bases: :class:`connector.exception.ConnectorException`" +msgstr "Bases : :class:`connector.exception.ConnectorException`" + +#: ../../../exception.pydocstring of connector.exception.InvalidDataError:1 +msgid "Data Invalid" +msgstr "Donnée incorrecte" + +#: ../../../exception.pydocstring of connector.exception.JobError:1 +msgid "A job had an error" +msgstr "Un job a eu une erreur" + +#: ../../../exception.pydocstring of connector.exception.ManyIDSInBackend:1 +msgid "Unique key exists many times in backend" +msgstr "Une clé unique existe plusieurs fois dans le backend" + +#: ../../../exception.pydocstring of connector.exception.MappingError:1 +msgid "An error occurred during a mapping transformation." +msgstr "Une erreur est survenue pendant une transformation de mapping" + +#: ../../../exception.pydocstring of +#: connector.exception.NetworkRetryableError:1 ../../../exception.pydocstring +#: of connector.exception.NoExternalId:1 +msgid "Bases: :class:`connector.exception.RetryableJobError`" +msgstr "Bases : :class:`connector.exception.RetryableJobError`" + +#: ../../../exception.pydocstring of +#: connector.exception.NetworkRetryableError:1 +msgid "" +"A network error caused the failure of the job, it can be retried later." +msgstr "" +"Une erreur de réseau a causé l'échec du job, il peut être réessayé plus " +"tard." + +#: ../../../exception.pydocstring of +#: connector.exception.NoConnectorUnitError:1 +msgid "No ConnectorUnit has been found" +msgstr "Aucune ConnectorUnit n'a été trouvé" + +#: ../../../exception.pydocstring of connector.exception.NoExternalId:1 +msgid "No External ID found, it can be retried later." +msgstr "Aucun ID Externe trouvé. Peut être réessayé plus tard." + +#: ../../../exception.pydocstring of connector.exception.NoSuchJobError:1 +msgid "The job does not exist." +msgstr "Le job n'existe pas." + +#: ../../../exception.pydocstring of connector.exception.NotReadableJobError:1 +msgid "The job cannot be read from the storage." +msgstr "Le job ne peut pas être lu depuis l'espace de stockage." + +#: ../../../exception.pydocstring of connector.exception.NothingToDoJob:1 +msgid "The Job has nothing to do." +msgstr "Le job n'a rien à faire." + +#: ../../../exception.pydocstring of connector.exception.RetryableJobError:1 +msgid "A job had an error but can be retried." +msgstr "Un job a eu une erreur mais peut être réessayé." + +#: ../../api/api_mapper.rst:2 +msgid "Mapper" +msgstr "Mappeur" + +#: ../../../unit/mapper.pydocstring of connector.unit.mapper:2 +msgid "Mappers" +msgstr "Mappeurs" + +#: ../../../unit/mapper.pydocstring of connector.unit.mapper:4 +msgid "" +"Mappers are the ConnectorUnit classes responsible to transform external " +"records into Odoo records and conversely." +msgstr "" +"Les Mappeurs sont les classes ConnectorUnit responsables de la " +"transformation d'un enregistrement externe vers un enregistrement Odoo et" +" vice versa." + +#: ../../../unit/mapper.pydocstring of connector.unit.mapper.ExportMapChild:1 +#: ../../../unit/mapper.pydocstring of connector.unit.mapper.ImportMapChild:1 +msgid "Bases: :class:`connector.unit.mapper.MapChild`" +msgstr "Bases : :class:`connector.unit.mapper.MapChild`" + +#: ../../../unit/mapper.pydocstring of connector.unit.mapper.ExportMapChild:1 +msgid ":py:class:`MapChild` for the Exports" +msgstr ":py:class:`MapChild` pour les exports" + +#: ../../../unit/mapper.pydocstring of connector.unit.mapper.ExportMapper:1 +#: ../../../unit/mapper.pydocstring of connector.unit.mapper.ImportMapper:1 +msgid "Bases: :class:`connector.unit.mapper.Mapper`" +msgstr "Bases : :class:`connector.unit.mapper.Mapper`" + +#: ../../../unit/mapper.pydocstring of connector.unit.mapper.ExportMapper:1 +msgid ":py:class:`Mapper` for exports." +msgstr ":py:class:`Mapper` pour les exports." + +#: ../../../unit/mapper.pydocstring of connector.unit.mapper.ExportMapper:3 +msgid "Transform a record from Odoo to a backend record" +msgstr "" +"Transforme un enregistrement depuis Odoo vers un enregistrement du " +"backend" + +#: ../../../unit/mapper.pydocstring of connector.unit.mapper.ImportMapChild:1 +msgid ":py:class:`MapChild` for the Imports" +msgstr ":py:class:`MapChild` pour les imports" + +#: ../../../unit/mapper.pydocstring of +#: connector.unit.mapper.ImportMapChild.format_items:1 +#: ../../../unit/mapper.pydocstring of +#: connector.unit.mapper.MapChild.format_items:1 +msgid "Format the values of the items mapped from the child Mappers." +msgstr "Formate les valeurs des items mappés depuis les Mappeurs enfants." + +#: ../../../unit/mapper.pydocstring of +#: connector.unit.mapper.ImportMapChild.format_items:3 +#: ../../../unit/mapper.pydocstring of +#: connector.unit.mapper.MapChild.format_items:3 +msgid "" +"It can be overridden for instance to add the Odoo relationships commands " +"``(6, 0, [IDs])``, ..." +msgstr "" +"Il peut être surchargé par exemple pour ajouter les commandes de relation " +"d'Odoo ``(6, 0, [IDs])``, ..." + +#: ../../../unit/mapper.pydocstring of +#: connector.unit.mapper.ImportMapChild.format_items:6 +#: ../../../unit/mapper.pydocstring of +#: connector.unit.mapper.MapChild.format_items:6 +msgid "" +"As instance, it can be modified to handle update of existing items: check if" +" an 'id' has been defined by :py:meth:`get_item_values` then use the ``(1, " +"ID, {values}``) command" +msgstr "" +"Par exemple, il peut être modifié pour pour gérer la mise à jour d'items " +"existants : vérifier si un 'id' a bien été défini par " +":py:meth:`get_item_values` puis utilise la commande ``(1, ID, {valeurs}``)" + +#: ../../../unit/mapper.pydocstring of +#: connector.unit.mapper.ImportMapChild.format_items:11 +msgid "list of values for the items to create" +msgstr "liste des valeurs pour les items à créer" + +#: ../../../unit/mapper.pydocstring of connector.unit.mapper.ImportMapper:1 +msgid ":py:class:`Mapper` for imports." +msgstr ":py:class:`Mapper` pour les imports." + +#: ../../../unit/mapper.pydocstring of connector.unit.mapper.ImportMapper:3 +msgid "Transform a record from a backend to an Odoo record" +msgstr "" +"Transforme un enregistrement depuis un backend vers un enregistrement " +"Odoo" + +#: ../../../unit/mapper.pydocstring of connector.unit.mapper.MapChild:1 +msgid "MapChild is responsible to convert items." +msgstr "MapChild est responsable de la conversion des items." + +#: ../../../unit/mapper.pydocstring of connector.unit.mapper.MapChild:3 +msgid "" +"Items are sub-records of a main record. In this example, the items are the " +"records in ``lines``::" +msgstr "" +"Les items sont des sous-enregistrements d'un enregistrement principal. Dans " +"cet exemple, les items sont les enregistrements qui sont dans ``lines`` ::" + +#: ../../../unit/mapper.pydocstring of connector.unit.mapper.MapChild:10 +msgid "" +"A MapChild is always called from another :py:class:`Mapper` which provides a" +" ``children`` configuration." +msgstr "" +"Un MapChild est toujours appelé depuis un autre :py:class:`Mapper` qui " +"fournit une configuration ``children``." + +#: ../../../unit/mapper.pydocstring of connector.unit.mapper.MapChild:13 +msgid "" +"Considering the example above, the \"main\" :py:class:`Mapper` would returns" +" something as follows::" +msgstr "" +"Compte tenu de l'exemple ci-dessus, le :py:class:`Mapper` « principal » " +"renverrait quelque chose comme ça ::" + +#: ../../../unit/mapper.pydocstring of connector.unit.mapper.MapChild:20 +msgid "A MapChild is responsible to:" +msgstr "Un MapChild est responsable de :" + +#: ../../../unit/mapper.pydocstring of connector.unit.mapper.MapChild:22 +msgid "Find the :py:class:`Mapper` to convert the items" +msgstr "Trouver le :py:class:`Mapper` pour convertir les items" + +#: ../../../unit/mapper.pydocstring of connector.unit.mapper.MapChild:25 +msgid "Convert the items' records using the found :py:class:`Mapper`" +msgstr "" +"Convertir les enregistrements des items en utilisant le :py:class:`Mapper` " +"trouvé" + +#: ../../../unit/mapper.pydocstring of connector.unit.mapper.MapChild:26 +msgid "" +"Format the output values to the format expected by Odoo or the backend " +"(as seen above with ``(0, 0, {values})``" +msgstr "" +"Formater les valeurs de sortie vers le format attendu par Odoo ou par le " +"backend (comme vu ci-dessus avec ``(0, 0, {values})``" + +#: ../../../unit/mapper.pydocstring of connector.unit.mapper.MapChild:29 +msgid "" +"A MapChild can be extended like any other " +":py:class:`~connector.connector.ConnectorUnit`. However, it is not mandatory" +" to explicitly create a MapChild for each children mapping, the default one " +"will be used (:py:class:`ImportMapChild` or :py:class:`ExportMapChild`)." +msgstr "" +"Un MapChild peut être étendu comme toute autre " +":py:class:`~connector.connector.ConnectorUnit`. Cependant il n'est pas " +"nécessaire de créer un MapChild pour chaque mappeur enfant, ceux par défaut " +"seront utilisés (:py:class:`ImportMapChild` ou :py:class:`ExportMapChild`)." + +#: ../../../unit/mapper.pydocstring of connector.unit.mapper.MapChild:35 +msgid "" +"The implementation by default does not take care of the updates: if I import" +" a sales order 2 times, the lines will be duplicated. This is not a problem " +"as long as an importation should only support the creation (typical for " +"sales orders). It can be implemented on a case-by-case basis by inheriting " +":py:meth:`get_item_values` and :py:meth:`format_items`." +msgstr "" +"L'implémentation par défaut ne gère pas les mises à jour : si j'importe une " +"commande deux fois, les lignes seront dupliquées. Ceci n'est pas un problème" +" à condition qu'un import ne prenne en charge que la création (typique pour" +" les commandes). Il peut être implémenté au cas par cas en héritant de " +":py:meth:`get_item_values` et :py:meth:`format_items`." + +#: ../../../unit/mapper.pydocstring of +#: connector.unit.mapper.MapChild.format_items:11 +msgid "mapped values for the items" +msgstr "valeurs traduites pour les items" + +#: ../../../unit/mapper.pydocstring of +#: connector.unit.mapper.MapChild.get_item_values:1 +msgid "Get the raw values from the child Mappers for the items." +msgstr "Récupère la valeur brute des Mappeurs enfants depuis les items." + +#: ../../../unit/mapper.pydocstring of +#: connector.unit.mapper.MapChild.get_item_values:3 +msgid "It can be overridden for instance to:" +msgstr "I peut être surchargé par exemple pour :" + +#: ../../../unit/mapper.pydocstring of +#: connector.unit.mapper.MapChild.get_item_values:5 +msgid "Change options" +msgstr "Changer des options" + +#: ../../../unit/mapper.pydocstring of +#: connector.unit.mapper.MapChild.get_item_values:6 +msgid "" +"Use a :py:class:`~connector.connector.Binder` to know if an item already " +"exists to modify an existing item, rather than to add it" +msgstr "" +"Utiliser un :py:class:`~connector.connector.Binder` pour savoir si un item " +"existe déjà afin de le modifier au lieu de l'ajouter" + +#: ../../../unit/mapper.pydocstring of +#: connector.unit.mapper.MapChild.get_item_values:10 +#: ../../../unit/mapper.pydocstring of +#: connector.unit.mapper.MapChild.skip_item:7 +msgid "record that we are converting" +msgstr "enregistrement que nous sommes en train de convertir" + +#: ../../../unit/mapper.pydocstring of +#: connector.unit.mapper.MapChild.get_item_values:12 +#: ../../../unit/mapper.pydocstring of +#: connector.unit.mapper.MapChild.get_items:6 +msgid "destination field (can be used for introspecting the relation)" +msgstr "champ destination (peut être utilisé pour inspecter la relation)" + +#: ../../../unit/mapper.pydocstring of +#: connector.unit.mapper.MapChild.get_item_values:15 +#: ../../../unit/mapper.pydocstring of +#: connector.unit.mapper.MapChild.get_items:9 +msgid "dict of options, herited from the main mapper" +msgstr "dictionnaire des options, hérité du mappeur principal" + +#: ../../../unit/mapper.pydocstring of +#: connector.unit.mapper.MapChild.get_items:1 +msgid "Returns the formatted output values of items from a main record" +msgstr "" +"Renvoie la sortie formatée des valeurs des items pour un enregistrement " +"principal" + +#: ../../../unit/mapper.pydocstring of +#: connector.unit.mapper.MapChild.get_items:3 +msgid "list of item records" +msgstr "liste d'enregistrements d'items" + +#: ../../../unit/mapper.pydocstring of +#: connector.unit.mapper.MapChild.get_items:5 +msgid "parent record" +msgstr "enregistrement parent" + +#: ../../../unit/mapper.pydocstring of +#: connector.unit.mapper.MapChild.get_items:10 +msgid "formatted output values for the item" +msgstr "valeurs de sortie formatées pour l'item" + +#: ../../../unit/mapper.pydocstring of +#: connector.unit.mapper.MapChild.skip_item:1 +msgid "" +"Hook to implement in sub-classes when some child records should be skipped." +msgstr "" +"Point d'accroche à implémenter dans les sous-classes lorsque certains " +"enregistrements enfants doivent être sautés." + +#: ../../../unit/mapper.pydocstring of +#: connector.unit.mapper.MapChild.skip_item:4 +msgid "" +"The parent record is accessible in ``map_record``. If it returns True, the " +"current child record is skipped." +msgstr "" +"L'enregistrement parent est accessible dans ``map_record``. S'il renvoie " +"True, l'enregistrement enfant en cours est sauté." + +#: ../../../unit/mapper.pydocstring of connector.unit.mapper.MapOptions:1 +msgid "Bases: :class:`dict`" +msgstr "Bases : :class:`dict`" + +#: ../../../unit/mapper.pydocstring of connector.unit.mapper.MapOptions:1 +msgid "Container for the options of mappings." +msgstr "Conteneur pour les options des mappeurs." + +#: ../../../unit/mapper.pydocstring of connector.unit.mapper.MapOptions:3 +msgid "" +"Options can be accessed using attributes of the instance. When an option is" +" accessed and does not exist, it returns None." +msgstr "" +"Des options peuvent être accédées grâce aux attributs de l'instance. Quand " +"une option est accédée mais n'existe pas, ceci renvoie None." + +#: ../../../unit/mapper.pydocstring of connector.unit.mapper.MapRecord:1 +msgid "A record prepared to be converted using a :py:class:`Mapper`." +msgstr "" +"Un enregistrement préparé à être converti en utilisans un " +":py:class:`Mapper`." + +#: ../../../unit/mapper.pydocstring of connector.unit.mapper.MapRecord:3 +msgid "MapRecord instances are prepared by :py:meth:`Mapper.map_record`." +msgstr "" +"Les instances de MapRecord sont préparées par :py:meth:`Mapper.map_record`." + +#: ../../../unit/mapper.pydocstring of connector.unit.mapper.MapRecord:5 +#: ../../../unit/mapper.pydocstring of +#: connector.unit.mapper.MapRecord.update:3 ../../../unit/mapper.pydocstring +#: of connector.unit.mapper.MapRecord.values:3 +#: ../../../unit/mapper.pydocstring of connector.unit.mapper.changed_by:14 +#: ../../../unit/mapper.pydocstring of connector.unit.mapper.mapping:5 +#: ../../../unit/mapper.pydocstring of connector.unit.mapper.only_create:6 +#: ../../../session.pydocstring of +#: connector.session.ConnectorSessionHandler:16 +msgid "Usage::" +msgstr "Utilisation ::" + +#: ../../../unit/mapper.pydocstring of connector.unit.mapper.MapRecord:11 +msgid "See :py:meth:`values` for more information on the available arguments." +msgstr "" +"Voir :py:meth:`values` pour avoir plus d'informations sur les arguments " +"disponibles." + +#: ../../../unit/mapper.pydocstring of +#: connector.unit.mapper.MapRecord.parent:1 +msgid "Parent record if the current record is an item" +msgstr "Enregistrement parent si l'enregistrement en cours est un item" + +#: ../../../unit/mapper.pydocstring of +#: connector.unit.mapper.MapRecord.source:1 +msgid "Source record to be converted" +msgstr "Enregistrement source à convertir" + +#: ../../../unit/mapper.pydocstring of +#: connector.unit.mapper.MapRecord.update:1 +msgid "Force values to be applied after a mapping." +msgstr "Force des valeurs à appliquer après une conversion." + +#: ../../../unit/mapper.pydocstring of +#: connector.unit.mapper.MapRecord.update:11 +msgid "" +"The values assigned with ``update()`` are in any case applied, they have a " +"greater priority than the mapping values." +msgstr "" +"Les valeurs affectées avec ``update()`` sont appliquées dans tous les cas, " +"elles ont une priorité supérieure que les valeurs converties." + +#: ../../../unit/mapper.pydocstring of +#: connector.unit.mapper.MapRecord.values:1 +msgid "Build and returns the mapped values according to the options." +msgstr "Construit et renvoie les valeurs converties selon les options." + +#: ../../../unit/mapper.pydocstring of +#: connector.unit.mapper.MapRecord.values:15 +msgid "Creation of records" +msgstr "Création des enregistrements" + +#: ../../../unit/mapper.pydocstring of +#: connector.unit.mapper.MapRecord.values:10 +msgid "" +"When using the option ``for_create``, only the mappings decorated with " +"``@only_create`` will be mapped." +msgstr "" +"En utilisant l'option ``for_create``, seuls les mappings décorés avec " +"``@only_create`` seront mappés." + +#: ../../../unit/mapper.pydocstring of +#: connector.unit.mapper.MapRecord.values:24 +msgid "Filter on fields" +msgstr "Filtrer sur les champs" + +#: ../../../unit/mapper.pydocstring of +#: connector.unit.mapper.MapRecord.values:18 +msgid "" +"When using the ``fields`` argument, the mappings will be filtered using " +"either the source key in ``direct`` arguments, either the ``changed_by`` " +"arguments for the mapping methods." +msgstr "" +"En utilisant l'argument ``fields``, les mappings seront filtrés en utilisant" +" soit la clé source dans les arguments ``direct``, soit les arguments " +"``changed_by`` pour les méthodes de mapping." + +#: ../../../unit/mapper.pydocstring of +#: connector.unit.mapper.MapRecord.values:33 +msgid "Custom options" +msgstr "Options spécifiques" + +#: ../../../unit/mapper.pydocstring of +#: connector.unit.mapper.MapRecord.values:27 +msgid "" +"Arbitrary key and values can be defined in the ``kwargs`` arguments. They " +"can later be used in the mapping methods using ``self.options``." +msgstr "" +"Des clé et valeurs arbitraires peuvent être définies dans les arguments " +"``kwargs``. Elles peuvent être ensuites utilisées dans les méthodes de " +"mapping en utilisant ``self.options``." + +#: ../../../unit/mapper.pydocstring of +#: connector.unit.mapper.MapRecord.values:35 +msgid "" +"specify if only the mappings for creation (``@only_create``) should be " +"mapped." +msgstr "" +"précise si seuls les mappings de création (``@only_create``) doivent être " +"mappés." + +#: ../../../unit/mapper.pydocstring of +#: connector.unit.mapper.MapRecord.values:38 +msgid "filter on fields" +msgstr "filtre sur les champs" + +#: ../../../unit/mapper.pydocstring of +#: connector.unit.mapper.MapRecord.values:40 ../../../unit/mapper.pydocstring +#: of connector.unit.mapper.MapRecord.values:40 +msgid "custom options, they can later be used in the mapping methods" +msgstr "" +"options spécifiques, elles peuvent être utilisées plus tard dans les " +"méthodes de mapping" + +#: ../../../unit/mapper.pydocstring of connector.unit.mapper.Mapper:1 +msgid "" +"A Mapper translates an external record to an Odoo record and conversely. " +"The output of a Mapper is a ``dict``." +msgstr "" +"Un Mappeur convertit un enregistrement externe en enregistrement Odoo et " +"vice versa. La sortie d'un Traducteur est un ``dict``." + +#: ../../../unit/mapper.pydocstring of connector.unit.mapper.Mapper:4 +msgid "3 types of mappings are supported:" +msgstr "3 types de mappings sont pris en charge :" + +#: ../../../unit/mapper.pydocstring of connector.unit.mapper.Mapper:55 +msgid "Direct Mappings" +msgstr "Mappings directs" + +#: ../../../unit/mapper.pydocstring of connector.unit.mapper.Mapper:7 +#: ../../../unit/mapper.pydocstring of connector.unit.mapper.backend_to_m2o:10 +#: ../../../unit/mapper.pydocstring of connector.unit.mapper.convert:5 +#: ../../../unit/mapper.pydocstring of connector.unit.mapper.m2o_to_backend:9 +#: ../../../unit/mapper.pydocstring of connector.unit.mapper.none:6 +msgid "Example::" +msgstr "Exemples ::" + +#: ../../../unit/mapper.pydocstring of connector.unit.mapper.Mapper:11 +msgid "Here, the ``source`` field will be copied in the ``target`` field." +msgstr "Ici le champs ``source`` sera copié vers le champ ``target``." + +#: ../../../unit/mapper.pydocstring of connector.unit.mapper.Mapper:13 +msgid "" +"A modifier can be used in the source item. The modifier will be applied to " +"the source field before being copied in the target field. It should be a " +"closure function respecting this idiom::" +msgstr "" +"Un modificateur peut être utilisé dans l'item source. Le modificateur sera " +"appliqué au champ source avant d'être copié dans le champ destination. Il " +"doit être une fonction de type `closure` pour respecter cet idiome ::" + +#: ../../../unit/mapper.pydocstring of connector.unit.mapper.Mapper:27 +#: ../../../unit/mapper.pydocstring of connector.unit.mapper.Mapper:45 +msgid "And used like that::" +msgstr "Et utilisé de cette façon ::" + +#: ../../../unit/mapper.pydocstring of connector.unit.mapper.Mapper:33 +msgid "A more concrete example of modifier::" +msgstr "Un exemple plus concret de modificateur ::" + +#: ../../../unit/mapper.pydocstring of connector.unit.mapper.Mapper:51 +msgid "More examples of modifiers:" +msgstr "D'autres exemples de modificateurs ::" + +#: ../../../unit/mapper.pydocstring of connector.unit.mapper.Mapper:53 +msgid ":py:func:`convert`" +msgstr ":py:func:`convert`" + +#: ../../../unit/mapper.pydocstring of connector.unit.mapper.Mapper:54 +msgid ":py:func:`m2o_to_backend`" +msgstr ":py:func:`m2o_to_backend`" + +#: ../../../unit/mapper.pydocstring of connector.unit.mapper.Mapper:55 +msgid ":py:func:`backend_to_m2o`" +msgstr ":py:func:`backend_to_m2o`" + +#: ../../../unit/mapper.pydocstring of connector.unit.mapper.Mapper:76 +msgid "Method Mappings" +msgstr "Mappings par méthode" + +#: ../../../unit/mapper.pydocstring of connector.unit.mapper.Mapper:58 +msgid "" +"A mapping method allows to execute arbitrary code and return one or many " +"fields::" +msgstr "" +"Un méthode de mapping permet d'exécuter un code arbitraire et de renvoyer un" +" ou plusieurs champs ::" + +#: ../../../unit/mapper.pydocstring of connector.unit.mapper.Mapper:67 +msgid "" +"We can also specify that a mapping methods should be applied only when an " +"object is created, and never applied on further updates::" +msgstr "" +"Nous pouvons aussi préciser qu'une méthode de mapping doit être appliquée " +"lorsqu'un objet est créé, mais jamais appliquée sur les mises à jour " +"ultérieures ::" + +#: ../../../unit/mapper.pydocstring of connector.unit.mapper.Mapper:89 +msgid "Submappings" +msgstr "Sous-mappings" + +#: ../../../unit/mapper.pydocstring of connector.unit.mapper.Mapper:79 +msgid "" +"When a record contains sub-items, like the lines of a sales order, we can " +"convert the children using another Mapper::" +msgstr "" +"Lorsqu'un enregistrement contient des sous-items, comme les lignes d'une " +"commande, nous pouvons convertir les enfants grâce à une autre Mappeur ::" + +#: ../../../unit/mapper.pydocstring of connector.unit.mapper.Mapper:84 +msgid "" +"It allows to create the sales order and all its lines with the same call to " +":py:meth:`odoo.models.BaseModel.create()`." +msgstr "" +"Il permet de créer des commandes et toutes ses lignes dans le même appel à " +":py:meth:`odoo.models.BaseModel.create()`." + +#: ../../../unit/mapper.pydocstring of connector.unit.mapper.Mapper:87 +msgid "" +"When using ``children`` for items of a record, we need to create a " +":py:class:`Mapper` for the model of the items, and optionally a " +":py:class:`MapChild`." +msgstr "" +"En utilisant des ``children`` pour les items d'un enregistrement, nous " +"devons créer un :py:class:`Mapper` pour le modèle des items, et de manière " +"optionnelle un :py:class:`MapChild`." + +#: ../../../unit/mapper.pydocstring of connector.unit.mapper.Mapper:91 +msgid "Usage of a Mapper::" +msgstr "Utilisation d'un Mappeur ::" + +#: ../../../unit/mapper.pydocstring of connector.unit.mapper.Mapper.finalize:1 +msgid "Called at the end of the mapping." +msgstr "Appelé à la fin du mapping." + +#: ../../../unit/mapper.pydocstring of connector.unit.mapper.Mapper.finalize:3 +msgid "" +"Can be used to modify the values before returning them, as the " +"``on_change``." +msgstr "" +"Peut être utilisé pour modifier les valeurs avant de les renvoyer, comme le " +"``on_change``." + +#: ../../../unit/mapper.pydocstring of connector.unit.mapper.Mapper.finalize:6 +msgid "source map_record" +msgstr "map_record source" + +#: ../../../unit/mapper.pydocstring of connector.unit.mapper.Mapper.finalize:8 +#: ../../../unit/mapper.pydocstring of connector.unit.mapper.Mapper.finalize:9 +msgid "mapped values" +msgstr "valeurs mappées" + +#: ../../../unit/mapper.pydocstring of +#: connector.unit.mapper.Mapper.map_methods:1 +msgid "Yield all the methods decorated with ``@mapping``" +msgstr "Émets toutes les méthodes décorées avec ``@mapping``" + +#: ../../../unit/mapper.pydocstring of +#: connector.unit.mapper.Mapper.map_record:1 +msgid "" +"Get a :py:class:`MapRecord` with record, ready to be converted using the " +"current Mapper." +msgstr "" +"Récupère un :py:class:`MapRecord` avec enregistrement, prêt à être converti " +"avec le Mappeur en cours." + +#: ../../../unit/mapper.pydocstring of +#: connector.unit.mapper.Mapper.map_record:4 +msgid "record to transform" +msgstr "enregistrement à transformer" + +#: ../../../unit/mapper.pydocstring of +#: connector.unit.mapper.Mapper.map_record:5 +msgid "optional parent record, for items" +msgstr "enregistrement parent optionnel, pour les items" + +#: ../../../unit/mapper.pydocstring of connector.unit.mapper.Mapper.options:1 +msgid "Options can be accessed in the mapping methods with ``self.options``." +msgstr "" +"Des options peuvent être accédées dans les méthodes de mapping avec " +"``self.options``." + +#: ../../../unit/mapper.pydocstring of +#: connector.unit.mapper.MappingDefinition:1 +msgid "Bases: :class:`tuple`" +msgstr "Bases : :class:`tuple`" + +#: ../../../unit/mapper.pydocstring of +#: connector.unit.mapper.MappingDefinition.changed_by:1 +msgid "Alias for field number 0" +msgstr "Alias pour le champ numéro 0" + +#: ../../../unit/mapper.pydocstring of +#: connector.unit.mapper.MappingDefinition.only_create:1 +msgid "Alias for field number 1" +msgstr "Alias pour le champs numéro 1" + +#: ../../../unit/mapper.pydocstring of connector.unit.mapper.MetaMapper:1 +msgid "Bases: :class:`connector.connector.MetaConnectorUnit`" +msgstr "Bases : :class:`connector.connector.MetaConnectorUnit`" + +#: ../../../unit/mapper.pydocstring of connector.unit.mapper.MetaMapper:1 +msgid "Metaclass for Mapper" +msgstr "Metaclass pour Mappeur" + +#: ../../../unit/mapper.pydocstring of connector.unit.mapper.MetaMapper:3 +msgid "" +"Build a ``_map_methods`` dict of mappings methods. The keys of the dict are " +"the method names. The values of the dict are a namedtuple containing:" +msgstr "" +"construit un dict ``_map_methods`` des méthodes de mapping. Les clés de ce " +"dict sont les noms de méthode. Les valeurs sont des `namedtuple` contenant :" + +#: ../../../unit/mapper.pydocstring of connector.unit.mapper.backend_to_m2o:1 +#: ../../../unit/mapper.pydocstring of connector.unit.mapper.convert:1 +#: ../../../unit/mapper.pydocstring of connector.unit.mapper.m2o_to_backend:1 +#: ../../../unit/mapper.pydocstring of connector.unit.mapper.none:1 +msgid "A modifier intended to be used on the ``direct`` mappings." +msgstr "Un modificateur destiné à être utilisé sur les mapping ``directs``" + +#: ../../../unit/mapper.pydocstring of connector.unit.mapper.backend_to_m2o:3 +msgid "" +"For a field from a backend which is an ID, search the corresponding binding " +"in Odoo and returns its ID." +msgstr "" +"Pour un champ d'un backend qui est un ID, recherche le binding correspondant" +" dans Odoo et renvoie son ID." + +#: ../../../unit/mapper.pydocstring of connector.unit.mapper.backend_to_m2o:6 +#: ../../../unit/mapper.pydocstring of connector.unit.mapper.m2o_to_backend:5 +msgid "" +"When the field's relation is not a binding (i.e. it does not point to " +"something like ``magento.*``), the binding model needs to be provided in the" +" ``binding`` keyword argument." +msgstr "" +"Quand la relation du champ n'est pas un binding (càd ne pointe pas vers " +"quelque chose comme ``magento.*``), le modèle de liaison doit être fourni " +"avec l'argument nommé ``binding``." + +#: ../../../unit/mapper.pydocstring of connector.unit.mapper.backend_to_m2o:16 +#: ../../../unit/mapper.pydocstring of connector.unit.mapper.convert:9 +#: ../../../unit/mapper.pydocstring of connector.unit.mapper.m2o_to_backend:15 +#: ../../../unit/mapper.pydocstring of connector.unit.mapper.none:11 +msgid "name of the source field in the record" +msgstr "nom du champ source dans l'enregistrement" + +#: ../../../unit/mapper.pydocstring of connector.unit.mapper.backend_to_m2o:17 +#: ../../../unit/mapper.pydocstring of connector.unit.mapper.m2o_to_backend:16 +msgid "name of the binding model is the relation is not a binding" +msgstr "nom du modèle de liaison si la relation n'est pas une liaison" + +#: ../../../unit/mapper.pydocstring of connector.unit.mapper.backend_to_m2o:18 +msgid "include the inactive records in Odoo in the search" +msgstr "inclut les enregistrements inactifs d'Odoo dans la recherche" + +#: ../../../unit/mapper.pydocstring of connector.unit.mapper.changed_by:1 +#: ../../../unit/mapper.pydocstring of connector.unit.mapper.only_create:1 +msgid "Decorator for the mapping methods (:py:func:`mapping`)" +msgstr "Décorateur pour les méthodes de mapping (:py:func:`mapping`)" + +#: ../../../unit/mapper.pydocstring of connector.unit.mapper.changed_by:3 +msgid "" +"When fields are modified in Odoo, we want to export only the modified " +"fields. Using this decorator, we can specify which fields updates should " +"trigger which mapping method." +msgstr "" +"Lorsque des champs sont modifié dans Odoo, nous ne devrions exporter que " +"les champs modifiés. En utilisant ce décorateur, nous pouvons préciser " +"quelles modifications de champs doivent déclencher quelle méthode de " +"mapping." + +#: ../../../unit/mapper.pydocstring of connector.unit.mapper.changed_by:7 +msgid "If ``changed_by`` is empty, the mapping is always active." +msgstr "Si ``changed_by`` est vide, le mapping est toujours actif." + +#: ../../../unit/mapper.pydocstring of connector.unit.mapper.changed_by:9 +msgid "" +"As far as possible, this decorator should be used for the exports, thus, " +"when we do an update on only a small number of fields on a record, the size " +"of the output record will be limited to only the fields really having to be " +"exported." +msgstr "" +"Autant que possible, ce décorateur devrait être utilisé pour les exports. De" +" cette façon lorsqu'on fait une modification sur une petite partie des " +"champs d'un enregistrement, la taille de l'enregistrement en sortie sera " +"limitée aux seuls champs devant être exportés." + +#: ../../../unit/mapper.pydocstring of connector.unit.mapper.changed_by:21 +#: ../../../unit/mapper.pydocstring of connector.unit.mapper.changed_by:21 +msgid "field names which trigger the mapping when modified" +msgstr "noms de champs qui déclenchent le mapping à la modification" + +#: ../../../unit/mapper.pydocstring of connector.unit.mapper.convert:3 +msgid "Convert a field's value to a given type." +msgstr "Convertit une valeur de champ vers un type donné" + +#: ../../../unit/mapper.pydocstring of connector.unit.mapper.convert:10 +#: ../../../unit/mapper.pydocstring of connector.unit.mapper.none:12 +msgid "True if the relation is a binding record" +msgstr "True si la relation est un enregistrement de binding" + +#: ../../../unit/mapper.pydocstring of connector.unit.mapper.m2o_to_backend:3 +msgid "For a many2one, get the ID on the backend and returns it." +msgstr "Pour un many2one, récupère l'ID depuis le backend et le renvoie." + +#: ../../../unit/mapper.pydocstring of connector.unit.mapper.mapping:1 +msgid "Declare that a method is a mapping method." +msgstr "Déclare qu'une méthode est une méthode de mapping." + +#: ../../../unit/mapper.pydocstring of connector.unit.mapper.mapping:3 +msgid "It is then used by the :py:class:`Mapper` to convert the records." +msgstr "" +"C'est ensuite utilisé par le :py:class:`Mapper` pour convertir les " +"enregistrements." + +#: ../../../unit/mapper.pydocstring of connector.unit.mapper.none:3 +msgid "" +"Replace the False-ish values by None. It can be used in a pipeline of " +"modifiers when ." +msgstr "" +"Remplace les valeurs similaires à False par None. Ceci peut être utilisé " +"dans un enchaînement de modificateurs quand ." + +#: ../../../unit/mapper.pydocstring of connector.unit.mapper.only_create:3 +msgid "" +"A mapping decorated with ``only_create`` means that it has to be used only " +"for the creation of the records." +msgstr "" +"Un mapping décoré avec ``only_create`` indique qu'il doit être utilisé " +"uniquement pour a création d'enregistrements." + +#: ../../api/api_queue.rst:3 ../../api/api_queue.rst:25 +msgid "Queue" +msgstr "Queue" + +#: ../../api/api_queue.rst:7 +msgid "Job" +msgstr "Job" + +#: ../../../queue/job.pydocstring of connector.queue.job.Job:1 +msgid "A Job is a task to execute." +msgstr "Un job est une tâche à exécuter." + +#: ../../../queue/job.pydocstring of connector.queue.job.Job:5 +msgid "Id (UUID) of the job." +msgstr "Id (UUID) du job." + +#: ../../../queue/job.pydocstring of connector.queue.job.Job:9 +msgid "When the job is enqueued, UUID of the worker." +msgstr "Quand le job est placé dans la queue, UUID du worker." + +#: ../../../queue/job.pydocstring of connector.queue.job.Job:13 +msgid "" +"State of the job, can pending, enqueued, started, done or failed. The start " +"state is pending and the final state is done." +msgstr "" +"État du job, peut être en attente, en queue, démarré, terminé, échoué. " +"L'état initial est `en attente` et l'état final est `terminé`." + +#: ../../../queue/job.pydocstring of connector.queue.job.Job:18 +msgid "" +"The current try, starts at 0 and each time the job is executed, it increases" +" by 1." +msgstr "" +"L'essai actuel, démarre à 0 et s'incrémente de 1 chaque fois que le job est " +"exécuté." + +#: ../../../queue/job.pydocstring of connector.queue.job.Job:23 +msgid "" +"The maximum number of retries allowed before the job is considered as " +"failed." +msgstr "" +"Le nombre maximum d'essais permis avant que le job soit considéré comme " +"échoué." + +#: ../../../queue/job.pydocstring of connector.queue.job.Job:28 +msgid "Name of the function (in the form module.function_name)." +msgstr "Nom de la fonction (sous la forme module.nom_fonction)." + +#: ../../../queue/job.pydocstring of connector.queue.job.Job:32 +msgid "Arguments passed to the function when executed." +msgstr "Arguments transmis à la fonction pendant l'exécution." + +#: ../../../queue/job.pydocstring of connector.queue.job.Job:36 +msgid "Keyword arguments passed to the function when executed." +msgstr "Arguments nommés transmis à la fonction pendant l'exécution." + +#: ../../../queue/job.pydocstring of connector.queue.job.Job:40 +msgid "" +"Full string representing the function to be executed, ie. " +"module.function(args, kwargs)" +msgstr "" +"Chaîne complète représentant la fonction à exécuter, càd " +"module.fonction(args, kwargs)" + +#: ../../../queue/job.pydocstring of connector.queue.job.Job:45 +msgid "Human description of the job." +msgstr "Description du job à destination des utilisateurs." + +#: ../../../queue/job.pydocstring of connector.queue.job.Job:49 +msgid "The python function itself." +msgstr "La fonction Python elle-même." + +#: ../../../queue/job.pydocstring of connector.queue.job.Job:53 +msgid "Odoo model on which the job will run." +msgstr "Modèle Odoo pour lequel le job va fonctionner." + +#: ../../../queue/job.pydocstring of connector.queue.job.Job:57 +msgid "Priority of the job, 0 being the higher priority." +msgstr "Priorité du job, 0 étant la plus haute priorité." + +#: ../../../queue/job.pydocstring of connector.queue.job.Job:61 +msgid "Date and time when the job was created." +msgstr "Date et heure de création du job." + +#: ../../../queue/job.pydocstring of connector.queue.job.Job:65 +msgid "Date and time when the job was enqueued." +msgstr "Date et heure de mise en queue du job." + +#: ../../../queue/job.pydocstring of connector.queue.job.Job:69 +msgid "Date and time when the job was started." +msgstr "Date et heure de démarrage du job." + +#: ../../../queue/job.pydocstring of connector.queue.job.Job:73 +msgid "Date and time when the job was done." +msgstr "Date et heure d'arrêt du job." + +#: ../../../queue/job.pydocstring of connector.queue.job.Job:77 +msgid "A description of the result (for humans)." +msgstr "Une description du résultat (à destination des utilisateurs)." + +#: ../../../queue/job.pydocstring of connector.queue.job.Job:81 +msgid "Exception information (traceback) when the job failed." +msgstr "" +"Informations sur l'`Exception` (`traceback') ayant causé l'échec du job" + +#: ../../../queue/job.pydocstring of connector.queue.job.Job:85 +msgid "Odoo user id which created the job" +msgstr "Id de l'utilisateur Odoo qui a créé le job" + +#: ../../../queue/job.pydocstring of connector.queue.job.Job:89 +msgid "" +"Estimated Time of Arrival of the job. It will not be executed before this " +"date/time." +msgstr "" +"Heure estimée de lancement (ETA) du job. Il ne sera pas exécuté avant cette " +"date/heure." + +#: ../../../queue/job.pydocstring of connector.queue.job.Job:94 +msgid "True if the job has been canceled." +msgstr "True si le job a été annulé." + +#: ../../../queue/job.pydocstring of connector.queue.job.Job.perform:1 +msgid "Execute the job." +msgstr "Exécute le job." + +#: ../../../queue/job.pydocstring of connector.queue.job.Job.perform:3 +msgid "The job is executed with the user which has initiated it." +msgstr "Le job est exécuté avec l'utilisateur qui l'a initié." + +#: ../../../queue/job.pydocstring of connector.queue.job.Job.perform:5 +msgid "session to execute the job" +msgstr "session d'exécution du job" + +#: ../../../queue/job.pydocstring of connector.queue.job.Job.postpone:1 +msgid "" +"Write an estimated time arrival to n seconds later than now. Used when an " +"retryable exception want to retry a job later." +msgstr "" +"Écrit un heure estimée de lancement dans `n` secondes. Utilisé quand une " +"`Exception` non fatale souhaite relancer un job." + +#: ../../../queue/job.pydocstring of connector.queue.job.Job.uuid:1 +msgid "Job ID, this is an UUID" +msgstr "Id du job, c'est un UUID" + +#: ../../../queue/job.pydocstring of connector.queue.job.JobStorage:1 +msgid "Interface for the storage of jobs" +msgstr "Interface pour le stockage des jobs" + +#: ../../../queue/job.pydocstring of connector.queue.job.JobStorage.exists:1 +#: ../../../queue/job.pydocstring of +#: connector.queue.job.OdooJobStorage.exists:1 +msgid "Returns if a job still exists in the storage." +msgstr "Indique si un job existe encore dans l'espace de stockage." + +#: ../../../queue/job.pydocstring of connector.queue.job.JobStorage.load:1 +msgid "Read the job's data from the storage" +msgstr "Lit les donnés du job dans l'espace de stockage" + +#: ../../../queue/job.pydocstring of connector.queue.job.JobStorage.store:1 +msgid "Store a job" +msgstr "Stocke un job" + +#: ../../../queue/job.pydocstring of connector.queue.job.OdooJobStorage:1 +msgid "Bases: :class:`connector.queue.job.JobStorage`" +msgstr "Bases : :class:`connector.queue.job.JobStorage`" + +#: ../../../queue/job.pydocstring of connector.queue.job.OdooJobStorage:1 +msgid "Store a job on Odoo" +msgstr "Stocke un job dans Odoo" + +#: ../../../queue/job.pydocstring of +#: connector.queue.job.OdooJobStorage.enqueue:1 +#: ../../../queue/job.pydocstring of +#: connector.queue.job.OdooJobStorage.enqueue_resolve_args:1 +msgid "Create a Job and enqueue it in the queue. Return the job uuid." +msgstr "Crée un job et le met en queue. Renvoie le UUID du job." + +#: ../../../queue/job.pydocstring of +#: connector.queue.job.OdooJobStorage.enqueue:3 +msgid "" +"This expects the arguments specific to the job to be already extracted from " +"the ones to pass to the job function." +msgstr "" +"S'attend à ce que les arguments spécifiques au job soient déjà extraites de " +"ceux à passer à la fonction du job." + +#: ../../../queue/job.pydocstring of +#: connector.queue.job.OdooJobStorage.load:1 +msgid "Read a job from the Database" +msgstr "Lit un job depuis la base de données" + +#: ../../../queue/job.pydocstring of +#: connector.queue.job.OdooJobStorage.store:1 +msgid "Store the Job" +msgstr "Stocke le job" + +#: ../../../queue/job.pydocstring of connector.queue.job.job:1 +msgid "Decorator for jobs." +msgstr "Décorateur pour les jobs." + +#: ../../../queue/job.pydocstring of connector.queue.job.job:3 +msgid "Add a ``delay`` attribute on the decorated function." +msgstr "Ajoute un attribut ``delay`` sur la fonction décorée." + +#: ../../../queue/job.pydocstring of connector.queue.job.job:5 +msgid "" +"When ``delay`` is called, the function is transformed to a job and stored in" +" the Odoo queue.job model. The arguments and keyword arguments given in " +"``delay`` will be the arguments used by the decorated function when it is " +"executed." +msgstr "" +"Quand ``delay`` est appelée, la fonction est transformée en job et stockée " +"dans le modèle Odoo queue.job. Les arguments positionnels et nommés " +"transmis à ``delay`` seront les arguments utilisés par la fonction décorée " +"lorsqu'elle sera exécutée." + +#: ../../../queue/job.pydocstring of connector.queue.job.job:10 +msgid "The ``delay()`` function of a job takes the following arguments:" +msgstr "La fonction ``delay()`` d'un job reçoit les arguments suivants :" + +#: ../../../queue/job.pydocstring of connector.queue.job.job:13 +msgid "Current :py:class:`~odoo.addons.connector.session.ConnectorSession`" +msgstr "" +":py:class:`~odoo.addons.connector.session.ConnectorSession` en cours" + +#: ../../../queue/job.pydocstring of connector.queue.job.job:16 +msgid "name of the model on which the job has something to do" +msgstr "nom du modèle sur lequel le job a quelque chose à faire" + +#: ../../../queue/job.pydocstring of connector.queue.job.job:57 +msgid "*args and **kargs" +msgstr "*args et **kargs" + +#: ../../../queue/job.pydocstring of connector.queue.job.job:19 +msgid "" +"Arguments and keyword arguments which will be given to the called function " +"once the job is executed. They should be ``pickle-able``." +msgstr "" +"Arguments positionnels et nommés qui seront transmis à la fonction une fois " +"que le job est exécuté. Ils doivent être « pickle-able »." + +#: ../../../queue/job.pydocstring of connector.queue.job.job:22 +msgid "There is 4 special and reserved keyword arguments that you can use:" +msgstr "" +"Il existe 4 arguments nommés spéciaux et réservés que vous pouvez utiliser :" + +#: ../../../queue/job.pydocstring of connector.queue.job.job:24 +msgid "priority: priority of the job, the smaller is the higher priority." +msgstr "priority : priorité du job, une valeur plus petite étant prioritaire." + +#: ../../../queue/job.pydocstring of connector.queue.job.job:25 +msgid "Default is 10." +msgstr "10 par défaut." + +#: ../../../queue/job.pydocstring of connector.queue.job.job:27 +msgid "max_retries: maximum number of retries before giving up and set" +msgstr "max_retries : nombre maximal d'essais avant d'abandonner et définir" + +#: ../../../queue/job.pydocstring of connector.queue.job.job:27 +msgid "" +"the job state to 'failed'. A value of 0 means infinite retries. Default is " +"5." +msgstr "" +"l'état du job à `échoué`. Une valeur de 0 signifie un nombre infini " +"d'essais. Par défaut la valeur est 5." + +#: ../../../queue/job.pydocstring of connector.queue.job.job:30 +msgid "eta: the job can be executed only after this datetime" +msgstr "eta : le job ne peut être exécuté qu'après cette `datetime`" + +#: ../../../queue/job.pydocstring of connector.queue.job.job:30 +msgid "(or now + timedelta if a timedelta or integer is given)" +msgstr "" +"(ou maintenant + `timedelta` si un `timedelta` ou un entier est fourni)" + +#: ../../../queue/job.pydocstring of connector.queue.job.job:35 +msgid "description : a human description of the job," +msgstr "description : une description à destination des utilisateurs," + +#: ../../../queue/job.pydocstring of connector.queue.job.job:33 +msgid "intended to discriminate job instances (Default is the func.__doc__ or" +msgstr "" +"destinée à différencier les instances de job (Par défaut func.__doc__ ou" + +#: ../../../queue/job.pydocstring of connector.queue.job.job:35 +msgid "'Function %s' % func.__name__)" +msgstr "'Function %s' % func.__name__)" + +#: ../../../queue/job.pydocstring of connector.queue.job.job:37 +msgid "Example:" +msgstr "Exemple :" + +#: ../../../queue/job.pydocstring of connector.queue.job.job:57 +msgid "" +"See also: :py:func:`related_action` a related action can be attached to a " +"job" +msgstr "" +"Voir aussi : :py:func:`related_action` une action connexe peut être attachée" +" à un job" + +#: ../../../queue/job.pydocstring of connector.queue.job.related_action:1 +msgid "Attach a *Related Action* to a job." +msgstr "Attache une *action connexe* à un job" + +#: ../../../queue/job.pydocstring of connector.queue.job.related_action:3 +msgid "" +"A *Related Action* will appear as a button on the Odoo view. The button " +"will execute the action, usually it will open the form view of the record " +"related to the job." +msgstr "" +"Un *action connexe* apparaîtra comme un bouton dans la vue Odoo. Le " +"bouton exécutera l'action, habituellement une ouverture de formulaire de " +"l'enregistrement lié au job." + +#: ../../../queue/job.pydocstring of connector.queue.job.related_action:7 +msgid "The ``action`` must be a callable that responds to arguments::" +msgstr "" +"L'``action`` doit être un objet `callable` qui prends les arguments ::" + +#: ../../../queue/job.pydocstring of connector.queue.job.related_action:11 +msgid "Example usage:" +msgstr "Exemple d'utilisation :" + +#: ../../../queue/job.pydocstring of connector.queue.job.related_action:34 +msgid "The kwargs are transmitted to the action:" +msgstr "Les ``kwargs`` sont transmis à l'action :" + +#: ../../api/api_queue.rst:16 ../../../queue/model.pydocstring of +#: connector.queue.model.QueueWorker:1 +msgid "Worker" +msgstr "Worker" + +#: ../../../queue/worker.pydocstring of connector.queue.worker.Worker:1 +#: ../../../queue/worker.pydocstring of connector.queue.worker.WorkerWatcher:1 +msgid "Bases: :class:`threading.Thread`" +msgstr "Bases : :class:`threading.Thread`" + +#: ../../../queue/worker.pydocstring of connector.queue.worker.Worker:1 +msgid "Post and retrieve jobs from the queue, execute them" +msgstr "Poste et récupère des jobs de la queue, les exécute" + +#: ../../../queue/worker.pydocstring of +#: connector.queue.worker.Worker.enqueue_job_uuid:1 +msgid "Enqueue a job:" +msgstr "Met un job en queue :" + +#: ../../../queue/worker.pydocstring of +#: connector.queue.worker.Worker.enqueue_job_uuid:3 +msgid "" +"It will be executed by the worker as soon as possible (according to the " +"job's priority" +msgstr "" +"Il sera exécuté par le worker aussi tôt que possible (en fonction de la " +"priorité du job)" + +#: ../../../queue/worker.pydocstring of connector.queue.worker.Worker.run:1 +msgid "Worker's main loop" +msgstr "Boucle principale du worker" + +#: ../../../queue/worker.pydocstring of connector.queue.worker.Worker.run:3 +msgid "" +"Check if it still exists in the ``watcher``. When it does no longer exist, " +"it break the loop so the thread stops properly." +msgstr "" +"Vérifie s'il existe encore dans le ``watcher``. Quand il n'existe plus, il " +"sort de la boucle de façon que le `thread` s'arrête proprement." + +#: ../../../queue/worker.pydocstring of connector.queue.worker.Worker.run:6 +msgid "Wait for jobs and execute them sequentially." +msgstr "Attend les jobs et les exécute séquentiellement." + +#: ../../../queue/worker.pydocstring of +#: connector.queue.worker.Worker.run_job:1 +msgid "Execute a job" +msgstr "Exécute un job" + +#: ../../../queue/worker.pydocstring of connector.queue.worker.WorkerWatcher:1 +msgid "Keep a sight on the workers and signal their aliveness." +msgstr "Garde un œil sur les workers et signale leur changement d'état." + +#: ../../../queue/worker.pydocstring of connector.queue.worker.WorkerWatcher:3 +msgid "" +"A `WorkerWatcher` is shared between databases, so only 1 instance is " +"necessary to check the aliveness of the workers for every database." +msgstr "" +"Un `WorkerWatcher` est partagé entre plusieurs bases de données, donc seule " +"une instance est nécessaire pour vérifier l'état des workers pour chaque " +"base de données." + +#: ../../../queue/worker.pydocstring of +#: connector.queue.worker.WorkerWatcher.available_db_names:1 +msgid "" +"Returns the databases for the server having the connector module installed." +msgstr "" +"Renvoie les bases de données du serveur où le module `connector` est " +"installé" + +#: ../../../queue/worker.pydocstring of +#: connector.queue.worker.WorkerWatcher.available_db_names:4 +msgid "Available means that they can be used by a `Worker`." +msgstr "Disponible signifie qu'elles peuvent être utilisées par un `Worker`." + +#: ../../../queue/worker.pydocstring of +#: connector.queue.worker.WorkerWatcher.available_db_names:6 +msgid "database names" +msgstr "Noms des bases de données" + +#: ../../../queue/worker.pydocstring of +#: connector.queue.worker.WorkerWatcher.check_alive:1 +msgid "" +"Check if the the worker is still alive and notify its aliveness. Check if " +"the other workers are still alive, if they are dead, remove them from the " +"worker's pool." +msgstr "" +"Vérifie si le worker est toujours vivant et signale son état. Vérifie si les" +" autres workers sont toujours vivants, et si ce n'est pas le cas, les retire" +" du pool de workers." + +#: ../../../queue/worker.pydocstring of +#: connector.queue.worker.WorkerWatcher.run:1 +msgid "`WorkerWatcher`'s main loop" +msgstr "boucle principale du `WorkerWatcher`" + +#: ../../../queue/worker.pydocstring of +#: connector.queue.worker.WorkerWatcher.worker_lost:1 +msgid "Indicate if a worker is no longer referenced by the watcher." +msgstr "Indique si un worker n'est plus référencé par l'observateur." + +#: ../../../queue/worker.pydocstring of +#: connector.queue.worker.WorkerWatcher.worker_lost:3 +msgid "Used by the worker threads to know if they have to exit." +msgstr "" +"Utilisé par les `threads` de worker pour savoir s'ils doivent s'arrêter." + +#: ../../../queue/worker.pydocstring of connector.queue.worker.start_service:1 +msgid "Start the watcher" +msgstr "Démarre l'observateur" + +#: ../../../queue/queue.pydocstring of connector.queue.queue.JobsQueue:1 +msgid "Holds the jobs planned for execution in memory." +msgstr "Contient en mémoire les jobs dont l'exécution est planifiée." + +#: ../../../queue/queue.pydocstring of connector.queue.queue.JobsQueue:3 +msgid "" +"The Jobs are sorted, the higher the priority is, the earlier the jobs are " +"dequeued." +msgstr "" +"Les jobs sont triés, plus la priorité est importante, plus tôt les jobs sont" +" dépilés de la queue." + +#: ../../../queue/queue.pydocstring of +#: connector.queue.queue.JobsQueue.dequeue:1 +msgid "Take the first job according to its priority and return it" +msgstr "Dépile et renvoie le premier job en fonction de sa priorité" + +#: ../../api/api_queue.rst:34 +msgid "Models" +msgstr "Modèles" + +#: ../../../queue/model.pydocstring of connector.queue.model.QueueJob:1 +#: ../../../queue/model.pydocstring of connector.queue.model.QueueWorker:1 +msgid "Bases: :class:`odoo.models.Model`" +msgstr "Bases : :class:`odoo.models.Model`" + +#: ../../../queue/model.pydocstring of connector.queue.model.QueueJob:1 +msgid "Job status and result" +msgstr "État du job et résultat" + +#: ../../../queue/model.pydocstring of +#: connector.queue.model.QueueJob.autovacuum:1 +msgid "" +"Delete all jobs (active or not) done since more than ``_removal_interval`` " +"days." +msgstr "" +"Efface tous les jobs (actifs ou non) qui sont terminés depuis plus de " +"``_removal_interval`` jours." + +#: ../../../queue/model.pydocstring of +#: connector.queue.model.QueueJob.autovacuum:4 +msgid "Called from a cron." +msgstr "Appelé depuis une tâche planifiée (`cron`)." + +#: ../../../queue/model.pydocstring of +#: connector.queue.model.QueueJob.company_id:1 +#: ../../../queue/model.pydocstring of +#: connector.queue.model.QueueJob.user_id:1 ../../../queue/model.pydocstring +#: of connector.queue.model.QueueJob.worker_id:1 +msgid "" +"The value of such a field is a recordset of size 0 (no record) or 1 (a " +"single record)." +msgstr "" +"La valeur d'un tel champ est un `recordset` de taille 0 (pas " +"d'enregistrement) ou 1 (enregistrement unique)." + +#: ../../../queue/model.pydocstring of +#: connector.queue.model.QueueJob.company_id:4 +#: ../../../queue/model.pydocstring of +#: connector.queue.model.QueueJob.user_id:4 ../../../queue/model.pydocstring +#: of connector.queue.model.QueueJob.worker_id:4 +#: ../../../queue/model.pydocstring of +#: connector.queue.model.QueueWorker.job_ids:5 +#: ../../../queue/model.pydocstring of +#: connector.queue.model.RequeueJob.job_ids:3 +msgid "name of the target model (string)" +msgstr "nom du modèle cible (chaîne de caractères)" + +#: ../../../queue/model.pydocstring of +#: connector.queue.model.QueueJob.company_id:6 +#: ../../../queue/model.pydocstring of +#: connector.queue.model.QueueJob.user_id:6 ../../../queue/model.pydocstring +#: of connector.queue.model.QueueJob.worker_id:6 +#: ../../../queue/model.pydocstring of +#: connector.queue.model.QueueWorker.job_ids:10 +#: ../../../queue/model.pydocstring of +#: connector.queue.model.RequeueJob.job_ids:21 +msgid "" +"an optional domain to set on candidate values on the client side (domain or " +"string)" +msgstr "" +"un `domain` optionnel à définir sur les valeurs candidates côté client " +"(`domain` ou `string`)" + +#: ../../../queue/model.pydocstring of +#: connector.queue.model.QueueJob.company_id:9 +#: ../../../queue/model.pydocstring of +#: connector.queue.model.QueueJob.user_id:9 ../../../queue/model.pydocstring +#: of connector.queue.model.QueueJob.worker_id:9 +#: ../../../queue/model.pydocstring of +#: connector.queue.model.QueueWorker.job_ids:13 +#: ../../../queue/model.pydocstring of +#: connector.queue.model.RequeueJob.job_ids:24 +msgid "" +"an optional context to use on the client side when handling that field " +"(dictionary)" +msgstr "" +"un `context` optionnel à utiliser côté client à la prise en charge de ce " +"champ (dictionnaire)" + +#: ../../../queue/model.pydocstring of +#: connector.queue.model.QueueJob.company_id:12 +#: ../../../queue/model.pydocstring of +#: connector.queue.model.QueueJob.user_id:12 ../../../queue/model.pydocstring +#: of connector.queue.model.QueueJob.worker_id:12 +msgid "" +"what to do when the referred record is deleted; possible values are: ``'set " +"null'``, ``'restrict'``, ``'cascade'``" +msgstr "" +"quoi faire quand l'enregistrement en rapport est effacé ; les valeurs " +"possibles sont : ``'set null'``, ``'restrict'``, ``'cascade'``" + +#: ../../../queue/model.pydocstring of +#: connector.queue.model.QueueJob.company_id:15 +#: ../../../queue/model.pydocstring of +#: connector.queue.model.QueueJob.user_id:15 ../../../queue/model.pydocstring +#: of connector.queue.model.QueueJob.worker_id:15 +#: ../../../queue/model.pydocstring of +#: connector.queue.model.QueueWorker.job_ids:16 +msgid "" +"whether JOINs are generated upon search through that field (boolean, by " +"default ``False``)" +msgstr "" +"si les JOINs sont générés lors de la recherche sur ce champ (booleen, par " +"défaut ``False``)" + +#: ../../../queue/model.pydocstring of +#: connector.queue.model.QueueJob.company_id:18 +#: ../../../queue/model.pydocstring of +#: connector.queue.model.QueueJob.user_id:18 ../../../queue/model.pydocstring +#: of connector.queue.model.QueueJob.worker_id:18 +msgid "" +"set it to ``True`` to make fields of the target model accessible from the " +"current model (corresponds to ``_inherits``)" +msgstr "" +"définir à ``True`` pour rendre les champs du modèle cible accessibles depuis" +" le modèle en cours (correspond à ``_inherits``)" + +#: ../../../queue/model.pydocstring of +#: connector.queue.model.QueueJob.company_id:21 +#: ../../../queue/model.pydocstring of +#: connector.queue.model.QueueJob.user_id:21 ../../../queue/model.pydocstring +#: of connector.queue.model.QueueJob.worker_id:21 +#: ../../../queue/model.pydocstring of +#: connector.queue.model.RequeueJob.job_ids:5 +msgid "" +"The attribute `comodel_name` is mandatory except in the case of related " +"fields or field extensions." +msgstr "" +"L'attribut `comodel_name` est obligatoire sauf dans le cas des champs " +"`related` ou des extensions de champs." + +#: ../../../queue/model.pydocstring of +#: connector.queue.model.QueueJob.exc_info:1 ../../../queue/model.pydocstring +#: of connector.queue.model.QueueJob.result:1 +msgid "" +"Very similar to :class:`~.Char` but used for longer contents, does not have " +"a size and usually displayed as a multiline text box." +msgstr "" +"Très similaire à :class:`~.Char` mais utilisé pour des contenus plus longs, " +"sans taille spécifiée et généralement affiché dans une boite de texte multi-" +"lignes." + +#: ../../../queue/model.pydocstring of +#: connector.queue.model.QueueJob.exc_info:4 ../../../queue/model.pydocstring +#: of connector.queue.model.QueueJob.result:4 +msgid "whether the value of this field can be translated" +msgstr "si la valeur de ce champ peut être traduite ou non" + +#: ../../../queue/model.pydocstring of +#: connector.queue.model.QueueJob.open_related_action:1 +msgid "Open the related action associated to the job" +msgstr "Ouvre l'action associée au job" + +#: ../../../queue/model.pydocstring of +#: connector.queue.model.QueueWorker.assign_jobs:1 +msgid "Assign ``n`` jobs to the worker of the current process" +msgstr "Affecte ``n`` jobs au worker du processus en cours" + +#: ../../../queue/model.pydocstring of +#: connector.queue.model.QueueWorker.assign_jobs:3 +msgid "``n`` is ``max_jobs`` or unlimited if ``max_jobs`` is None" +msgstr "``n`` est ``max_jobs`` ou illimité si ``max_jobs`` est None" + +#: ../../../queue/model.pydocstring of +#: connector.queue.model.QueueWorker.assign_jobs:5 +#: ../../../queue/model.pydocstring of +#: connector.queue.model.QueueWorker.assign_then_enqueue:11 +msgid "maximal limit of jobs to assign on a worker" +msgstr "nombre maximal de jobs à affecter à un worker" + +#: ../../../queue/model.pydocstring of +#: connector.queue.model.QueueWorker.assign_then_enqueue:1 +msgid "" +"Assign all the jobs not already assigned to a worker. Then enqueue all the " +"jobs having a worker but not enqueued." +msgstr "" +"Affecte tous les jobs non encore affectés à un worker. Puis met en queue " +"tous les jobs qui ont un worker mais qui ne sont pas dans la queue." + +#: ../../../queue/model.pydocstring of +#: connector.queue.model.QueueWorker.assign_then_enqueue:4 +msgid "Each operation is atomic." +msgstr "Chaque opération est atomique." + +#: ../../../queue/model.pydocstring of +#: connector.queue.model.QueueWorker.assign_then_enqueue:6 +msgid "" +"commit transaction ``cr.commit()`` is called, so please always call this " +"method in your own transaction, not in the main Odoo's transaction" +msgstr "" +"valide la transaction. ``cr.commit()`` est appelé, donc veuillez appeler " +"cette méthode dans vos propres transactions, pas dans la transaction " +"principale d'Odoo" + +#: ../../../queue/model.pydocstring of +#: connector.queue.model.QueueWorker.enqueue_jobs:1 +msgid "Enqueue all the jobs assigned to the worker of the current process" +msgstr "Met en queue tous les jobs affectés au worker du processus en cours" + +#: ../../../queue/model.pydocstring of +#: connector.queue.model.QueueWorker.job_ids:1 +msgid "" +"One2many field; the value of such a field is the recordset of all the " +"records in `comodel_name` such that the field `inverse_name` is equal to the" +" current record." +msgstr "" +"Champ one2many ; la valeur d'un tel champ est le `recordset` de tous les " +"enregistrements dans `comodel_name` de sorte que le champ `inverse_name` " +"soit égal à l'enregistrement actuel." + +#: ../../../queue/model.pydocstring of +#: connector.queue.model.QueueWorker.job_ids:7 +msgid "name of the inverse `Many2one` field in `comodel_name` (string)" +msgstr "nom du champ `many2one` réciproque côté `comodel_name` (string)" + +#: ../../../queue/model.pydocstring of +#: connector.queue.model.QueueWorker.job_ids:19 +#: ../../../queue/model.pydocstring of +#: connector.queue.model.RequeueJob.job_ids:27 +msgid "optional limit to use upon read (integer)" +msgstr "limite optionnelle à utiliser à la lecture (entier)" + +#: ../../../queue/model.pydocstring of +#: connector.queue.model.QueueWorker.job_ids:21 +msgid "" +"The attributes `comodel_name` and `inverse_name` are mandatory except in the" +" case of related fields or field extensions." +msgstr "" +"Les attributs `comodel_name` et `inverse_name` sont obligatoires sauf dans " +"les cas des champs `related` ou des extensions de champs." + +#: ../../../queue/model.pydocstring of connector.queue.model.RequeueJob:1 +msgid "Bases: :class:`odoo.models.TransientModel`" +msgstr "Bases : :class:`odoo.models.TransientModel`" + +#: ../../../queue/model.pydocstring of +#: connector.queue.model.RequeueJob.job_ids:1 +msgid "Many2many field; the value of such a field is the recordset." +msgstr "Champ many2many ; la valeur d'un tel champ est un `recordset`." + +#: ../../../queue/model.pydocstring of +#: connector.queue.model.RequeueJob.job_ids:8 +msgid "" +"optional name of the table that stores the relation in the database (string)" +msgstr "" +"nom optionnel de la table qui stocke la relation dans la base de données " +"(string)" + +#: ../../../queue/model.pydocstring of +#: connector.queue.model.RequeueJob.job_ids:11 +msgid "" +"optional name of the column referring to \"these\" records in the table " +"`relation` (string)" +msgstr "" +"nom optionnel de la colonne qui se réfère à \"ces\" enregistrements dans la " +"table `relation` (string)" + +#: ../../../queue/model.pydocstring of +#: connector.queue.model.RequeueJob.job_ids:14 +msgid "" +"optional name of the column referring to \"those\" records in the table " +"`relation` (string)" +msgstr "" +"nom optionnel de la colonne qui se réfère à \"ces\" enregistrements dans la " +"table `relation` (string)" + +#: ../../../queue/model.pydocstring of +#: connector.queue.model.RequeueJob.job_ids:17 +msgid "" +"The attributes `relation`, `column1` and `column2` are optional. If not " +"given, names are automatically generated from model names, provided " +"`model_name` and `comodel_name` are different!" +msgstr "" +"Les attributs `relation`, `column1` et `column2` sont optionnels. S'ils ne " +"sont pas fournis, des noms sont générés automatiquement depuis les noms de " +"modèles, à condition que `model_name` et `comodel_name` soient differents !" + +#: ../../api/api_session.rst:2 +msgid "Session" +msgstr "Session" + +#: ../../../session.pydocstring of connector.session.ConnectorSession:1 +msgid "Container for the Odoo transactional stuff:" +msgstr "Conteneur pour les choses transactionnelles d'Odoo :" + +#: ../../../session.pydocstring of connector.session.ConnectorSession:5 +msgid "The Environment" +msgstr "L'Environnement" + +#: ../../../session.pydocstring of connector.session.ConnectorSession:9 +msgid "The Odoo Cursor" +msgstr "Le curseur d'Odoo" + +#: ../../../session.pydocstring of connector.session.ConnectorSession:13 +#: ../../../session.pydocstring of +#: connector.session.ConnectorSessionHandler:10 +msgid "The User ID as integer" +msgstr "L'ID de l'utilisateur (entier)" + +#: ../../../session.pydocstring of connector.session.ConnectorSession:17 +msgid "The registry of models" +msgstr "Le registre des modèles" + +#: ../../../session.pydocstring of connector.session.ConnectorSession:21 +#: ../../../session.pydocstring of +#: connector.session.ConnectorSessionHandler:14 +msgid "The current Odoo's context" +msgstr "Le `context` actuel d'Odoo" + +#: ../../../session.pydocstring of connector.session.ConnectorSession.browse:1 +msgid "Shortcut to :py:class:`odoo.models.BaseModel.browse`" +msgstr "Raccourci vers :py:class:`odoo.models.BaseModel.browse`" + +#: ../../../session.pydocstring of +#: connector.session.ConnectorSession.change_context:1 +msgid "Context Manager: create a new Env with an updated context" +msgstr "`Context Manager` : crée un nouvel Env avec un `context` mis à jour" + +#: ../../../session.pydocstring of +#: connector.session.ConnectorSession.change_context:3 +msgid "" +"It generates a new :class:`odoo.api.Environment` used within the context " +"manager, where the context is extended with the arguments. The original " +"environment is restored at the closing of the context manager." +msgstr "" +"Génère un nouvel :class:`odoo.api.Environment` utilisé à l'intérieur du " +"`context manager`, où le `context` est enrichi avec les arguments. " +"L'environnement original est restauré à la fermeture du `context manager`." + +#: ../../../session.pydocstring of +#: connector.session.ConnectorSession.change_context:8 +msgid "" +"The extended context is either the provided ``context`` in which " +"``overrides`` are merged or the *current* context in which ``overrides`` are" +" merged e.g." +msgstr "" +"Le `context` enrichi est soit le ``context`` fourni, dans lequel les " +"``overrides`` sont fusionnés, ou le `context` *actuel* dans lequel les " +"``overrides`` sont fusionné, càd" + +#: ../../../session.pydocstring of +#: connector.session.ConnectorSession.change_context:20 +#: ../../../session.pydocstring of +#: connector.session.ConnectorSession.change_user:8 +msgid "" +"only recordsets read within the context manager will be attached to this " +"environment. In many cases, you will prefer to use " +":meth:`odoo.models.BaseModel.with_context`" +msgstr "" +"seuls les `recordset` lus à l'intérieur du `context manager` seront attachés" +" à cet environnement. Dans beaucoup de cas, vous préférerez utiliser " +":meth:`odoo.models.BaseModel.with_context`" + +#: ../../../session.pydocstring of +#: connector.session.ConnectorSession.change_user:1 +msgid "Context Manager: create a new Env with the specified user" +msgstr "`Context Manager` : crée un nouvel Env avec l'utilisateur spécifié" + +#: ../../../session.pydocstring of +#: connector.session.ConnectorSession.change_user:3 +msgid "" +"It generates a new :class:`odoo.api.Environment` used within the context " +"manager, where the user is replaced by the specified one. The original " +"environment is restored at the closing of the context manager." +msgstr "" +"Ceci génère un nouvel :class:`odoo.api.Environment` utilisé à l'intérieur" +" du `context manager`, où l'utilisateur est remplacé par celui spécifié. " +"L'environnement original est restaré à la fermeture du `context manager`." + +#: ../../../session.pydocstring of connector.session.ConnectorSession.close:1 +msgid "Close the cursor" +msgstr "Ferme le curseur" + +#: ../../../session.pydocstring of connector.session.ConnectorSession.commit:1 +msgid "Commit the cursor" +msgstr "Valide la transaction" + +#: ../../../session.pydocstring of connector.session.ConnectorSession.create:1 +msgid "Shortcut to :py:class:`odoo.models.BaseModel.create`" +msgstr "Raccourci pour :py:class:`odoo.models.BaseModel.create`" + +#: ../../../session.pydocstring of +#: connector.session.ConnectorSession.is_module_installed:1 +msgid "" +"Indicates whether a module is installed or not on the current database." +msgstr "" +"Indique si un module est installé ou non dans la base de données en cours." + +#: ../../../session.pydocstring of +#: connector.session.ConnectorSession.is_module_installed:4 +msgid "" +"Use a convention established for the connectors addons: To know if a module " +"is installed, it looks if an (abstract) model with name " +"``module_name.installed`` is loaded in the registry." +msgstr "" +"Utilise une convention établie pour les modules connecteurs : pour savoir si" +" un module est installé, il regarde si un modèle (abstrait) avec le nom " +"``nom_module.installed`` est chargé dans le registre." + +#: ../../../session.pydocstring of connector.session.ConnectorSession.read:1 +msgid "Shortcut to :py:class:`odoo.models.BaseModel.read`" +msgstr "Raccourci pour :py:class:`odoo.models.BaseModel.read`" + +#: ../../../session.pydocstring of +#: connector.session.ConnectorSession.rollback:1 +msgid "Rollback the cursor" +msgstr "Annule la transaction" + +#: ../../../session.pydocstring of connector.session.ConnectorSession.search:1 +msgid "Shortcut to :py:class:`odoo.models.BaseModel.search`" +msgstr "Raccourci pour :py:class:`odoo.models.BaseModel.search`" + +#: ../../../session.pydocstring of connector.session.ConnectorSession.write:1 +msgid "Shortcut to :py:class:`odoo.models.BaseModel.write`" +msgstr "Raccourci pour :py:class:`odoo.models.BaseModel.write`" + +#: ../../../session.pydocstring of connector.session.ConnectorSessionHandler:1 +msgid "" +"Allow to create a new instance of " +":py:class:`~connector.session.ConnectorSession` for a database." +msgstr "" +"Permet de créer une nouvelle instance de " +":py:class:`~connector.session.ConnectorSession` pour une base de données." + +#: ../../../session.pydocstring of connector.session.ConnectorSessionHandler:6 +msgid "The name of the database we're working on" +msgstr "Le nom de la base de données sur laquelle on travaille" + +#: ../../../session.pydocstring of +#: connector.session.ConnectorSessionHandler.session:1 +msgid "" +"Context Manager: start a new session and ensure that the session's cursor " +"is:" +msgstr "" +"`Context Manager` : démarre une nouvelle session et s'assure que le curseur " +"de la session est :" + +#: ../../../session.pydocstring of +#: connector.session.ConnectorSessionHandler.session:4 +msgid "rollbacked on errors" +msgstr "annulé en cas d'erreur" + +#: ../../../session.pydocstring of +#: connector.session.ConnectorSessionHandler.session:5 +msgid "commited at the end of the ``with`` context when no error occured" +msgstr "validé à la fin du contexte ``with`` si aucune erreur n'est apparue" + +#: ../../../session.pydocstring of +#: connector.session.ConnectorSessionHandler.session:6 +msgid "always closed at the end of the ``with`` context" +msgstr "toujours fermé à la fin d'un contexte ``with``" + +#: ../../../session.pydocstring of +#: connector.session.ConnectorSessionHandler.session:7 +msgid "it handles the registry signaling" +msgstr "il gère le signalement du registre" + +#: ../../api/api_synchronizer.rst:2 +msgid "Synchronizer" +msgstr "Synchroniseur" + +#: ../../../unit/synchronizer.pydocstring of +#: connector.unit.synchronizer.Deleter:1 +#: ../../../unit/synchronizer.pydocstring of +#: connector.unit.synchronizer.Exporter:1 +#: ../../../unit/synchronizer.pydocstring of +#: connector.unit.synchronizer.Importer:1 +msgid "Bases: :class:`connector.unit.synchronizer.Synchronizer`" +msgstr "Bases : :class:`connector.unit.synchronizer.Synchronizer`" + +#: ../../../unit/synchronizer.pydocstring of +#: connector.unit.synchronizer.Deleter:1 +msgid "Synchronizer for deleting a record on the backend" +msgstr "Synchroniseur pour effacer un enregistrement du backend" + +#: ../../../unit/synchronizer.pydocstring of +#: connector.unit.synchronizer.Exporter:1 +msgid "Synchronizer for exporting data from Odoo to a backend" +msgstr "Synchroniseur pour exporter des donnés d'Odoo vers un backend" + +#: ../../../unit/synchronizer.pydocstring of +#: connector.unit.synchronizer.Importer:1 +msgid "Synchronizer for importing data from a backend to Odoo" +msgstr "Synchroniseur pour importer des données d'un backend vers Odoo" + +#: ../../../unit/synchronizer.pydocstring of +#: connector.unit.synchronizer.Synchronizer:1 +msgid "Base class for synchronizers" +msgstr "Classe de base des synchroniseurs" + +#: ../../../unit/synchronizer.pydocstring of +#: connector.unit.synchronizer.Synchronizer.backend_adapter:1 +msgid "Return an instance of ``BackendAdapter`` for the synchronization." +msgstr "Renvoie une instance de ``BackendAdapter`` pour la synchronisation." + +#: ../../../unit/synchronizer.pydocstring of +#: connector.unit.synchronizer.Synchronizer.backend_adapter:4 +#: ../../../unit/synchronizer.pydocstring of +#: connector.unit.synchronizer.Synchronizer.binder:3 +#: ../../../unit/synchronizer.pydocstring of +#: connector.unit.synchronizer.Synchronizer.mapper:3 +msgid "" +"The instanciation is delayed because some synchronisations do not need such " +"an unit and the unit may not exist." +msgstr "" +"L'instanciation est retardée parce que certaines synchronisations n'ont pas " +"besoin d'une telle unité et celle-ci peut ne pas exister." + +#: ../../../unit/synchronizer.pydocstring of +#: connector.unit.synchronizer.Synchronizer.binder:1 +msgid "Return an instance of ``Binder`` for the synchronization." +msgstr "Renvoie une instance de liaison ``Binder`` pour la synchronisation." + +#: ../../../unit/synchronizer.pydocstring of +#: connector.unit.synchronizer.Synchronizer.binder:6 +msgid ":py:class:`connector.unit.binder.Binder`" +msgstr ":py:class:`connector.unit.binder.Binder`" + +#: ../../../unit/synchronizer.pydocstring of +#: connector.unit.synchronizer.Synchronizer.mapper:1 +msgid "Return an instance of ``Mapper`` for the synchronization." +msgstr "Renvoie une instance de mappeur ``Mapper`` pour la synchronisation" + +#: ../../../unit/synchronizer.pydocstring of +#: connector.unit.synchronizer.Synchronizer.run:1 +msgid "Run the synchronization" +msgstr "Lance la synchronisation" + +#: ../../../event.pydocstring of connector.event.Event:14 +msgid "Then to subscribe one or more consumers, an event has a function::" +msgstr "" +"Ensuite pour abonner un ou plusieurs consommateurs, un événement a une " +"fonction :" + +#: ../../../exception.pydocstring of connector.exception.IDMissingInBackend:1 +msgid "The ID does not exist in the backend" +msgstr "L'ID n'existe pas dans le backend" + +#: ../../../unit/mapper.pydocstring of connector.unit.mapper.MapChild:23 +msgid "" +"Possibly filter out some lines (can be done by inheriting " +":py:meth:`skip_item`)" +msgstr "" +"Éventuellement exclure certaines lignes (en surchargeant " +":py:meth:`skip_item`)" + +#: ../../../event.pydocstring of connector.event.Event:30 +msgid "We can also replace a consumer::" +msgstr "On peut aussi remplacer un consommateur ::" + +#~ msgid "We can also replace an consumer::" +#~ msgstr "On peut aussi remplacer un consommateur ::" + +#~ msgid "int" +#~ msgstr "int" + +#~ msgid "dict" +#~ msgstr "dict" + +#~ msgid "MappingDefinition(changed_by, only_create)" +#~ msgstr "MappingDefinition(changed_by, only_create)" + +#~ msgid "list" +#~ msgstr "list" + +#~ msgid "The ID of does not exist in the backend" +#~ msgstr "L'ID " + +#~ msgid "Then to subscribe one or more consumers, a consumer is a function::" +#~ msgstr "" +#~ "Ensuite pour abonner un ou plusieurs consommateurs, un événement a une " +#~ "fonction ``subscribe`` ::" + +#~ msgid "We can also replace an event::" +#~ msgstr "On peut également remplacer un consommateur ::" diff --git a/ext/3rd-party-addons/connector/doc/locale/fr/LC_MESSAGES/guides.po b/ext/3rd-party-addons/connector/doc/locale/fr/LC_MESSAGES/guides.po new file mode 100644 index 00000000..d81fe834 --- /dev/null +++ b/ext/3rd-party-addons/connector/doc/locale/fr/LC_MESSAGES/guides.po @@ -0,0 +1,1214 @@ +# +msgid "" +msgstr "" +"Project-Id-Version: Connector\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2015-04-15 22:28+0300\n" +"PO-Revision-Date: 2015-05-05 11:55+0100\n" +"Last-Translator: Guewen Baconnier \n" +"Language-Team: fr \n" +"Language: fr\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Generator: Poedit 1.5.4\n" + +#: ../../guides/bootstrap_connector.rst:6 +msgid "Boostrapping a connector" +msgstr "Amorcer la création un nouveau connecteur" + +#: ../../guides/bootstrap_connector.rst:8 +msgid "We'll see the steps to bootstrap a new connector." +msgstr "" +"Nous allons voir les étapes pour amorcer la création d'un nouveau connecteur" + +#: ../../guides/bootstrap_connector.rst:10 +msgid "" +"Besides that, you may want to use the existing connectors to have some real " +"implementation examples:" +msgstr "" +"À côté de ça, vous devriez utiliser les connecteurs existants pour avoir des " +"exemples réels d'implémentation:" + +#: ../../guides/bootstrap_connector.rst:16 +msgid "" +"Some boilerplate is necessary, so this document will guide you through some " +"steps. Please also take a look on the :ref:`naming-convention`." +msgstr "" +"Du code boilerplate est nécessaire, donc ce document va vous guider à " +"travers différentes étapes. Consultez également les :ref:`naming-convention`." + +#: ../../guides/bootstrap_connector.rst:59 +msgid "Nothing special but 2 things to note:" +msgstr "Il y a 2 points à noter :" + +#: ../../guides/bootstrap_connector.rst:61 +msgid "It depends from ``connector``." +msgstr "Il dépend de ``connector``." + +#: ../../guides/bootstrap_connector.rst:62 +msgid "The module category should be ``Connector``." +msgstr "La catégorie du module doit être ``Connector``." + +#: ../../guides/bootstrap_connector.rst:64 +msgid "" +"Of course, we also need to create the ``__init__.py`` file where we will put " +"the imports of our python modules." +msgstr "" +"Bien sûr, nous devons aussi créer le fichier ``__init__.py`` où nous plaçons " +"les imports de nos modules Python." + +#: ../../guides/bootstrap_connector.rst:70 +msgid "Install the module in the connector" +msgstr "Installation du module dans le connecteur" + +#: ../../guides/bootstrap_connector.rst:72 +msgid "" +"Each new module needs to be plugged in the connector's framework. That's " +"just a matter of following a convention and creating ``connector_coffee/" +"connector.py``" +msgstr "" +"Chaque nouveau module doit être branché dans le framework du connecteur. " +"C'est juste un question de suivre une convention et créer un fichier " +"``connector_coffee/connector.py``" + +#: ../../guides/bootstrap_connector.rst:82 +msgid "" +"If you miss this line of code, your ConnectorUnit classes won't be found." +msgstr "" +"Si vous oubliez cette ligne de code, vos classes ConnectorUnit seront " +"introuvables." + +#: ../../guides/bootstrap_connector.rst:90 +msgid "" +"To prevent this, we use a little trick: create an abstract model and look in " +"the registry if it is loaded." +msgstr "" +"Pour éviter cela, nous utilisons une astuce: créer un « abstract model » et " +"regarder dans le registre s'il est chargé." + +#: ../../guides/bootstrap_connector.rst:96 +msgid "Declare the backends" +msgstr "Déclaration des backends" + +#: ../../guides/bootstrap_connector.rst:98 +msgid "Our module is compatible with the coffee machines:" +msgstr "Notre module est compatible avec les machines à café :" + +#: ../../guides/bootstrap_connector.rst:100 +msgid "Coffee 1900" +msgstr "Coffee 1900" + +#: ../../guides/bootstrap_connector.rst:101 +msgid "Coffee 2900" +msgstr "Coffee 2900" + +#: ../../guides/bootstrap_connector.rst:103 +msgid "" +"So we'll declare a backend `coffee`, the generic entity, and a backend per " +"version." +msgstr "" +"Donc nous allons déclarer un backend `coffee`, l'entité générique, et un " +"backend différent par version." + +#: ../../guides/bootstrap_connector.rst:106 +msgid "Put this in ``connector_coffee/backend.py``::" +msgstr "Placez ceci dans ``connector_coffee/backend.py``::" + +#: ../../guides/bootstrap_connector.rst:118 +msgid "Backend Model" +msgstr "Modèle du backend" + +#: ../../guides/bootstrap_connector.rst:120 +msgid "We declared the backends, but we need a model to configure them." +msgstr "" +"Nous avons déclaré les backends, mais nous avons besoin d'un modèle pour les " +"configurer." + +#: ../../guides/bootstrap_connector.rst:122 +msgid "" +"We create a model ``coffee.backend`` which is an ``_inherit`` of ``connector." +"backend``. In ``connector_coffee/coffee_model.py``::" +msgstr "" +"Nous créons un modèle ``coffee.backend`` qui est un ``_inherit`` de " +"``connector.backend``. Dans ``connector_coffee/coffee_model.py``::" + +#: ../../guides/bootstrap_connector.rst:157 +msgid "Notes:" +msgstr "Notes :" + +#: ../../guides/bootstrap_connector.rst:159 +msgid "" +"The ``_backend_type`` must be the same than the name in the backend in " +"`Declare the backends`_." +msgstr "" +"Le ``_backend_type`` doit être le même que le nom du backend dans " +"`Déclaration des backends`_." + +#: ../../guides/bootstrap_connector.rst:161 +msgid "" +"the versions should be the same than the ones declared in `Declare the " +"backends`_." +msgstr "" +"les versions doivent être les mêmes que celles déclarées dans `Déclaration " +"des backends`_." + +#: ../../guides/bootstrap_connector.rst:162 +msgid "" +"We may want to add as many fields as we want to configure our connection or " +"configuration regarding the backend in that model." +msgstr "" +"Nous pouvons ajouter dans ce modèle autant de champs que nous voulons pour " +"configurer notre connexion ou configuration en rapport avec le backend." + +#: ../../guides/bootstrap_connector.rst:168 +msgid "Abstract Binding" +msgstr "Binding abstrait" + +#: ../../guides/bootstrap_connector.rst:170 +msgid "" +"If we have many :ref:`binding`, we may want to create an abstract model for " +"them." +msgstr "" +"Si nous avons de nombreux :ref:`binding`, nous pouvons créer un modèle " +"abstrait pour eux." + +#: ../../guides/bootstrap_connector.rst:173 +msgid "It can be as follows (in ``connector_coffee/connector.py``)::" +msgstr "Cela peut être comme suit (dans ``connector_coffee/connector.py``)::" + +#: ../../guides/bootstrap_connector.rst:197 ../../guides/concepts.rst:125 +msgid "Environment" +msgstr "Environnement" + +#: ../../guides/bootstrap_connector.rst:199 +msgid "" +"We'll often need to create a new environment to work with. I propose to " +"create a helper method which build it for us (in ``connector_coffee/" +"connector.py``::" +msgstr "" +"Nous aurons souvent besoin de créer un nouvel environnement avec lequel " +"travailler. Je propose de créer une méthode auxiliaire qui le construit " +"(dans ``connector_coffee/connector.py``::" + +#: ../../guides/bootstrap_connector.rst:218 +msgid "" +"Note that the part regarding the language definition is totally optional but " +"I left it as an example." +msgstr "" +"Remarquez que la partie qui concerne la définition du langage est " +"complètement optionnelle mais elle est conservée pour l'exemple." + +#: ../../guides/bootstrap_connector.rst:224 +msgid "Checkpoints" +msgstr "Points de contrôle" + +#: ../../guides/bootstrap_connector.rst:226 +msgid "" +"When new records are imported and need a review, :ref:`checkpoint` are " +"created. I propose to create a helper too in ``connector_coffee/connector." +"py``::" +msgstr "" +"Quand de nouveaux enregistrements sont importés et ont besoin de " +"vérification, des :ref:`checkpoint` sont créés. Je propose de créer aussi un " +"auxiliaire dans ``connector_coffee/connector.py``::" + +#: ../../guides/bootstrap_connector.rst:239 +msgid "ConnectorUnit classes" +msgstr "Classes ConnectorUnit" + +#: ../../guides/bootstrap_connector.rst:241 +msgid "" +"We'll probably need to create synchronizers, mappers, backend adapters, " +"binders and maybe our own types of ConnectorUnit classes." +msgstr "" +"Nous aurons probablement besoin de créer des synchroniseurs, des mappeurs, " +"des adaptateurs de backend, des bindings, et peut-être nos propres types de " +"classes ConnectorUnit" + +#: ../../guides/code_overview.rst:5 +msgid "Code Overview" +msgstr "Survol du code" + +#: ../../guides/code_overview.rst:7 +msgid "Here is an overview of some of the concepts in the framework." +msgstr "Voici un survol de certains concepts du framework." + +#: ../../guides/code_overview.rst:9 +msgid "" +"As an example, we'll see the steps for exporting an invoice to Magento. The " +"steps won't show all the steps, but a simplified excerpt of a real use case " +"exposing the main ideas." +msgstr "" +"Comme exemple, nous allons voir les étapes pour exporter une facture vers " +"Magento. Ce n'est pas un exemple complet mais un aperçu d'un cas réel pour " +"exposer les idée principales." + +#: ../../guides/code_overview.rst:15 +msgid "Backends" +msgstr "Backends" + +#: ../../guides/code_overview.rst:17 +msgid "" +"All start with the declaration of the :py:class:`~connector.backend." +"Backend`::" +msgstr "" +"Tout commence par une déclaration du :py:class:`~connector.backend.Backend`::" + +#: ../../guides/code_overview.rst:27 +msgid "" +"As you see, Magento is the parent of Magento 1.7. We can define a hierarchy " +"of backends." +msgstr "" +"Comme vous pouvez voir, Magento est parent de Magento 1.7. Nous pouvons donc " +"définir une hiérarchie de backends." + +#: ../../guides/code_overview.rst:32 ../../guides/concepts.rst:213 +msgid "Bindings" +msgstr "Bindings (Liaisons)" + +#: ../../guides/code_overview.rst:55 ../../guides/concepts.rst:88 +msgid "Session" +msgstr "Session" + +#: ../../guides/code_overview.rst:57 +msgid "" +"The framework uses :py:class:`~connector.session.ConnectorSession` objects " +"to store the ``cr``, ``uid`` and ``context`` in a :class:`odoo.api." +"Environment`. So from a session, we can access to the usual ``self.env`` " +"(new API) or ``self.pool`` (old API)." +msgstr "" +"Le framework utilise des objets :py:class:`~connector.session." +"ConnectorSession` pour stocker les ``cr``, ``uid`` et ``context`` dans un :" +"class:`odoo.api.Environment`. Donc depuis une session, nous pouvons " +"accéder aux habituels ``self.env`` (nouvelle API) ou ``self.pool`` (ancienne " +"API)." + +#: ../../guides/code_overview.rst:64 ../../guides/concepts.rst:20 +msgid "Events" +msgstr "Événements" + +#: ../../guides/code_overview.rst:66 +msgid "" +"We can create :py:class:`~connector.event.Event` on which we'll be able to " +"subscribe consumers. The connector already integrates the most generic " +"ones: :py:meth:`~connector.event.on_record_create`, :py:meth:`~connector." +"event.on_record_write`, :py:meth:`~connector.event.on_record_unlink`" +msgstr "" +"Nous pouvons créer un :py:class:`~connector.event.Event` sur lequel nous " +"pouvons abonner des consommateurs. Le connecteur fournit d'origine les plus " +"génériques: :py:meth:`~connector.event.on_record_create`, :py:meth:" +"`~connector.event.on_record_write`, :py:meth:`~connector.event." +"on_record_unlink`" + +#: ../../guides/code_overview.rst:73 +msgid "" +"When we create a ``magento.account.invoice`` record, we want to delay a job " +"to export it to Magento, so we subscribe a new consumer on :py:meth:" +"`~connector.event.on_record_create`::" +msgstr "" +"À la création d'un enregistrement ``magento.account.invoice``, nous voulons " +"lancer un job déporté pour l'exporter vers Magento, donc nous abonnons un " +"nouveau consommateur à l'événement :py:meth:`~connector.event." +"on_record_create`::" + +#: ../../guides/code_overview.rst:84 +msgid "" +"On the last line, you can notice an ``export_invoice.delay``. We'll discuss " +"about that in Jobs_" +msgstr "" +"Sur la dernière ligne, vous pouvez notez un ``export_invoice.delay``. Nous " +"parlerons de ceci dans Jobs_" + +#: ../../guides/code_overview.rst:89 +msgid "Jobs" +msgstr "Jobs" + +#: ../../guides/code_overview.rst:91 +msgid "" +"A :py:class:`~connector.queue.job.Job` is a task to execute later. In that " +"case: create the invoice on Magento." +msgstr "" +"Un :py:class:`~connector.queue.job.Job` est une tâche à exécuter plus tard. " +"Dans le cas présent: créer une facture dans Magento." + +#: ../../guides/code_overview.rst:94 +msgid "" +"Any function decorated with :py:meth:`~connector.queue.job.job` can be " +"posted in the queue of jobs using a ``delay()`` function and will be run as " +"soon as possible::" +msgstr "" +"N'importe quelle fonction décorée avec :py:meth:`~connector.queue.job.job` " +"peut être envoyée dans la queue de jobs en utilisant la fonction ``delay()`` " +"et sera lancée aussi tôt que possible ::" + +#: ../../guides/code_overview.rst:107 +msgid "There is a few things happening there:" +msgstr "Voici les choses qui se passent à ce moment :" + +#: ../../guides/code_overview.rst:109 +msgid "We find the backend on which we'll export the invoice." +msgstr "Nous trouvons le backend vers lequel exporter la facture." + +#: ../../guides/code_overview.rst:110 +msgid "" +"We build an :py:class:`~connector.connector.Environment` with the current :" +"py:class:`~connector.session.ConnectorSession`, the model we work with and " +"the target backend." +msgstr "" +"Nous construisons un :py:class:`~connector.connector.Environment` avec la :" +"py:class:`~connector.session.ConnectorSession` actuelle, le modèle avec " +"lequel on travaille et le backend cible." + +#: ../../guides/code_overview.rst:113 +msgid "" +"We get the :py:class:`~connector.connector.ConnectorUnit` responsible for " +"the work using :py:meth:`~connector.connector.Environment." +"get_connector_unit` (according the backend version and the model) and we " +"call ``run()`` on it." +msgstr "" +"Nous récupérons la :py:class:`~connector.connector.ConnectorUnit` " +"responsable du travail grâce à :py:meth:`~connector.connector.Environment." +"get_connector_unit` (en fonction de la version du backend et du modèle) et " +"nous appelons sa méthode ``run()``." + +#: ../../guides/code_overview.rst:122 ../../guides/concepts.rst:143 +msgid "ConnectorUnit" +msgstr "ConnectorUnit" + +#: ../../guides/code_overview.rst:124 +msgid "" +"These are all classes which are responsible for a specific work. The main " +"types of :py:class:`~connector.connector.ConnectorUnit` are (the " +"implementation of theses classes belongs to the connectors):" +msgstr "" +"Voici toutes les classes qui sont responsables d'un travail particulier. Les " +"principaux types de :py:class:`~connector.connector.ConnectorUnit` sont " +"(l'implémentation de ces classes fait partie des connecteurs):" + +#: ../../guides/code_overview.rst:128 +msgid ":py:class:`~connector.connector.Binder`" +msgstr ":py:class:`~connector.connector.Binder`" + +#: ../../guides/code_overview.rst:133 +msgid ":py:class:`~connector.unit.mapper.Mapper`" +msgstr ":py:class:`~connector.unit.mapper.Mapper`" + +#: ../../guides/code_overview.rst:138 +msgid ":py:class:`~connector.unit.backend_adapter.BackendAdapter`" +msgstr ":py:class:`~connector.unit.backend_adapter.BackendAdapter`" + +#: ../../guides/code_overview.rst:140 +msgid "" +"The ``adapters`` implements the discussion with the ``backend's`` APIs. They " +"usually adapt their APIs to a common interface (CRUD)." +msgstr "" +"Les ``adaptateurs`` implémentent le dialogue avec les API du ``backend``. " +"Elles adaptent habituellement leurs APIs à une interface commune (CRUD)." + +#: ../../guides/code_overview.rst:143 +msgid ":py:class:`~connector.unit.synchronizer.Synchronizer`" +msgstr ":py:class:`~connector.unit.synchronizer.Synchronizer`" + +#: ../../guides/code_overview.rst:145 +msgid "" +"The ``synchronizers`` are the main piece of a synchronization. They define " +"the flow of a synchronization and use the other :py:class:`~connector." +"connector.ConnectorUnit` (the ones above or specific ones)." +msgstr "" +"Les ``synchroniseurs`` sont la partie principale d'une synchronisation. Ils " +"définissent le flux de synchronisation et utilisent les :py:class:" +"`~connector.connector.ConnectorUnit` (ceux ci-dessus ou des spécifiques)." + +#: ../../guides/code_overview.rst:150 +msgid "" +"For the export of the invoice, we just need an ``adapter`` and a " +"``synchronizer`` (the real implementation is more complete)::" +msgstr "" +"Pour l'export de la facture, nous avons juste besoin d'un ``adaptateur`` et " +"d'un ``synchroniseur`` (l'implémentation réelle est plus complexe)::" + +#: ../../guides/concepts.rst:5 +msgid "Connector Concepts" +msgstr "Concepts du connecteur" + +#: ../../guides/concepts.rst:7 +msgid "" +"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." +msgstr "" +"Le framework pour développer des connecteur est découplé en composants " +"interagissant ensemble. Chacun d'eux peut être utilisé ou non dans une " +"implémentation." + +#: ../../guides/concepts.rst:13 +msgid "" +"This document describes them from a high-level point of view and gives " +"pointers to more concrete 'how-to' or small tutorials." +msgstr "" +"Ce document les décrit d'un point de vue haut-niveau et donne des pointeurs " +"vers des « how-to » plus concrets ou de petits tutoriels." + +#: ../../guides/concepts.rst:25 +msgid "" +"The basic idea is to declare an :py:class:`~connector.event.Event`, for " +"instance :py:class:`~connector.event.on_record_create`. Then each connector " +"has the ability to subscribe one or many function on it. The creation of a " +"record should fire :py:class:`~connector.event.on_record_create`, which will " +"trigger all the subscribed functions." +msgstr "" +"L'idée de base est de déclarer un :py:class:`~connector.event.Event`, par " +"exemple :py:class:`~connector.event.on_record_create`. Grâce à ceci, chaque " +"connecteur a la possibilité d'abonner une ou plusieurs fonctions sur " +"l'événement. La création de l'enregistrement doit alors exécuter :py:class:" +"`~connector.event.on_record_create`, qui va déclencher toutes les fonctions " +"abonnées." + +#: ../../guides/concepts.rst:32 +msgid "" +"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." +msgstr "" +"Le même événement peut être partagé entre plusieurs connecteurs, facilitant " +"ainsi leur implémentation. Par exemple, le module connector_ecommerce_ qui " +"est une extension du framework avec des capacités courantes pour le e-" +"commerce, ajoute ses propres événements dédiés au e-commerce." + +#: ../../guides/concepts.rst:38 ../../guides/concepts.rst:81 +#: ../../guides/concepts.rst:115 ../../guides/concepts.rst:136 +msgid "A connectors developer is mostly interested by:" +msgstr "Un développeur de connecteur est principalement intéressé par :" + +#: ../../guides/concepts.rst:40 +msgid "" +"register a new function on an event (see :py:class:`connector.event.Event`)" +msgstr "" +"abonner une nouvelle fonction à un événement (voir :py:class:`connector." +"event.Event`)" + +#: ../../guides/concepts.rst:41 +msgid "" +"unregister a function from an event (see :py:meth:`connector.event.Event." +"unsubscribe`)" +msgstr "" +"désabonner une fonction d'un événement (voir :py:meth:`connector.event.Event." +"unsubscribe`)" + +#: ../../guides/concepts.rst:42 +msgid "" +"replace a consumer function by another one (see :py:class:`connector.event." +"Event`)" +msgstr "" +"remplacer une fonction consommatrice par une autre (voir :py:class:" +"`connector.event.Event`)" + +#: ../../guides/concepts.rst:43 +msgid "" +"filter the events by model, so a subscribed function will be triggered only " +"if the event happens on a registered model" +msgstr "" +"filtrer les événements par modèle, de sorte qu'une fonction abonnée ne soit " +"déclenchée que pour l'événement d'un modèle particulier" + +#: ../../guides/concepts.rst:50 +msgid "Jobs Queue" +msgstr "Queue de jobs" + +#: ../../guides/concepts.rst:52 +msgid "" +"This section summarises the Job's Queue, which articulates around several " +"classes, in broad terms, :py:class:`~connector.queue.job.Job` are executed " +"by a :py:class:`~connector.queue.worker.Worker` which stores them in a :py:" +"class:`~connector.queue.queue.JobsQueue`." +msgstr "" +"Cette section résume le principe des queues de jobs, qui s'articule autour " +"de quelques classes, dans les grandes lignes, les :py:class:`~connector." +"queue.job.Job` sont exécutés par un :py:class:`~connector.queue.worker." +"Worker` qui les stocke dans une :py:class:`~connector.queue.queue.JobsQueue`." + +#: ../../guides/concepts.rst:61 +msgid "" +"Jobs are stored in the :py:class:`~connector.queue.model.QueueJob` model." +msgstr "" +"Les jobs son stockés dans le modèle :py:class:`~connector.queue.model." +"QueueJob`." + +#: ../../guides/concepts.rst:64 +msgid "" +"Workers are stored in the :py:class:`~connector.queue.model.QueueWorker` " +"model. A :py:class:`~connector.queue.worker.WorkerWatcher` create or destroy " +"new workers when new :py:class:`~odoo.modules.registry.Registry` are " +"created or destroyed, and signal the aliveness of the workers." +msgstr "" +"Les workers sont stockés dans le modèle :py:class:`~connector.queue.model." +"QueueWorker`. Un :py:class:`~connector.queue.worker.WorkerWatcher` crée ou " +"détruit de nouveaux workers quand de nouveaux :py:class:`~odoo.modules." +"registry.Registry` sont créés ou détruits, et signale si les workers sont en " +"vie ou non." + +#: ../../guides/concepts.rst:70 +msgid "" +"Jobs are assigned to a worker in the database by a cron. The worker loads " +"all the jobs assigned to itself in memory in the :py:class:`~connector.queue." +"queue.JobsQueue`. When a worker is dead, it is removed from the database, so " +"the jobs are freeed from the worker and can be assigned to another one." +msgstr "" +"Les jobs sont affectés à un worker dans la base de données par une tâche " +"récurrente (cron). Le worker charge en mémoire tous les jobs qui lui sont " +"affectés, dans la :py:class:`~connector.queue.queue.JobsQueue`. Quand un " +"worker s'arrête, il est supprimé de la base de données, de façon que les " +"jobs soient libérés et affectés à un autre worker." + +#: ../../guides/concepts.rst:83 +msgid "Delay a job (see the decorator :py:func:`~connector.queue.job.job`)" +msgstr "" +"Déporter un job (voir le décorateur :py:func:`~connector.queue.job.job`)" + +#: ../../guides/concepts.rst:97 +msgid "Backend" +msgstr "Backend" + +#: ../../guides/concepts.rst:99 +msgid "" +"A :py:class:`~connector.backend.Backend` is a reference to an external " +"system or service." +msgstr "" +"Un :py:class:`~connector.backend.Backend` est une référence à un système ou " +"service externe à Odoo." + +#: ../../guides/concepts.rst:102 +msgid "" +"A backend is defined by a name and a version. For instance ``Magento 1.7``." +msgstr "" +"Un backend est défini par un nom et une version. Par exemple ``Magento 1.7``." + +#: ../../guides/concepts.rst:105 +msgid "" +"A reference can have a parent. The instance ``Magento 1.7`` is the child of " +"``Magento``." +msgstr "" +"Une référence peut avoir un parent. L'instance ``Magento 1.7`` est fille de " +"``Magento``." + +#: ../../guides/concepts.rst:108 +msgid "" +":py:class:`~connector.connector.ConnectorUnit` classes are registered on the " +"backends. Then, we are able to ask a registered class to a backend. If no " +"class is found, it will search in its parent backend." +msgstr "" +"Les classes :py:class:`~connector.connector.ConnectorUnit` sont inscrites " +"dans les backends. Ceci permet de récupérer une classe inscrite dans le " +"backend. Si aucune classe n'est trouvée, elle est cherchée dans le backend " +"parent." + +#: ../../guides/concepts.rst:112 +msgid "" +"It is always accompanied by a concrete subclass of the model :py:class:" +"`~connector.backend_model.connector_backend`." +msgstr "" +"Il est toujours accompagné d'une sous-classe concrète du modèle :py:class:" +"`~connector.backend_model.connector_backend`." + +#: ../../guides/concepts.rst:117 +msgid "Declare the backends (see :py:class:`connector.backend.Backend`)" +msgstr "Déclarer les backends (voir :py:class:`connector.backend.Backend`)" + +#: ../../guides/concepts.rst:118 +msgid "" +"Register a ConnectorUnit on a backend (see :py:class:`connector.backend." +"Backend`)" +msgstr "" +"Inscrire un ConnectorUnit dans un backend (voir :py:class:`connector.backend." +"Backend`)" + +#: ../../guides/concepts.rst:119 +msgid "" +"Replace a ConnectorUnit on a backend (see :py:class:`connector.backend." +"Backend`)" +msgstr "" +"Remplacer un ConnectorUnit dans un backend (voir :py:class:`connector." +"backend.Backend`)" + +#: ../../guides/concepts.rst:120 +msgid "" +"Use a different ConnectorUnit for a different version of a backend (see :py:" +"class:`connector.backend.Backend`)" +msgstr "" +"Utiliser un ConnectorUnit différent pour une version différente d'un backend " +"(voir :py:class:`connector.backend.Backend`)" + +#: ../../guides/concepts.rst:127 +msgid "" +"An :py:class:`~connector.connector.Environment` is the scope from which we " +"will do synchronizations." +msgstr "" +"Un :py:class:`~connector.connector.Environment` est le périmètre à partir " +"duquel nous allons faire des synchronisations." + +#: ../../guides/concepts.rst:130 +msgid "" +"It contains a :py:class:`~connector.backend.Backend`, a record of a concrete " +"subclass of the model :py:class:`~connector.backend_model." +"connector_backend`, a :py:class:`~connector.session.Session` and the name of " +"the model to work with." +msgstr "" +"Il contient un :py:class:`~connector.backend.Backend`, un enregistrement " +"d'une sous-classe concrète du modèle :py:class:`~connector.backend_model." +"connector_backend`, une :py:class:`~connector.session.Session` et le nom du " +"modèle avec lequel travailler." + +#: ../../guides/concepts.rst:138 +msgid "" +"Get a connectorUnit from an environment (:py:meth:`connector.connector." +"ConnectorUnit.unit_for`, :py:meth:`connector.connector.ConnectorUnit." +"binder_for`)" +msgstr "" +"Récupère un ConnectorUnit depuis un environnement (:py:meth:`connector." +"connector.ConnectorUnit.unit_for`, :py:meth:`connector.connector." +"ConnectorUnit.binder_for`)" + +#: ../../guides/concepts.rst:145 +msgid "" +":py:class:`~connector.connector.ConnectorUnit` are pluggable classes used " +"for the synchronizations with the external systems." +msgstr "" +"Les :py:class:`~connector.connector.ConnectorUnit` sont des classes " +"modulables utilisées pour la synchronisation avec des systèmes externes." + +#: ../../guides/concepts.rst:149 +msgid "" +"The connector defines some base classes, which you can find below. Note that " +"you can define your own ConnectorUnits as well." +msgstr "" +"Le connecteur définit des classes de bases que vous pouvez trouver ci-" +"dessous. Notez que vous pouvez aussi définir vos propres ConnectorUnits." + +#: ../../guides/concepts.rst:153 +msgid "Mappings" +msgstr "Mappings" + +#: ../../guides/concepts.rst:155 +msgid "The base class is :py:class:`connector.unit.mapper.Mapper`." +msgstr "La classe de base est :py:class:`connector.unit.mapper.Mapper`." + +#: ../../guides/concepts.rst:160 +msgid "It supports:" +msgstr "Il prend en charge :" + +#: ../../guides/concepts.rst:163 +msgid "direct mappings" +msgstr "les mapping directs" + +#: ../../guides/concepts.rst:163 +msgid "Fields *a* is written in field *b*." +msgstr "Le champ *a* est écrit dans le champ *b*." + +#: ../../guides/concepts.rst:169 +msgid "method mappings" +msgstr "Les mapping par méthode" + +#: ../../guides/concepts.rst:166 +msgid "" +"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." +msgstr "" +"Une méthode est utilisée pour convertir un ou plusieurs champs en un ou " +"plusieurs autres champs, avec transformation éventuelle. Il peut être " +"filtré, par exemple appliqué uniquement lorsque l'enregistrement est créé ou " +"quand les champs source sont modifiés." + +#: ../../guides/concepts.rst:173 +msgid "submapping" +msgstr "Sous-mapping" + +#: ../../guides/concepts.rst:172 +msgid "a sub-record (lines of a sale order) is converted using another Mapper" +msgstr "" +"Un sous-enregistrement (ligne d'un bon de commande) est converti grâce à un " +"autre Mapper" + +#: ../../guides/concepts.rst:176 +msgid "Synchronizers" +msgstr "Synchroniseurs" + +#: ../../guides/concepts.rst:178 +msgid "The base class is :py:class:`connector.unit.synchronizer.Synchronizer`." +msgstr "" +"La classe de base est :py:class:`connector.unit.synchronizer.Synchronizer`." + +#: ../../guides/concepts.rst:180 +msgid "" +"A synchronizer defines the flow of 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." +msgstr "" +"Un synchroniseur définit le flux de la synchronisation avec un backend. Il " +"peut correspondre à un import ou un export, une suppression de quelque " +"chose, ou n'importe quoi d'autre. Par exemple, il peut utiliser les mappeurs " +"pour convertir des données entre les deux systèmes, les adaptateurs de " +"backend pour lire ou écrire les données sur le backend et les binders pour " +"créer le lien entre eux." + +#: ../../guides/concepts.rst:189 +msgid "Backend Adapters" +msgstr "Adaptateurs de backend" + +#: ../../guides/concepts.rst:191 +msgid "" +"The base class is :py:class:`connector.unit.backend_adapter.BackendAdapter`." +msgstr "" +"La classe de base est :py:class:`connector.unit.backend_adapter." +"BackendAdapter`." + +#: ../../guides/concepts.rst:194 +msgid "" +"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." +msgstr "" +"Un adaptateur externe possède une interface commune pour parler avec le " +"backend. Il traduit les commandes basiques (recherche, lecture, écriture) " +"vers le protocole utilisé par le backend." + +#: ../../guides/concepts.rst:199 +msgid "Binders" +msgstr "Binders (Liants)" + +#: ../../guides/concepts.rst:201 +msgid "The base class is :py:class:`connector.connector.Binder`." +msgstr "La classe de base est :py:class:`connector.connector.Binder`." + +#: ../../guides/concepts.rst:217 +msgid "" +"The proposed implementation for the connectors widely use the `_inherits` " +"capabilities." +msgstr "" +"L'implémentation proposée pour les connecteurs utilise largement les " +"capacités de l'`_inherits`." + +#: ../../guides/concepts.rst:220 +msgid "Say we import a customer from *Magento*." +msgstr "Disons que nous importons un client depuis *Magento*." + +#: ../../guides/concepts.rst:222 +msgid "" +"We create a `magento.res.partner` model, which `_inherits` `res.partner`." +msgstr "" +"Nous créons un modèle `magento.res.partner`, qui `_inherits` `res.partner`." + +#: ../../guides/concepts.rst:228 +msgid "" +"It also stores all the necessary metadata related to this customer coming " +"from Magento." +msgstr "" +"Il stocke également toutes les métadonnées nécessaires à ce client venant de " +"Magento" + +#: ../../guides/concepts.rst:235 +msgid "Checkpoint" +msgstr "Point de contrôle" + +#: ../../guides/concepts.rst:237 +msgid "" +"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." +msgstr "" +"Un point de contrôle est un enregistrement du modèle `connector.checkpoint` " +"lié à un modèle et un enregistrement. Les connecteurs peuvent en créer de " +"nouveaux quand l'utilisateur a besoin de vérifier des documents importés." + +#: ../../guides/multiprocessing.rst:6 +msgid "Use the connector with multiprocessing" +msgstr "Connecteur et multiprocessing" + +#: ../../guides/multiprocessing.rst:22 +msgid "Example::" +msgstr "Exemple ::" + +#: ../../guides/multiprocessing.rst:27 +msgid "" +"The 'Enqueue Jobs' scheduled action is useless when multiprocessing is used." +msgstr "L'action planifiée 'Enqueue Jobs' est inutile en mode multi-processus." + +#: ../../guides/multiprocessing.rst:34 +msgid "" +"The Magento Connector's buildout contains builtin commands to launch the " +"workers: :ref:`connectormagento:installation-with-buildout`" +msgstr "" +"Le `buildout` du connecteur Magento contient des commandes intégrées pour " +"lancer les workers : :ref:`connectormagento:installation-with-buildout`" + +#: ../../guides/bootstrap_connector.rst:13 +msgid "`Odoo Magento Connector`_" +msgstr "`Connecteur Odoo Magento`_" + +#: ../../guides/bootstrap_connector.rst:14 +msgid "`Odoo Prestashop Connector`_" +msgstr "`Connecteur Odoo Prestashop`_" + +#: ../../guides/bootstrap_connector.rst:19 +msgid "" +"For the sake of the example, we'll imagine we have to synchronize Odoo with " +"a coffee machine." +msgstr "" +"Pour cet exemple nous allons imaginer que nous devons synchroniser Odoo avec " +"une machine à café." + +#: ../../guides/bootstrap_connector.rst:24 +msgid "Odoo Manifest" +msgstr "" + +#: ../../guides/bootstrap_connector.rst:26 +msgid "" +"As we want to synchronize Odoo with a coffee machine, we'll name our " +"connector connector_coffee." +msgstr "" +"Comme nous voulons synchroniser Odoo avec une machine à café, nous allons " +"nommer notre connecteur connector_coffee" + +#: ../../guides/bootstrap_connector.rst:29 +msgid "" +"First, we need to create the Odoo addons itself, editing the " +"``connector_coffee/__odoo__.py`` manifest." +msgstr "" +"Tout d'abord, nous devons créer le module Odoo lui-même, en modifiant le " +"fichier ``connector_coffee/__odoo__.py``." + +#: ../../guides/bootstrap_connector.rst:85 +msgid "" +"The reason for this is that Odoo may import the Python modules of " +"uninstalled modules, so it automatically registers the events and " +"ConnectorUnit classes, even for uninstalled modules." +msgstr "" +"La raison de ce fonctionnement est qu'Odoo importe les modules Python des " +"addons non installés, donc il inscrit automatiquement les événements et les " +"classes ConnectorUnit, même pour les modules non installés." + +#: ../../guides/bootstrap_connector.rst:244 +msgid "" +"Their implementation can vary a lot. Have a look on the `Odoo Magento " +"Connector`_ and `Odoo Prestashop Connector`_ projects." +msgstr "" +"Leur implémentation peut varier énormément. Jetez un œil aux projets " +"`Connecteur Odoo Magento`_ et `Connecteur Odoo Prestashop`_." + +#: ../../guides/code_overview.rst:34 +msgid "" +"The ``binding`` is the link between an Odoo record and an external record. " +"There is no forced implementation for the ``bindings``. The most " +"straightforward techniques are: storing the external ID in the same model " +"(``account.invoice``), in a new link model or in a new link model which " +"``_inherits`` ``account.invoice``. Here we choose the latter solution::" +msgstr "" +"Un ``binding`` est ce qui permet de lier un enregistrement Odoo et un " +"enregistrement externe. Il n'y a pas d'obligation pour l'implémentation des " +"``liaisons``. Les techniques les plus évidentes sont: stocker les ID " +"externes dans le même modèle (``account.invoice``), dans un modèle de " +"liaison ou dans un modèle de laison qui ``_inherits`` ``account.invoice``. " +"Ici nous choisissons la dernière solution ::" + +#: ../../guides/code_overview.rst:130 +msgid "" +"The ``binders`` give the external ID or Odoo ID from respectively an Odoo ID " +"or an external ID." +msgstr "" +"Les ``binders`` (liants) donnent l'ID externe ou l'ID Odoo en fonction, " +"respectivement, d'un ID Odoo ou d'un ID externe." + +#: ../../guides/code_overview.rst:135 +msgid "" +"The ``mappers`` transform a external record into an Odoo record or " +"conversely." +msgstr "" +"Les ``mappeurs`` transforment un enregistrement externe en enregistrement " +"Odoo ou l'inverse." + +#: ../../guides/concepts.rst:11 +msgid "An example of implementation is the `Odoo Magento Connector`_." +msgstr "Un exemple d'implémentation est le `Connecteur Odoo Magento`_." + +#: ../../guides/concepts.rst:22 +msgid "" +"Events are hooks in Odoo on which we can plug some actions. They are based " +"on an Observer pattern." +msgstr "" +"Les événements sont des points d'accroche dans Odoo sur lesquels on peut " +"brancher des actions. Ils sont basés sur le motif de conception « " +"Observateur »." + +#: ../../guides/concepts.rst:77 +msgid "" +"When multiple Odoo processes are running, a worker per process is running, " +"but only those which are *CronWorkers* enqueue and execute jobs, to avoid to " +"clutter the HTTP processes." +msgstr "" +"Si plusieurs processus Odoo sont en marche, il y a un worker par processus, " +"mais seuls ceux qui sont des *CronWorkers* traitent les jobs dans la queue, " +"pour éviter d'encombrer les processus HTTP." + +#: ../../guides/concepts.rst:90 +msgid "" +"A :py:class:`~connector.session.ConnectorSession` is a container for the " +"usual ``cr``, ``uid``, ``context`` used in Odoo. Now, it contains the Odoo " +"``Environment`` as ``self.env``. We use them accross the connectors." +msgstr "" +"Une :py:class:`~connector.session.ConnectorSession` est un conteneur pour " +"les classiques ``cr``, ``uid``, ``context`` utilisés dans Odoo. Maintenant " +"il contient l'``Environment`` Odoo dans ``self.env``. Nous les utilisons au " +"sein des connecteurs." + +#: ../../guides/concepts.rst:157 +msgid "" +"A mapping translates an external record to an Odoo record and conversely." +msgstr "" +"Un mapping convertit un enregistrement externe en un enregistrement Odoo et " +"inversement." + +#: ../../guides/concepts.rst:204 +msgid "" +"Binders are classes which 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." +msgstr "" +"Les Binders sont des classes qui savent comment trouver l'ID externe depuis " +"un ID Odoo, comment trouver l'ID Odoo depuis un ID externe et comment créer " +"le lien entre elles." + +#: ../../guides/concepts.rst:215 +msgid "Here a binding means the link of a record between Odoo and a backend." +msgstr "" +"Ici, un « binding » signifie le lien d'un enregistrement entre Odoo et un " +"backend." + +#: ../../guides/concepts.rst:225 +msgid "" +"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." +msgstr "" +"Ce modèle, appelé modèle de *binding* (liaison), connaît les ID du `partner` " +"dans Odoo, l'ID dans Magento et la relation avec le modèle backend." + +#: ../../guides/multiprocessing.rst:8 +msgid "" +"When Odoo is launched with 1 process, the jobs worker will run threaded in " +"the same process." +msgstr "" +"Quand Odoo est lancé avec un seul processus, le worker de jobs fonctionne " +"dans un thread." + +#: ../../guides/multiprocessing.rst:11 +msgid "" +"When Odoo is launched with multiple processes using the option ``--" +"workers``, the jobs workers are not independant processes, however, you have " +"to launch them separately with the script ``odoo-connector-worker`` " +"located in the connector module." +msgstr "" +"Quand Odoo est lancé en multi-processus grâce à l'option ``--workers``, les " +"workers de jobs ne sont pas des processus indépendants, mais vous devez les " +"lancer séparément avec le script ``odoo-connector-worker`` situé dans le " +"module `connector`." + +#: ../../guides/multiprocessing.rst:16 +msgid "" +"It takes the same arguments and configuration file than the Odoo server." +msgstr "" +"Il prend les mêmes arguments et fichier de configuration que le serveur Odoo." + +#: ../../guides/multiprocessing.rst:19 +msgid "" +"The Python path must contain the path to the Odoo server when ``odoo-" +"connector-worker`` is launched." +msgstr "" +"Le `path` de Python doit contenir le chemin vers le serveur Odoo quand " +"``odoo-connector-worker`` est lancé." + +#: ../../guides/multiprocessing.rst:30 +msgid "" +"The ``odoo-connector-worker`` should not be launched alongside Odoo when " +"the latter does not run in multiprocess mode, because the interprocess " +"signaling would not be done." +msgstr "" +"Le script ``odoo-connector-worker`` ne doit pas être lancé avec Odoo " +"quand ce dernier ne fonctionne pas en multi-processus, parce que les signaux " +"inter-processus ne seraient pas transmis." + +#~ msgid "`Odoo Magento Connector`_" +#~ msgstr "`Connecteur Odoo Magento`_" + +#~ msgid "`Odoo Prestashop Connector`_" +#~ msgstr "`Connecteur Odoo Prestashop`_" + +#~ msgid "" +#~ "For the sake of the example, we'll imagine we have to synchronize Odoo " +#~ "with a coffee machine." +#~ msgstr "" +#~ "Pour cet exemple nous allons imaginer que nous devons synchroniser " +#~ "Odoo avec une machine à café." + +#~ msgid "Odoo Manifest" +#~ msgstr "Manifest Odoo" + +#~ msgid "" +#~ "As we want to synchronize Odoo with a coffee machine, we'll name our " +#~ "connector connector_coffee." +#~ msgstr "" +#~ "Comme nous voulons synchroniser Odoo avec une machine à café, nous " +#~ "allons nommer notre connecteur connector_coffee" + +#~ msgid "" +#~ "First, we need to create the Odoo addons itself, editing the " +#~ "``connector_coffee/__odoo__.py`` manifest." +#~ msgstr "" +#~ "Tout d'abord, nous devons créer le module Odoo lui-même, en modifiant " +#~ "le fichier ``connector_coffee/__odoo__.py``." + +#~ msgid "" +#~ "The reason for this is that Odoo may import the Python modules of " +#~ "uninstalled modules, so it automatically registers the events and " +#~ "ConnectorUnit classes, even for uninstalled modules." +#~ msgstr "" +#~ "La raison de ce fonctionnement est qu'Odoo importe les modules Python " +#~ "des addons non installés, donc il inscrit automatiquement les événements " +#~ "et les classes ConnectorUnit, même pour les modules non installés." + +#~ msgid "" +#~ "Their implementation can vary a lot. Have a look on the `Odoo Magento " +#~ "Connector`_ and `Odoo Prestashop Connector`_ projects." +#~ msgstr "" +#~ "Leur implémentation peut varier énormément. Jetez un œil aux projets " +#~ "`Connecteur Odoo Magento`_ et `Connecteur Odoo Prestashop`_." + +#~ msgid "" +#~ "The ``binding`` is the link between an Odoo record and an external " +#~ "record. There is no forced implementation for the ``bindings``. The most " +#~ "straightforward techniques are: storing the external ID in the same model " +#~ "(``account.invoice``), in a new link model or in a new link model which " +#~ "``_inherits`` ``account.invoice``. Here we choose the latter solution::" +#~ msgstr "" +#~ "Un ``binding`` est ce qui permet de lier un enregistrement Odoo et un " +#~ "enregistrement externe. Il n'y a pas d'obligation pour l'implémentation " +#~ "des ``liaisons``. Les techniques les plus évidentes sont: stocker les ID " +#~ "externes dans le même modèle (``account.invoice``), dans un modèle de " +#~ "liaison ou dans un modèle de laison qui ``_inherits`` ``account." +#~ "invoice``. Ici nous choisissons la dernière solution ::" + +#~ msgid "" +#~ "The ``binders`` give the external ID or Odoo ID from respectively an " +#~ "Odoo ID or an external ID." +#~ msgstr "" +#~ "Les ``binders`` (liants) donnent l'ID externe ou l'ID Odoo en " +#~ "fonction, respectivement, d'un ID Odoo ou d'un ID externe." + +#~ msgid "" +#~ "The ``mappers`` transform a external record into an Odoo record or " +#~ "conversely." +#~ msgstr "" +#~ "Les ``mappeurs`` transforment un enregistrement externe en enregistrement " +#~ "Odoo ou l'inverse." + +#~ msgid "An example of implementation is the `Odoo Magento Connector`_." +#~ msgstr "Un exemple d'implémentation est le `Connecteur Odoo Magento`_." + +#~ msgid "" +#~ "When multiple Odoo processes are running, a worker per process is " +#~ "running, but only those which are *CronWorkers* enqueue and execute jobs, " +#~ "to avoid to clutter the HTTP processes." +#~ msgstr "" +#~ "Si plusieurs processus Odoo sont en marche, il y a un worker par " +#~ "processus, mais seuls ceux qui sont des *CronWorkers* traitent les jobs " +#~ "dans la queue, pour éviter d'encombrer les processus HTTP." + +#~ msgid "" +#~ "A :py:class:`~connector.session.ConnectorSession` is a container for the " +#~ "usual ``cr``, ``uid``, ``context`` used in Odoo. Now, it contains the " +#~ "Odoo ``Environment`` as ``self.env``. We use them accross the connectors." +#~ msgstr "" +#~ "Une :py:class:`~connector.session.ConnectorSession` est un conteneur pour " +#~ "les classiques ``cr``, ``uid``, ``context`` utilisés dans Odoo. " +#~ "Maintenant il contient l'``Environment`` Odoo dans ``self.env``. Nous les " +#~ "utilisons au sein des connecteurs." + +#~ msgid "" +#~ "A mapping translates an external record to an Odoo record and " +#~ "conversely." +#~ msgstr "" +#~ "Un mapping convertit un enregistrement externe en un enregistrement " +#~ "Odoo et inversement." + +#~ msgid "" +#~ "Binders are classes which 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." +#~ msgstr "" +#~ "Les Binders sont des classes qui savent comment trouver l'ID externe " +#~ "depuis un ID Odoo, comment trouver l'ID Odoo depuis un ID externe " +#~ "et comment créer le lien entre elles." + +#~ msgid "" +#~ "Here a binding means the link of a record between Odoo and a backend." +#~ msgstr "" +#~ "Ici, un « binding » signifie le lien d'un enregistrement entre Odoo et " +#~ "un backend." + +#~ msgid "" +#~ "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." +#~ msgstr "" +#~ "Ce modèle, appelé modèle de *binding* (liaison), connaît les ID du " +#~ "`partner` dans Odoo, l'ID dans Magento et la relation avec le modèle " +#~ "backend." + +#~ msgid "" +#~ "When Odoo is launched with 1 process, the jobs worker will run " +#~ "threaded in the same process." +#~ msgstr "" +#~ "Quand Odoo est lancé avec un seul processus, le worker de jobs " +#~ "fonctionne dans un thread." + +#~ msgid "" +#~ "When Odoo is launched with multiple processes using the option ``--" +#~ "workers``, the jobs workers are not independant processes, however, you " +#~ "have to launch them separately with the script ``odoo-connector-" +#~ "worker`` located in the connector module." +#~ msgstr "" +#~ "Quand Odoo est lancé en multi-processus grâce à l'option ``--" +#~ "workers``, les workers de jobs ne sont pas des processus indépendants, " +#~ "mais vous devez les lancer séparément avec le script ``odoo-connector-" +#~ "worker`` situé dans le module `connector`." + +#~ msgid "" +#~ "It takes the same arguments and configuration file than the Odoo " +#~ "server." +#~ msgstr "" +#~ "Il prend les mêmes arguments et fichier de configuration que le serveur " +#~ "Odoo." + +#~ msgid "" +#~ "The Python path must contain the path to the Odoo server when " +#~ "``odoo-connector-worker`` is launched." +#~ msgstr "" +#~ "Le `path` de Python doit contenir le chemin vers le serveur Odoo quand " +#~ "``odoo-connector-worker`` est lancé." + +#~ msgid "" +#~ "The ``odoo-connector-worker`` should not be launched alongside Odoo " +#~ "when the latter does not run in multiprocess mode, because the " +#~ "interprocess signaling would not be done." +#~ msgstr "" +#~ "Le script ``odoo-connector-worker`` ne doit pas être lancé avec " +#~ "Odoo quand ce dernier ne fonctionne pas en multi-processus, parce que " +#~ "les signaux inter-processus ne seraient pas transmis." + +#~ msgid "" +#~ "Events are hooks in Odoo on which we can plug some actions. They are " +#~ "based on an Observer pattern." +#~ msgstr "" +#~ "Les événements sont des points d'accroche dans Odoo sur lesquels on " +#~ "peut brancher des actions. Ils sont basés sur le motif de conception « " +#~ "Observateur »." diff --git a/ext/3rd-party-addons/connector/doc/locale/fr/LC_MESSAGES/index.po b/ext/3rd-party-addons/connector/doc/locale/fr/LC_MESSAGES/index.po new file mode 100644 index 00000000..30714913 --- /dev/null +++ b/ext/3rd-party-addons/connector/doc/locale/fr/LC_MESSAGES/index.po @@ -0,0 +1,281 @@ +# +msgid "" +msgstr "" +"Project-Id-Version: Connector\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2015-04-15 22:28+0300\n" +"PO-Revision-Date: 2015-05-05 11:52+0100\n" +"Last-Translator: Guewen Baconnier \n" +"Language-Team: fr \n" +"Language: fr\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Generator: Poedit 1.5.4\n" + +#: ../../index.rst:21 +msgid "*Subscribe to the* `project's mailing list`_" +msgstr "*Inscrivez-vous à la* `project's mailing list`_ *(en anglais)*" + +#: ../../index.rst:23 +msgid "*Learn how to* :ref:`contribute`" +msgstr "*Découvrez comment* :ref:`contribute`" + +#: ../../index.rst:27 +msgid "Core Features" +msgstr "Fonctionnalités de base" + +#: ../../index.rst:29 +msgid "" +"**100% Open Source** (`AGPL version 3`_): the full `source code is available " +"on GitHub`_" +msgstr "" +"**100% Open Source** (`AGPL version 3`_): la totalité du `code source est " +"disponible sur GitHub`_" + +#: ../../index.rst:33 +msgid "" +"**Robust for high volumetries** and **easy to monitor** thanks to a :ref:" +"`jobs-queue`." +msgstr "" +"**Robuste pour des volumétries importantes** et **faciler à surveiller** " +"grâce à la :ref:`jobs-queue`." + +#: ../../index.rst:34 +msgid "" +"A flexible set of building blocks, it does not force to a certain " +"implementation but leaves the final choice to the developer on how to use " +"the proposed pieces." +msgstr "" +"Un ensemble flexible de blocs de construction : il n'oblige pas à respecter " +"une implémentation particulière mais laisse le choix final au développeur " +"sur la manière d'utiliser les composants." + +#: ../../index.rst:37 +msgid "See a :ref:`code-overview` with examples of code" +msgstr "Voir le :ref:`code-overview` et les exemples de code" + +#: ../../index.rst:48 +msgid "Connectors based on the framework" +msgstr "Connecteurs basés sur le framework" + +#: ../../index.rst:50 +msgid "`Magento Connector `_" +msgstr "`Connecteur Magento `_" + +#: ../../index.rst:51 +msgid "`Prestashop Connector `_" +msgstr "`Connecteur Prestashop `_" + +#: ../../index.rst:52 +msgid "`solerp (Solr Connector) `_" +msgstr "`solerp (Connecteur Solr) `_" + +#: ../../index.rst:54 +msgid "`CMIS `_" +msgstr "`Connecteur CMIS `_" + +#: ../../index.rst:58 +msgid "" +"Develop easily and rapidly your own connector based on this powerful " +"framework and list your project on this page! Examples:" +msgstr "" +"Développez facilement et rapidement votre propre connecteur basé sur ce " +"puissant framework et ajoutez votre projet sur cette page ! Exemples :" + +#: ../../index.rst:69 +msgid "Overview" +msgstr "Présentation" + +#: ../../index.rst:79 +msgid "Top financial contributors" +msgstr "Principaux contributeurs financiers" + +#: ../../index.rst:90 +msgid "*See all the project's* :ref:`financial-contributors`." +msgstr "*Voir tous les* :ref:`financial-contributors` *du projet*." + +#: ../../index.rst:94 +msgid "Project" +msgstr "Projet" + +#: ../../index.rst:107 +msgid "Developer's guide" +msgstr "Guide du développeur" + +#: ../../index.rst:118 +msgid "API Reference" +msgstr "Référence de l'API" + +#: ../../index.rst:136 +msgid "Indices and tables" +msgstr "Index et tables" + +#: ../../index.rst:138 +msgid ":ref:`genindex`" +msgstr ":ref:`genindex`" + +#: ../../index.rst:139 +msgid ":ref:`modindex`" +msgstr ":ref:`modindex`" + +#: ../../index.rst:140 +msgid ":ref:`search`" +msgstr ":ref:`search`" + +#: ../../index.rst:8 +msgid "Odoo Connector" +msgstr "Odoo Connector" + +#: ../../index.rst:10 +msgid "" +"Odoo Connector is a powerful framework to develop any kind of bi-directional " +"connector between `Odoo`_ (Open Source ERP) and any other software or " +"service." +msgstr "" +"`Odoo Connector` est un puissant framework de développement de connecteur bi-" +"directionnel entre `Odoo`_ (ERP Open Source) et tout autre logiciel ou " +"service." + +#: ../../index.rst:14 +msgid "" +"This Odoo add-on has a modular and generic core, with the ability to be " +"extended with additional modules for new features or customizations." +msgstr "" +"Ce module Odoo a un cœur modulaire et générique, capable d'être lui-même " +"étendu grâce à des modules additionnels, pour ajouter des nouvelles " +"fonctions ou des personnalisations." + +#: ../../index.rst:18 +msgid "" +"The development of Odoo Connector has been started by `Camptocamp`_ and is " +"now maintained by `Camptocamp`_, `Akretion`_ and several :ref:`contributors`." +msgstr "" +"Le développement du Connecteur Odoo a été démarré par `Camptocamp`_ et est " +"maintenu par `Camptocamp`_, `Akretion`_ et d'autres :ref:`contributors`." + +#: ../../index.rst:31 +msgid "" +"Not only designed to connect Odoo with e-commerce backends, rather it is " +"**adaptable** to connect Odoo with any type of service." +msgstr "" +"Pas uniquement conçu pour connecter Odoo à des backend e-commerce, mais " +"**adaptable** pour connecter Odoo à tout type de service." + +#: ../../index.rst:53 +msgid "" +"`Odoo Multi Company `_" +msgstr "" +"`Odoo Multi-sociétés `_" + +#: ../../index.rst:55 +msgid "" +"`Odoo Asynchronous import module `_" +msgstr "" +"`Module Odoo d'import asynchrone `_" + +#: ../../index.rst:56 +msgid "`Salesforce Connector `_" +msgstr "`Connecteur Salesforce `_" + +#: ../../index.rst:57 +msgid "" +"`Google Spreadsheet Connector `_" +msgstr "" +"`Connecteur Google Spreadsheet `_" + +#: ../../index.rst:61 +msgid "" +"E-Commerce: Odoo OsCommerce connector, Odoo Drupal Commerce connector, Odoo " +"Spree connector, Odoo Ebay connector, Odoo Amazon connector…" +msgstr "" +"E-Commerce : connecteur Odoo OsCommerce, connecteur Odoo Drupal Commerce, " +"connecteur Odoo Spree, connecteur Odoo Ebay, connecteur Odoo Amazon…" + +#: ../../index.rst:62 +msgid "CMS: Odoo Wordpress connector…" +msgstr "CMS : connecteur Odoo Wordpress…" + +#: ../../index.rst:63 +msgid "CRM: Odoo SugarCRM connector, Odoo Zabbix connector…" +msgstr "CRM : connecteur Odoo SugarCRM, connecteur Odoo Zabbix…" + +#: ../../index.rst:64 +msgid "Project Management: Odoo Redmine connector…" +msgstr "Gestion de projets : connecteur Odoo Redmine…" + +#: ../../index.rst:65 +msgid "Ticketing: Odoo Request Tracker connector, Odoo GLPI connector…" +msgstr "Ticketing : connecteur Odoo Request Tracker, connecteur Odoo GLPI…" + +#~ msgid "Odoo Connector" +#~ msgstr "Odoo Connector" + +#~ msgid "" +#~ "Odoo Connector is a powerful framework to develop any kind of bi-" +#~ "directional connector between `Odoo`_ (Open Source ERP) and any other " +#~ "software or service." +#~ msgstr "" +#~ "`Odoo Connector` est un puissant framework de développement de " +#~ "connecteur bi-directionnel entre `Odoo`_ (ERP Open Source) et tout " +#~ "autre logiciel ou service." + +#~ msgid "" +#~ "This Odoo add-on has a modular and generic core, with the ability to " +#~ "be extended with additional modules for new features or customizations." +#~ msgstr "" +#~ "Ce module Odoo a un cœur modulaire et générique, capable d'être lui-" +#~ "même étendu grâce à des modules additionnels, pour ajouter des nouvelles " +#~ "fonctions ou des personnalisations." + +#~ msgid "" +#~ "The development of Odoo Connector has been started by `Camptocamp`_ " +#~ "and is now maintained by `Camptocamp`_, `Akretion`_ and several :ref:" +#~ "`contributors`." +#~ msgstr "" +#~ "Le développement du Connecteur Odoo a été démarré par `Camptocamp`_ et " +#~ "est maintenu par `Camptocamp`_, `Akretion`_ et d'autres :ref:" +#~ "`contributors`." + +#~ msgid "" +#~ "Not only designed to connect Odoo with e-commerce backends, rather it " +#~ "is **adaptable** to connect Odoo with any type of service." +#~ msgstr "" +#~ "Pas uniquement conçu pour connecter Odoo à des backend e-commerce, " +#~ "mais **adaptable** pour connecter Odoo à tout type de service." + +#~ msgid "" +#~ "`Odoo Multi Company `_" +#~ msgstr "" +#~ "`Odoo Multi-sociétés `_" + +#~ msgid "" +#~ "E-Commerce: Odoo OsCommerce connector, Odoo Drupal Commerce " +#~ "connector, Odoo Spree connector, Odoo Ebay connector, Odoo " +#~ "Amazon connector…" +#~ msgstr "" +#~ "E-Commerce : connecteur Odoo OsCommerce, connecteur Odoo Drupal " +#~ "Commerce, connecteur Odoo Spree, connecteur Odoo Ebay, connecteur " +#~ "Odoo Amazon…" + +#~ msgid "CMS: Odoo Wordpress connector…" +#~ msgstr "CMS : connecteur Odoo Wordpress…" + +#~ msgid "CRM: Odoo SugarCRM connector, Odoo Zabbix connector…" +#~ msgstr "CRM : connecteur Odoo SugarCRM, connecteur Odoo Zabbix…" + +#~ msgid "Project Management: Odoo Redmine connector…" +#~ msgstr "Gestion de projets : connecteur Odoo Redmine…" + +#~ msgid "" +#~ "Ticketing: Odoo Request Tracker connector, Odoo GLPI connector…" +#~ msgstr "" +#~ "Ticketing : connecteur Odoo Request Tracker, connecteur Odoo GLPI…" diff --git a/ext/3rd-party-addons/connector/doc/locale/fr/LC_MESSAGES/project.po b/ext/3rd-party-addons/connector/doc/locale/fr/LC_MESSAGES/project.po new file mode 100644 index 00000000..acb02d35 --- /dev/null +++ b/ext/3rd-party-addons/connector/doc/locale/fr/LC_MESSAGES/project.po @@ -0,0 +1,777 @@ +# +msgid "" +msgstr "" +"Project-Id-Version: Connector\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2015-04-15 22:28+0300\n" +"PO-Revision-Date: 2015-05-05 11:48+0100\n" +"Last-Translator: Guewen Baconnier \n" +"Language-Team: fr \n" +"Language: fr\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Generator: Poedit 1.5.4\n" + +#: ../../project/changes.rst:5 +msgid "Changes" +msgstr "Changements" + +#: ../../../CHANGES.rst:2 +msgid "3.0.0 (2015-04-01)" +msgstr "3.0.0 (2015-04-01)" + +#: ../../../CHANGES.rst:4 +msgid "/!\\ Backwards incompatible changes inside." +msgstr "Attention : changements non rétro-compatibles dans cette version." + +#: ../../../CHANGES.rst:6 +msgid "" +"Add ``odoo.api.Environment`` in ``Session`` It is accessible in ``self." +"env`` in ``Session`` and all ``ConnectorUnit`` instances. Also in " +"``ConnectorUnit``, ``model`` returns the current (new api!) model:" +msgstr "" +"Ajout de ``odoo.api.Environment`` dans ``Session`` Accessible via ``self." +"env`` dans ``Session`` et toutes les instances ``ConnectorUnit``. Également " +"dans ``ConnectorUnit``, ``model`` renvoie le modèle en cours (nouvelle " +"API!) :" + +#: ../../../CHANGES.rst:20 +msgid "Deprecate the CRUD methods in ``Session``" +msgstr "Dépréciation des méthodes CRUD dans ``Session``" + +#: ../../../CHANGES.rst:32 +msgid "" +"``Environment.set_lang()`` is removed. It was modifying the context in place " +"which is not possible with the new frozendict context. It should be done " +"with:" +msgstr "" +"``Environment.set_lang()`` est supprimé. Il modifiait le contexte sur place " +"ce qui n'est pas possible avec les nouveaux context en frozendict. Doit être " +"fait avec:" + +#: ../../../CHANGES.rst:41 +msgid "Add an argument on the Binders methods to return a browse record" +msgstr "" +"Ajout d'un argument sur les méthodes des Binders pour renvoyer un `browse " +"record`" + +#: ../../../CHANGES.rst:47 +msgid "" +"Shorten ``ConnectorUnit.get_binder_for_model`` to ``ConnectorUnit." +"binder_for``" +msgstr "" +"Renommage de ``ConnectorUnit.get_binder_for_model`` vers ``ConnectorUnit." +"binder_for``" + +#: ../../../CHANGES.rst:49 +msgid "" +"Shorten ``ConnectorUnit.get_connector_unit_for_model`` to ``ConnectorUnit." +"unit_for``" +msgstr "" +"Renommage de ``ConnectorUnit.get_connector_unit_for_model`` vers " +"``ConnectorUnit.unit_for``" + +#: ../../../CHANGES.rst:51 +msgid "" +"Renamed ``Environment`` to ``ConnectorEnvironment`` to avoid confusion with " +"``odoo.api.Environment``" +msgstr "" +"Renommage d'``Environment`` vers ``ConnectorEnvironment`` pour éviter la " +"confusion avec ``odoo.api.Environment``" + +#: ../../../CHANGES.rst:53 +msgid "" +"Renamed the class attribute ``ConnectorUnit.model_name`` to ``ConnectorUnit." +"for_model_name``." +msgstr "" +"Renommage de l'attribut de classe ``ConnectorUnit.model_name`` vers " +"``ConnectorUnit.for_model_name``." + +#: ../../../CHANGES.rst:55 +msgid "" +"Added ``_base_binder``, ``_base_mapper``, ``_base_backend_adapter`` in the " +"synchronizers (Importer, Exporter) so it is no longer required to override " +"the ``binder``, ``mapper``, ``backend_adapter`` property methods" +msgstr "" +"Ajout de ``_base_binder``, ``_base_mapper``, ``_base_backend_adapter`` dans " +"les synchroniseurs (Importer, Exporter) donc ce n'est plus nécessaire pour " +"surcharger les méthodes property ``binder``, ``mapper``, ``backend_adapter``" + +#: ../../../CHANGES.rst:59 +msgid "" +"``Session.change_context()`` now supports the same argument/keyword " +"arguments semantics than ``odoo.model.BaseModel.with_context()``." +msgstr "" +"``Session.change_context()`` prend maintenant en charge la même sémantique " +"d'arguments que ``odoo.model.BaseModel.with_context()``." + +#: ../../../CHANGES.rst:62 +msgid "Renamed ``ExportSynchronizer`` to ``Exporter``" +msgstr "Renommage de ``ExportSynchronizer`` vers ``Exporter``" + +#: ../../../CHANGES.rst:63 +msgid "Renamed ``ImportSynchronizer`` to ``Importer``" +msgstr "Renommage de ``ImportSynchronizer`` vers ``Importer``" + +#: ../../../CHANGES.rst:64 +msgid "Renamed ``DeleteSynchronizer`` to ``Deleter``" +msgstr "Renommage de ``DeleteSynchronizer`` vers ``Deleter``" + +#: ../../../CHANGES.rst:65 +msgid "``Session.commit`` do not commit when tests are running" +msgstr "``Session.commit`` ne commite pas pendant les tests" + +#: ../../../CHANGES.rst:66 +msgid "Cleaned the methods that have been deprecated in version 2.x" +msgstr "Nettoyage des méthodes dépréciées en version 2.x" + +#: ../../../CHANGES.rst:70 +msgid "2.2.0 (2014-05-26)" +msgstr "2.2.0 (2014-05-26)" + +#: ../../../CHANGES.rst:72 +msgid "" +"Job arguments can now contain unicode strings (thanks to Stéphane Bidoul) " +"lp:1288187" +msgstr "" +"Les arguments d'un Job peuvent maintenant contenir des chaînes unicode " +"(merci à Stéphane Bidoul) lp:1288187" + +#: ../../../CHANGES.rst:73 +msgid "List view of the jobs improved" +msgstr "Amélioration de la vue en liste des jobs" + +#: ../../../CHANGES.rst:74 +msgid "" +"Jobs now support multicompany (thanks to Laurent Mignon) https://lists." +"launchpad.net/odoo-connector-community/msg00253.html)" +msgstr "" +"Les jobs fonctionnement maintenant en multi-sociétés (merci à Laurent " +"Mignon) https://lists.launchpad.net/odoo-connector-community/msg00253." +"html)" + +#: ../../../CHANGES.rst:75 +msgid "" +"An action can be assigned to a job. The action is called with a button on " +"the job and could be something like open a form view or an url." +msgstr "" +"Une action peut être affectée à un job. L'action est appelée via un bouton " +"sur le job et peut appeler une ouverture de formulaire ou une URL." + +#: ../../../CHANGES.rst:78 +msgid "2.1.1 (2014-02-06)" +msgstr "2.1.1 (2014-02-06)" + +#: ../../../CHANGES.rst:80 +msgid "" +"A user can be blocked because he has no access to the model queue.job when a " +"job has been delayed. The creation of a job is low level and should not be " +"restrained by the accesses of the user. (lp:1276182)" +msgstr "" +"Un utilisateur peut être bloqué s'il n'a pas accès au modèle queue.job quand " +"un job a été retardé. La création d'un job est à bas niveau et ne devrait " +"pas être contrainte par les accès de l'utilisateur. (lp:1276182)" + +#: ../../../CHANGES.rst:85 +msgid "2.1.0 (2014-01-15 - warning: breaks compatibility)" +msgstr "2.1.0 (2014-01-15 - attention : rupture de compatibilité)" + +#: ../../../CHANGES.rst:87 +msgid "" +"Add a new optional keyword argument 'description' to the delay() function of " +"a job. If given, the description is used as name of the queue.job record " +"stored in Odoo and displayed in the list of jobs." +msgstr "" +"Ajout d'un nouvel argument nommé 'description' pour la fonction delay() d'un " +"job. Si fournie, la description est utilisée comme nom pour " +"l'enregistrement ``queue.job`` stocké dans Odoo et affiché dans la liste " +"des jobs." + +#: ../../../CHANGES.rst:90 +msgid "" +"Fix: assignment of jobs to workers respect the priority of the jobs " +"(lp:1252681)" +msgstr "" +"Correction: l'affectation des jobs aux workers respecte la priorité des jobs " +"(lp:1252681)" + +#: ../../../CHANGES.rst:91 +msgid "" +"Pass a new parameter to listeners of 'on_record_create' ( vals: field " +"values of the new record, e.g {'field_name': field_value, ...})" +msgstr "" +"Passage d'un nouveau paramètre aux abonnés à 'on_record_create' ( vals: " +"valeurs du champ du nouvel enregistrement, par ex : {'field_name': " +"field_value, ...})" + +#: ../../../CHANGES.rst:93 +msgid "" +"Replace the list of updated fields passed to listeners of 'on_record_write' " +"by a dictionary of updated field values e.g {'field_name': field_value, ...}" +msgstr "" +"Remplacement de la liste des champs modifiés transmis aux abonnés à " +"'on_record_write' par un dictionnaire des valeurs des champs modifiés. Par " +"ex : {'field_name': field_value, ...}" + +#: ../../../CHANGES.rst:95 +msgid "" +"Add the possibility to use 'Modifiers' functions in the 'direct " +"mappings' (details in the documentation of the Mapper class)" +msgstr "" +"Ajout de la possibilité d'utiliser des fonctions 'Modificatrices' dans les " +"'mappings directs' (détails dans la documentation de la classe Mapper)" + +#: ../../../CHANGES.rst:97 +msgid "" +"When a job a delayed, the job's UUID is returned by the delay() function" +msgstr "" +"Quand un job est retardé, le UUID du job est renvoyé par la fonction delay()" + +#: ../../../CHANGES.rst:98 +msgid "" +"Refactoring of mappers. Much details here: https://code.launchpad.net/" +"~odoo-connector-core-editors/odoo-connector/7.0-connector-mapper-" +"refactor/+merge/194485" +msgstr "" +"Refactorisation des mappers. Plus de détails ici : https://code.launchpad." +"net/~odoo-connector-core-editors/odoo-connector/7.0-connector-mapper-" +"refactor/+merge/194485" + +#: ../../../CHANGES.rst:102 +msgid "2.0.1 (2013-09-12)" +msgstr "2.0.1 (2013-09-12)" + +#: ../../../CHANGES.rst:104 +msgid "" +"Developers of addons do no longer need to create an AbstractModel with a " +"_name 'name_of_the_module.installed', instead, they just have to call " +"connector.connector.install_in_connector() lp:1196859" +msgstr "" +"Les développeurs d'addons n'ont plus besoin de créer un AbstractModel avec " +"un _name 'nom_module.installed', ils doivent simplement appeler ``connector." +"connector.install_in_connector()`` lp:1196859" + +#: ../../../CHANGES.rst:106 +msgid "" +"Added a script `odoo-connector-worker` to start processes for Jobs " +"Workers when running Odoo is multiprocessing" +msgstr "" +"Ajout d'un script `odoo-connector-worker` pour lancer les processus des " +"workers de jobs en fonctionnement multi-processus d'Odoo" + +#: ../../../CHANGES.rst:108 +msgid "" +"Fix: do no fail to start when Odoo has access to a not-Odoo database " +"(lp:1233388)" +msgstr "" +"Correction : n'échoue pas au démarrage quand Odoo a accès à une base de " +"données non-Odoo (lp:1233388)" + +#: ../../../CHANGES.rst:112 +msgid "2.0.0" +msgstr "2.0.0" + +#: ../../../CHANGES.rst:114 +msgid "First release" +msgstr "Première version" + +#: ../../project/contribute.rst:5 +msgid "Contribute" +msgstr "Contribuer" + +#: ../../project/contribute.rst:7 +msgid "We accept with pleasure all type of contributions:" +msgstr "Nous acceptons avec plaisir tous types de contributions :" + +#: ../../project/contribute.rst:9 +msgid "bug reports" +msgstr "Signalement d'anomalies" + +#: ../../project/contribute.rst:10 +msgid "merge proposals" +msgstr "Propositions de corrections" + +#: ../../project/contribute.rst:11 +msgid "ideas" +msgstr "idées" + +#: ../../project/contribute.rst:12 +msgid "translations" +msgstr "traductions" + +#: ../../project/contribute.rst:13 +msgid "..." +msgstr "..." + +#: ../../project/contribute.rst:15 +msgid "" +"Have a look on the :ref:`Magento Connector Developer's Guide " +"` which is more complete, most of the " +"information is the same." +msgstr "" +"Jetez un œil au :ref:`Guide du développeur du Connecteur Magento " +"` qui est plus complet, la plupart des " +"informations sont les mêmes." + +#: ../../project/contribute.rst:19 +msgid "The GitHub project is: https://github.com/OCA/connector" +msgstr "Le projet GitHub est : https://github.com/OCA/connector" + +#: ../../project/contribute.rst:23 +msgid "Want to start a new connector" +msgstr "Démarrer un nouveau connecteur" + +#: ../../project/contribute.rst:25 +msgid "" +"If you want to start a new connector based on the framework, a sane approach " +"is to read this documentation, especially :ref:`concepts` and :ref:" +"`bootstrap-connector`." +msgstr "" +"Si vous voulez fabriquer un nouveau connecteur basé sur le framework, " +"l'approche conseillée est de lire cette documentation, en particulier les :" +"ref:`concepts` et :ref:`bootstrap-connector`." + +#: ../../project/contribute.rst:33 +msgid "" +"If the connector belongs to the e-commerce domain, you may want to reuse the " +"pieces of the `E-Commerce Connector`_ module." +msgstr "" +"Si le connecteur est dans le domaine e-commerce, vous devriez réutiliser les " +"composants du module `E-Commerce Connector`_." + +#: ../../project/contribute.rst:39 +msgid "Naming conventions" +msgstr "Conventions de nommage" + +#: ../../project/contribute.rst:41 +msgid "The naming conventions for the new projects are the following:" +msgstr "" +"Les conventions de nommage pour les nouveaux projets sont les suivantes :" + +#: ../../project/contribute.rst:43 +msgid "Name of the project if it is in the OCA:" +msgstr "Nom du projet s'il est dans l'OCA :" + +#: ../../project/contribute.rst:45 +msgid "connector-xxx" +msgstr "connector-xxx" + +#: ../../project/contribute.rst:48 +msgid "connector_xxx" +msgstr "connector_xxx" + +#: ../../project/contribute.rst:53 +msgid "Example:" +msgstr "Exemple :" + +#: ../../project/contribute.rst:51 +msgid "https://github.com/OCA/connector-magento" +msgstr "https://github.com/OCA/connector-magento" + +#: ../../project/contribute.rst:53 +msgid "``connector_magento``" +msgstr "``connector_magento``" + +#: ../../project/contribute.rst:55 +msgid "" +"Actually, the Magento and Prestashop connectors do not respect this " +"convention for historical reasons (magentoerpconnect, prestashoperpconnect). " +"New projects should ideally respect it." +msgstr "" +"En réalité les connecteurs Magento et Prestashop ne respectent pas cette " +"convention pour des raisons historiques (magentoerpconnect, " +"prestashoperpconnect). Les nouveaux projets devraient idéalement la " +"respecter." + +#: ../../project/contributors.rst:5 +msgid "Contributors" +msgstr "Contributeurs" + +#: ../../project/contributors.rst:7 +msgid "List of contributors:" +msgstr "Liste des contributeurs :" + +#: ../../../AUTHORS:1 +msgid "Guewen Baconnier at Camptocamp" +msgstr "Guewen Baconnier chez Camptocamp" + +#: ../../../AUTHORS:2 +msgid "Alexandre Fayolle at Camptocamp" +msgstr "Alexandre Fayolle chez Camptocamp" + +#: ../../../AUTHORS:3 +msgid "Benoit Guillot at Akretion" +msgstr "Benoit Guillot chez Akretion" + +#: ../../../AUTHORS:4 +msgid "Nicolas Bessi at Camptocamp (tiny change)" +msgstr "Nicolas Bessi chez Camptocamp (changement minuscule)" + +#: ../../../AUTHORS:5 +msgid "Joël Grand-Guillaume at Camptocamp (tiny change)" +msgstr "Joël Grand-Guillaume chez Camptocamp (changement minuscule)" + +#: ../../../AUTHORS:6 +msgid "Arthur Vuillard at Akretion (tiny change)" +msgstr "Arthur Vuillard chez Akretion (changement minuscule)" + +#: ../../../AUTHORS:7 +msgid "Sebastien Beau at Akretion (tiny change)" +msgstr "Sebastien Beau chez Akretion (changement minuscule)" + +#: ../../../AUTHORS:8 +msgid "Laurent Mignon at Acsone" +msgstr "Laurent Mignon chez Acsone" + +#: ../../../AUTHORS:9 +msgid "Leonardo Pistone at Camptocamp" +msgstr "Leonardo Pistone chez Camptocamp" + +#: ../../../AUTHORS:10 +msgid "David Béal at Akretion (tiny change)" +msgstr "David Béal chez Akretion (changement minuscule)" + +#: ../../project/contributors.rst:16 +msgid "Financial Contributors" +msgstr "Contributeurs financiers" + +#: ../../project/contributors.rst:18 +msgid "" +"A fund raising has been done during the year 2013, allowing us to develop " +"the connector framework and the Magento connector." +msgstr "" +"Une levée de fond a été réalisée en 2013, et a permis de développer le " +"framework Connecteur et le Connecteur Magento." + +#: ../../project/contributors.rst:21 +msgid "" +"Here is the list of the funders, ordered by the amount of the contribution:" +msgstr "Voici la liste des fondateurs, classée par volume de contribution :" + +#: ../../project/contributors.rst:23 +msgid "**Logic Supply**" +msgstr "**Logic Supply**" + +#: ../../project/contributors.rst:24 +msgid "**Debonix**" +msgstr "**Debonix**" + +#: ../../project/contributors.rst:25 +msgid "Apertoso" +msgstr "Apertoso" + +#: ../../project/contributors.rst:26 +msgid "OpenBIG" +msgstr "OpenBIG" + +#: ../../project/contributors.rst:27 +msgid "Smile" +msgstr "Smile" + +#: ../../project/contributors.rst:28 +msgid "IT Service Partners" +msgstr "IT Service Partners" + +#: ../../project/contributors.rst:29 +msgid "WillowIT" +msgstr "WillowIT" + +#: ../../project/contributors.rst:30 +msgid "Eezee-It" +msgstr "Eezee-It" + +#: ../../project/contributors.rst:31 +msgid "Auguria" +msgstr "Auguria" + +#: ../../project/contributors.rst:32 +msgid "Enova" +msgstr "Enova" + +#: ../../project/contributors.rst:33 +msgid "Mr. Goran Sunjka" +msgstr "M. Goran Sunjka" + +#: ../../project/contributors.rst:34 +msgid "Taktik" +msgstr "Taktik" + +#: ../../project/contributors.rst:35 +msgid "Maison del Gusto" +msgstr "Maison del Gusto" + +#: ../../project/contributors.rst:36 +msgid "Open2bizz Software" +msgstr "Open2bizz Software" + +#: ../../project/contributors.rst:37 +msgid "Bee Company" +msgstr "Bee Company" + +#: ../../project/contributors.rst:38 +msgid "initOS" +msgstr "initOS" + +#: ../../project/contributors.rst:39 +msgid "Rhônalia" +msgstr "Rhônalia" + +#: ../../project/contributors.rst:40 +msgid "Julius Network Solutions" +msgstr "Julius Network Solutions" + +#: ../../project/contributors.rst:41 +msgid "Elico Corp" +msgstr "Elico Corp" + +#: ../../project/contributors.rst:42 +msgid "Linko Solutions" +msgstr "Linko Solutions" + +#: ../../project/contributors.rst:43 +msgid "HSP Hanse Shopping" +msgstr "HSP Hanse Shopping" + +#: ../../project/contributors.rst:44 +msgid "Burn Out Italy" +msgstr "Burn Out Italy" + +#: ../../project/contributors.rst:45 +msgid "Mr. Peter Dijkstra" +msgstr "M. Peter Dijkstra" + +#: ../../project/contributors.rst:46 +msgid "Mr. Luc Maurer" +msgstr "M. Luc Maurer" + +#: ../../project/contributors.rst:47 +msgid "Mr. Maxime Chambreuil" +msgstr "M. Maxime Chambreuil" + +#: ../../project/contributors.rst:48 +msgid "Mr. Eric Vernichon" +msgstr "M. Eric Vernichon" + +#: ../../project/contributors.rst:49 +msgid "Avanzosc" +msgstr "Avanzosc" + +#: ../../project/contributors.rst:50 +msgid "Mr. Fabio Martinelli" +msgstr "M. Fabio Martinelli" + +#: ../../project/contributors.rst:51 +msgid "Mr. Marcelo Bello" +msgstr "M. Marcelo Bello" + +#: ../../project/contributors.rst:52 +msgid "Rove.design" +msgstr "Rove.design" + +#: ../../project/contributors.rst:53 +msgid "Mr. Mark Felling" +msgstr "M. Mark Felling" + +#: ../../project/contributors.rst:55 +msgid "Thanks to all of them!" +msgstr "Merci à eux !" + +#: ../../project/license.rst:5 +msgid "License" +msgstr "Licence" + +#: ../../project/license.rst:7 +msgid "This work is licensed under the AGPL3 license." +msgstr "Ce travail est publié sous licence AGPL3." + +#: ../../project/roadmap.rst:5 +msgid "Roadmap" +msgstr "Roadmap" + +#: ../../project/roadmap.rst:7 +msgid "Here is a list of things we may agree to merge." +msgstr "Voici une liste de choses qu'on peut s'accorder à intégrer" + +#: ../../project/roadmap.rst:9 +msgid "Queue: use PostgreSQL `notify` for direct enqueue of jobs" +msgstr "" +"Queue : utiliser `notify` de PostgreSQL pour une mise en queue directe des " +"jobs" + +#: ../../project/roadmap.rst:13 +msgid "" +"Add facilities to parse the errors from the jobs so we can replace it by " +"more contextual and helpful errors." +msgstr "" +"Ajouter des facilités pour analyser les erreurs des jobs pour pouvoir les " +"remplacer par des erreurs plus contextuelles et utiles" + +#: ../../project/roadmap.rst:16 +msgid "" +"A logger which keeps in a buffer all the logs and flushes them when an error " +"occurs in a synchronization, clears them if it succeeded" +msgstr "" +"Un `logger` qui garde en tampon tous les logs et les vide quand une erreur " +"survient pendant une synchronisation, et les efface s'ils ont réussi" + +#: ../../project/roadmap.rst:19 +msgid "" +"Job Channels: each job is owned by a channel and workers can be dedicated to " +"one channel only" +msgstr "" +"Canal de job : chaque job appartient à un canal et les workers peuvent être " +"dédiés à un canal" + +#: ../../../CHANGES.rst:107 +msgid "" +"Fix: inheritance broken when an orm.Model inherit from an orm.AbstractModel. " +"One effect was that the mail.thread features were no longer working " +"(lp:1233355)" +msgstr "" +"Correction : héritage cassé quand un orm.Model hérite d'un orm." +"AbstractModel. Un effet était que les fonctionnalités de mail.thread ne " +"fonctionnaient plus (lp:1233355)" + +#: ../../../AUTHORS:11 +msgid "Christophe Combelles at Anybox (french translation)" +msgstr "Christophe Combelles chez Anybox (trad française)" + +#: ../../project/contribute.rst:65 +msgid "Creating or maintaining a translation of this doc" +msgstr "Créer ou maintenir une traduction de cette doc" + +#: ../../project/contribute.rst:67 +msgid "" +"Install Odoo, its dependencies, sphinx, sphinx_bootstrap_theme and sphinx-" +"intl" +msgstr "" +"Installez Odoo, ses dépendances, sphinx, sphinx_bootstrap_theme et sphinx-" +"intl" + +#: ../../project/contribute.rst:72 +msgid "create an empty database with the connector module installed" +msgstr "créez une nouvelle base de donnée avec le module connector installé" + +#: ../../project/contribute.rst:73 +msgid "``cd connector/doc``" +msgstr "``cd connector/doc``" + +#: ../../project/contribute.rst:74 +msgid "rebuild the gettext .pot source catalogs: ``make gettext``" +msgstr "reconstruisez les catalogues gettext sources .pot: ``make gettext``" + +#: ../../project/contribute.rst:75 +msgid "" +"update the .po translation files from the latest .pot files (here for " +"language 'fr'): ``sphinx-intl update -l fr -p _build/locale``" +msgstr "" +"mettez à jour les fichiers de traduction .po depuis les derniers fichiers ." +"pot (ici pour la langue 'fr'): ``sphinx-intl update -l fr -p _build/locale``" + +#: ../../project/contribute.rst:77 +msgid "" +"create or edit the translation in the .po files: ``poedit locale/fr/" +"LC_MESSAGES/*.po``" +msgstr "" +"créez ou modifiez la traduction dans les fichiers .po : ``poedit locale/fr/" +"LC_MESSAGES/*.po``" + +#: ../../project/contribute.rst:79 +msgid "compile the .po files into .mo files: ``sphinx-intl build``" +msgstr "compilez les fichiers .po en fichiers .mo : ``sphinx-intl build``" + +#: ../../project/contribute.rst:80 +msgid "" +"build the translated documentation to html: ``make SPHINXOPTS=\"-Dlanguage=fr" +"\" html``" +msgstr "" +"construisez en html la documentation traduite : ``make SPHINXOPTS=\"-" +"Dlanguage=fr\" html``" + +#: ../../project/contribute.rst:83 +msgid "" +"The same using a `buildout `_::" +msgstr "" +"La même chose en utilisant un `buildout `_::" + +#: ../../project/contribute.rst:69 +msgid "" +"Add `this patch `_ to sphinx-intl (until merged) to support *fuzzy* translations" +msgstr "" +"Ajoutez `ce patch `_ à sphinx-intl (jusqu'à ce que ce soit mergé) pour gérer les " +"traductions *fuzzy*" + +#: ../../project/contribute.rst:29 +msgid "" +"Then, my personal advice is to look at the existing connectors (`Odoo " +"Magento Connector`_, `Odoo Prestashop Connector`_). You will also probably " +"need to dive a bit in the framework's code." +msgstr "" +"Ensuite, il est conseillé de parcourir les connecteurs existants " +"(`Connecteur Odoo Magento`_, `Connecteur Odoo Prestashop`_). Vous devrez " +"aussi plonger peut-être un peu dans le code du framework." + +#: ../../project/contribute.rst:48 +msgid "Name of the Odoo module:" +msgstr "Nom du module Odoo :" + +#: ../../project/contribute.rst:100 +msgid "" +"Then you can see the result in _build/html/ and submit a Pull Request. " +"Repeat the 5 last steps to update the translation if modified upstream." +msgstr "" +"Vous pouvez ensuite voir le résultat dans _build/html/ et soumettre un " +"\"Pull Request\". Répétez les 5 dernières étapes pour remettre à jour les " +"traductions en cas de modification dans le tronc principal." + +#: ../../project/roadmap.rst:11 ../../project/roadmap.rst:22 +msgid "See: https://github.com/OCA/connector/pull/52" +msgstr "See: https://github.com/OCA/connector/pull/52" + +#~ msgid "" +#~ "Then, my personal advice is to look at the existing connectors (`Odoo " +#~ "Magento Connector`_, `Odoo Prestashop Connector`_). You will also " +#~ "probably need to dive a bit in the framework's code." +#~ msgstr "" +#~ "Ensuite, il est conseillé de parcourir les connecteurs existants " +#~ "(`Connecteur Odoo Magento`_, `Connecteur Odoo Prestashop`_). Vous " +#~ "devrez aussi plonger peut-être un peu dans le code du framework." + +#~ msgid "Name of the Odoo module:" +#~ msgstr "Nom du module Odoo :" + +#~ msgid "" +#~ "Experimental branch: lp:~odoo-connector-core-editors/odoo-" +#~ "connector/7.0-connector-pg-notify-listen-experimental" +#~ msgstr "" +#~ "Branche expérimentale : lp:~odoo-connector-core-editors/odoo-" +#~ "connector/7.0-connector-pg-notify-listen-experimental" + +#~ msgid "" +#~ "Then you can see the result in _build/html/ and submit a Pull Request" +#~ msgstr "" +#~ "Vous pouvez ensuite voir le résultat dans _build/html/ et soumettre un " +#~ "Pull Request" + +#~ msgid "" +#~ "Add `this patch `_ to sphinx-intl (until " +#~ "merged)" +#~ msgstr "" +#~ "Ajoutez `ce patch `_ to sphinx-intl (jusqu'à " +#~ "ce qu'il soit mergé)" + +#~ msgid "" +#~ "Fix: inheritance broken when an orm.Model inherit from an or." +#~ "AbstractModel. One effect was that the mail.thread features were no " +#~ "longer working (lp:1233355)" +#~ msgstr "" +#~ "Correction : héritage cassé quand un orm.Model hérite d'un or." +#~ "AbstractModel. Une conséquence est que les fonctionnalités de mail.thread " +#~ "ne fonctionnaient plus (lp:1233355)" diff --git a/ext/3rd-party-addons/connector/doc/make.bat b/ext/3rd-party-addons/connector/doc/make.bat new file mode 100644 index 00000000..3b846632 --- /dev/null +++ b/ext/3rd-party-addons/connector/doc/make.bat @@ -0,0 +1,190 @@ +@ECHO OFF + +REM Command file for Sphinx documentation + +if "%SPHINXBUILD%" == "" ( + set SPHINXBUILD=sphinx-build +) +set BUILDDIR=_build +set ALLSPHINXOPTS=-d %BUILDDIR%/doctrees %SPHINXOPTS% . +set I18NSPHINXOPTS=%SPHINXOPTS% . +if NOT "%PAPER%" == "" ( + set ALLSPHINXOPTS=-D latex_paper_size=%PAPER% %ALLSPHINXOPTS% + set I18NSPHINXOPTS=-D latex_paper_size=%PAPER% %I18NSPHINXOPTS% +) + +if "%1" == "" goto help + +if "%1" == "help" ( + :help + echo.Please use `make ^` where ^ is one of + echo. html to make standalone HTML files + echo. dirhtml to make HTML files named index.html in directories + echo. singlehtml to make a single large HTML file + echo. pickle to make pickle files + echo. json to make JSON files + echo. htmlhelp to make HTML files and a HTML help project + echo. qthelp to make HTML files and a qthelp project + echo. devhelp to make HTML files and a Devhelp project + echo. epub to make an epub + echo. latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter + echo. text to make text files + echo. man to make manual pages + echo. texinfo to make Texinfo files + echo. gettext to make PO message catalogs + echo. changes to make an overview over all changed/added/deprecated items + echo. linkcheck to check all external links for integrity + echo. doctest to run all doctests embedded in the documentation if enabled + goto end +) + +if "%1" == "clean" ( + for /d %%i in (%BUILDDIR%\*) do rmdir /q /s %%i + del /q /s %BUILDDIR%\* + goto end +) + +if "%1" == "html" ( + %SPHINXBUILD% -b html %ALLSPHINXOPTS% %BUILDDIR%/html + if errorlevel 1 exit /b 1 + echo. + echo.Build finished. The HTML pages are in %BUILDDIR%/html. + goto end +) + +if "%1" == "dirhtml" ( + %SPHINXBUILD% -b dirhtml %ALLSPHINXOPTS% %BUILDDIR%/dirhtml + if errorlevel 1 exit /b 1 + echo. + echo.Build finished. The HTML pages are in %BUILDDIR%/dirhtml. + goto end +) + +if "%1" == "singlehtml" ( + %SPHINXBUILD% -b singlehtml %ALLSPHINXOPTS% %BUILDDIR%/singlehtml + if errorlevel 1 exit /b 1 + echo. + echo.Build finished. The HTML pages are in %BUILDDIR%/singlehtml. + goto end +) + +if "%1" == "pickle" ( + %SPHINXBUILD% -b pickle %ALLSPHINXOPTS% %BUILDDIR%/pickle + if errorlevel 1 exit /b 1 + echo. + echo.Build finished; now you can process the pickle files. + goto end +) + +if "%1" == "json" ( + %SPHINXBUILD% -b json %ALLSPHINXOPTS% %BUILDDIR%/json + if errorlevel 1 exit /b 1 + echo. + echo.Build finished; now you can process the JSON files. + goto end +) + +if "%1" == "htmlhelp" ( + %SPHINXBUILD% -b htmlhelp %ALLSPHINXOPTS% %BUILDDIR%/htmlhelp + if errorlevel 1 exit /b 1 + echo. + echo.Build finished; now you can run HTML Help Workshop with the ^ +.hhp project file in %BUILDDIR%/htmlhelp. + goto end +) + +if "%1" == "qthelp" ( + %SPHINXBUILD% -b qthelp %ALLSPHINXOPTS% %BUILDDIR%/qthelp + if errorlevel 1 exit /b 1 + echo. + echo.Build finished; now you can run "qcollectiongenerator" with the ^ +.qhcp project file in %BUILDDIR%/qthelp, like this: + echo.^> qcollectiongenerator %BUILDDIR%\qthelp\Connectors.qhcp + echo.To view the help file: + echo.^> assistant -collectionFile %BUILDDIR%\qthelp\Connectors.ghc + goto end +) + +if "%1" == "devhelp" ( + %SPHINXBUILD% -b devhelp %ALLSPHINXOPTS% %BUILDDIR%/devhelp + if errorlevel 1 exit /b 1 + echo. + echo.Build finished. + goto end +) + +if "%1" == "epub" ( + %SPHINXBUILD% -b epub %ALLSPHINXOPTS% %BUILDDIR%/epub + if errorlevel 1 exit /b 1 + echo. + echo.Build finished. The epub file is in %BUILDDIR%/epub. + goto end +) + +if "%1" == "latex" ( + %SPHINXBUILD% -b latex %ALLSPHINXOPTS% %BUILDDIR%/latex + if errorlevel 1 exit /b 1 + echo. + echo.Build finished; the LaTeX files are in %BUILDDIR%/latex. + goto end +) + +if "%1" == "text" ( + %SPHINXBUILD% -b text %ALLSPHINXOPTS% %BUILDDIR%/text + if errorlevel 1 exit /b 1 + echo. + echo.Build finished. The text files are in %BUILDDIR%/text. + goto end +) + +if "%1" == "man" ( + %SPHINXBUILD% -b man %ALLSPHINXOPTS% %BUILDDIR%/man + if errorlevel 1 exit /b 1 + echo. + echo.Build finished. The manual pages are in %BUILDDIR%/man. + goto end +) + +if "%1" == "texinfo" ( + %SPHINXBUILD% -b texinfo %ALLSPHINXOPTS% %BUILDDIR%/texinfo + if errorlevel 1 exit /b 1 + echo. + echo.Build finished. The Texinfo files are in %BUILDDIR%/texinfo. + goto end +) + +if "%1" == "gettext" ( + %SPHINXBUILD% -b gettext %I18NSPHINXOPTS% %BUILDDIR%/locale + if errorlevel 1 exit /b 1 + echo. + echo.Build finished. The message catalogs are in %BUILDDIR%/locale. + goto end +) + +if "%1" == "changes" ( + %SPHINXBUILD% -b changes %ALLSPHINXOPTS% %BUILDDIR%/changes + if errorlevel 1 exit /b 1 + echo. + echo.The overview file is in %BUILDDIR%/changes. + goto end +) + +if "%1" == "linkcheck" ( + %SPHINXBUILD% -b linkcheck %ALLSPHINXOPTS% %BUILDDIR%/linkcheck + if errorlevel 1 exit /b 1 + echo. + echo.Link check complete; look for any errors in the above output ^ +or in %BUILDDIR%/linkcheck/output.txt. + goto end +) + +if "%1" == "doctest" ( + %SPHINXBUILD% -b doctest %ALLSPHINXOPTS% %BUILDDIR%/doctest + if errorlevel 1 exit /b 1 + echo. + echo.Testing of doctests in the sources finished, look at the ^ +results in %BUILDDIR%/doctest/output.txt. + goto end +) + +:end diff --git a/ext/3rd-party-addons/connector/doc/project/changes.rst b/ext/3rd-party-addons/connector/doc/project/changes.rst new file mode 100644 index 00000000..31f01c6d --- /dev/null +++ b/ext/3rd-party-addons/connector/doc/project/changes.rst @@ -0,0 +1,9 @@ +.. _changes: + +####### +Changes +####### + +.. include:: ../../CHANGES.rst + :start-line: 3 + diff --git a/ext/3rd-party-addons/connector/doc/project/contribute.rst b/ext/3rd-party-addons/connector/doc/project/contribute.rst new file mode 100644 index 00000000..fd47353a --- /dev/null +++ b/ext/3rd-party-addons/connector/doc/project/contribute.rst @@ -0,0 +1,100 @@ +.. _contribute: + +########## +Contribute +########## + +We accept with pleasure all type of contributions: + +* bug reports +* merge proposals +* ideas +* translations +* ... + +Have a look on the :ref:`Magento Connector Developer's Guide +` which is more complete, most of the +information is the same. + +The GitHub project is: https://github.com/OCA/connector + +***************************** +Want to start a new connector +***************************** + +If you want to start a new connector based on the framework, +a sane approach is to read this documentation, especially +:ref:`concepts` and :ref:`bootstrap-connector`. + +Then, my personal advice is to look at the existing connectors (`Odoo +Magento Connector`_, `Odoo Prestashop Connector`_). You will also probably +need to dive a bit in the framework's code. + +If the connector belongs to the e-commerce domain, you may want to reuse the pieces +of the `E-Commerce Connector`_ module. + +.. _naming-convention: + +Naming conventions +================== + +The naming conventions for the new projects are the following: + +Name of the project if it is in the OCA: + + connector-xxx + +Name of the Odoo module: + connector_xxx + +Example: + https://github.com/OCA/connector-magento + + ``connector_magento`` + +Actually, the Magento and Prestashop connectors do not respect this convention +for historical reasons (magentoerpconnect, prestashoperpconnect). +New projects should ideally respect it. + +.. _`Odoo Magento Connector`: https://github.com/OCA/connector-magento +.. _`Odoo Prestashop Connector`: https://github.com/OCA/connector-prestashop +.. _`E-Commerce Connector`: https://github.com/OCA/connector-ecommerce + +************************************************* +Creating or maintaining a translation of this doc +************************************************* + +- Install Odoo, its dependencies, sphinx, sphinx_bootstrap_theme and + sphinx-intl +- Add `this patch + `_ + to sphinx-intl (until merged) to support *fuzzy* translations +- create an empty database with the connector module installed +- ``cd connector/doc`` +- rebuild the gettext .pot source catalogs: ``make gettext`` +- update the .po translation files from the latest .pot files (here for + language 'fr'): ``sphinx-intl update -l fr -p _build/locale`` +- create or edit the translation in the .po files: ``poedit + locale/fr/LC_MESSAGES/*.po`` +- compile the .po files into .mo files: ``sphinx-intl build`` +- build the translated documentation to html: ``make SPHINXOPTS="-Dlanguage=fr" + html`` + +The same using a `buildout +`_:: + + $ mkdir buildout && cd buildout + $ wget https://bitbucket.org/anybox/public_buildbot_buildouts/raw/tip/odoo-connector.cfg -O buildout.cfg + $ wget https://bitbucket.org/anybox/public_buildbot_buildouts/raw/tip/bootstrap.py + $ python bootstrap.py + $ bin/buildout + $ createdb connectordb + $ bin/start_odoo -d connectordb --stop-after-init + $ cd connector/connector/doc/ + $ ../../../bin/sphinx-build -d connectordb -- -b gettext ./ _build/locale/ + $ ../../../bin/sphinx-intl -d connectordb -- update -l fr -p _build/locale/ + $ poedit locale/fr/LC_MESSAGES/*po + $ ../../../bin/sphinx-intl -d connectordb -- build + $ ../../../bin/sphinx-build -d connectordb -- -D language=fr -b html ./ _build/html/ + +Then you can see the result in _build/html/ and submit a Pull Request. Repeat the 5 last steps to update the translation if modified upstream. diff --git a/ext/3rd-party-addons/connector/doc/project/contributors.rst b/ext/3rd-party-addons/connector/doc/project/contributors.rst new file mode 100644 index 00000000..a115cdf2 --- /dev/null +++ b/ext/3rd-party-addons/connector/doc/project/contributors.rst @@ -0,0 +1,55 @@ +.. _contributors: + +############ +Contributors +############ + +List of contributors: + +.. include:: ../../AUTHORS + + +.. _financial-contributors: + +###################### +Financial Contributors +###################### + +A fund raising has been done during the year 2013, allowing us to develop +the connector framework and the Magento connector. + +Here is the list of the funders, ordered by the amount of the contribution: + +* **Logic Supply** +* **Debonix** +* Apertoso +* OpenBIG +* Smile +* IT Service Partners +* WillowIT +* Eezee-It +* Auguria +* Enova +* Mr. Goran Sunjka +* Taktik +* Maison del Gusto +* Open2bizz Software +* Bee Company +* initOS +* Rhônalia +* Julius Network Solutions +* Elico Corp +* Linko Solutions +* HSP Hanse Shopping +* Burn Out Italy +* Mr. Peter Dijkstra +* Mr. Luc Maurer +* Mr. Maxime Chambreuil +* Mr. Eric Vernichon +* Avanzosc +* Mr. Fabio Martinelli +* Mr. Marcelo Bello +* Rove.design +* Mr. Mark Felling + +Thanks to all of them! diff --git a/ext/3rd-party-addons/connector/doc/project/license.rst b/ext/3rd-party-addons/connector/doc/project/license.rst new file mode 100644 index 00000000..e0a030b0 --- /dev/null +++ b/ext/3rd-party-addons/connector/doc/project/license.rst @@ -0,0 +1,674 @@ +.. _license: + +####### +License +####### + +This work is licensed under the AGPL3 license. + +------ + +.. code-block:: none + + + GNU AFFERO GENERAL PUBLIC LICENSE + Version 3, 19 November 2007 + + Copyright (C) 2007 Free Software Foundation, Inc. + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The GNU Affero General Public License is a free, copyleft license for + software and other kinds of works, specifically designed to ensure + cooperation with the community in the case of network server software. + + The licenses for most software and other practical works are designed + to take away your freedom to share and change the works. By contrast, + our General Public Licenses are intended to guarantee your freedom to + share and change all versions of a program--to make sure it remains free + software for all its users. + + When we speak of free software, we are referring to freedom, not + price. Our General Public Licenses are designed to make sure that you + have the freedom to distribute copies of free software (and charge for + them if you wish), that you receive source code or can get it if you + want it, that you can change the software or use pieces of it in new + free programs, and that you know you can do these things. + + Developers that use our General Public Licenses protect your rights + with two steps: (1) assert copyright on the software, and (2) offer + you this License which gives you legal permission to copy, distribute + and/or modify the software. + + A secondary benefit of defending all users' freedom is that + improvements made in alternate versions of the program, if they + receive widespread use, become available for other developers to + incorporate. Many developers of free software are heartened and + encouraged by the resulting cooperation. However, in the case of + software used on network servers, this result may fail to come about. + The GNU General Public License permits making a modified version and + letting the public access it on a server without ever releasing its + source code to the public. + + The GNU Affero General Public License is designed specifically to + ensure that, in such cases, the modified source code becomes available + to the community. It requires the operator of a network server to + provide the source code of the modified version running there to the + users of that server. Therefore, public use of a modified version, on + a publicly accessible server, gives the public access to the source + code of the modified version. + + An older license, called the Affero General Public License and + published by Affero, was designed to accomplish similar goals. This is + a different license, not a version of the Affero GPL, but Affero has + released a new version of the Affero GPL which permits relicensing under + this license. + + The precise terms and conditions for copying, distribution and + modification follow. + + TERMS AND CONDITIONS + + 0. Definitions. + + "This License" refers to version 3 of the GNU Affero General Public License. + + "Copyright" also means copyright-like laws that apply to other kinds of + works, such as semiconductor masks. + + "The Program" refers to any copyrightable work licensed under this + License. Each licensee is addressed as "you". "Licensees" and + "recipients" may be individuals or organizations. + + To "modify" a work means to copy from or adapt all or part of the work + in a fashion requiring copyright permission, other than the making of an + exact copy. The resulting work is called a "modified version" of the + earlier work or a work "based on" the earlier work. + + A "covered work" means either the unmodified Program or a work based + on the Program. + + To "propagate" a work means to do anything with it that, without + permission, would make you directly or secondarily liable for + infringement under applicable copyright law, except executing it on a + computer or modifying a private copy. Propagation includes copying, + distribution (with or without modification), making available to the + public, and in some countries other activities as well. + + To "convey" a work means any kind of propagation that enables other + parties to make or receive copies. Mere interaction with a user through + a computer network, with no transfer of a copy, is not conveying. + + An interactive user interface displays "Appropriate Legal Notices" + to the extent that it includes a convenient and prominently visible + feature that (1) displays an appropriate copyright notice, and (2) + tells the user that there is no warranty for the work (except to the + extent that warranties are provided), that licensees may convey the + work under this License, and how to view a copy of this License. If + the interface presents a list of user commands or options, such as a + menu, a prominent item in the list meets this criterion. + + 1. Source Code. + + The "source code" for a work means the preferred form of the work + for making modifications to it. "Object code" means any non-source + form of a work. + + A "Standard Interface" means an interface that either is an official + standard defined by a recognized standards body, or, in the case of + interfaces specified for a particular programming language, one that + is widely used among developers working in that language. + + The "System Libraries" of an executable work include anything, other + than the work as a whole, that (a) is included in the normal form of + packaging a Major Component, but which is not part of that Major + Component, and (b) serves only to enable use of the work with that + Major Component, or to implement a Standard Interface for which an + implementation is available to the public in source code form. A + "Major Component", in this context, means a major essential component + (kernel, window system, and so on) of the specific operating system + (if any) on which the executable work runs, or a compiler used to + produce the work, or an object code interpreter used to run it. + + The "Corresponding Source" for a work in object code form means all + the source code needed to generate, install, and (for an executable + work) run the object code and to modify the work, including scripts to + control those activities. However, it does not include the work's + System Libraries, or general-purpose tools or generally available free + programs which are used unmodified in performing those activities but + which are not part of the work. For example, Corresponding Source + includes interface definition files associated with source files for + the work, and the source code for shared libraries and dynamically + linked subprograms that the work is specifically designed to require, + such as by intimate data communication or control flow between those + subprograms and other parts of the work. + + The Corresponding Source need not include anything that users + can regenerate automatically from other parts of the Corresponding + Source. + + The Corresponding Source for a work in source code form is that + same work. + + 2. Basic Permissions. + + All rights granted under this License are granted for the term of + copyright on the Program, and are irrevocable provided the stated + conditions are met. This License explicitly affirms your unlimited + permission to run the unmodified Program. The output from running a + covered work is covered by this License only if the output, given its + content, constitutes a covered work. This License acknowledges your + rights of fair use or other equivalent, as provided by copyright law. + + You may make, run and propagate covered works that you do not + convey, without conditions so long as your license otherwise remains + in force. You may convey covered works to others for the sole purpose + of having them make modifications exclusively for you, or provide you + with facilities for running those works, provided that you comply with + the terms of this License in conveying all material for which you do + not control copyright. Those thus making or running the covered works + for you must do so exclusively on your behalf, under your direction + and control, on terms that prohibit them from making any copies of + your copyrighted material outside their relationship with you. + + Conveying under any other circumstances is permitted solely under + the conditions stated below. Sublicensing is not allowed; section 10 + makes it unnecessary. + + 3. Protecting Users' Legal Rights From Anti-Circumvention Law. + + No covered work shall be deemed part of an effective technological + measure under any applicable law fulfilling obligations under article + 11 of the WIPO copyright treaty adopted on 20 December 1996, or + similar laws prohibiting or restricting circumvention of such + measures. + + When you convey a covered work, you waive any legal power to forbid + circumvention of technological measures to the extent such circumvention + is effected by exercising rights under this License with respect to + the covered work, and you disclaim any intention to limit operation or + modification of the work as a means of enforcing, against the work's + users, your or third parties' legal rights to forbid circumvention of + technological measures. + + 4. Conveying Verbatim Copies. + + You may convey verbatim copies of the Program's source code as you + receive it, in any medium, provided that you conspicuously and + appropriately publish on each copy an appropriate copyright notice; + keep intact all notices stating that this License and any + non-permissive terms added in accord with section 7 apply to the code; + keep intact all notices of the absence of any warranty; and give all + recipients a copy of this License along with the Program. + + You may charge any price or no price for each copy that you convey, + and you may offer support or warranty protection for a fee. + + 5. Conveying Modified Source Versions. + + You may convey a work based on the Program, or the modifications to + produce it from the Program, in the form of source code under the + terms of section 4, provided that you also meet all of these conditions: + + a) The work must carry prominent notices stating that you modified + it, and giving a relevant date. + + b) The work must carry prominent notices stating that it is + released under this License and any conditions added under section + 7. This requirement modifies the requirement in section 4 to + "keep intact all notices". + + c) You must license the entire work, as a whole, under this + License to anyone who comes into possession of a copy. This + License will therefore apply, along with any applicable section 7 + additional terms, to the whole of the work, and all its parts, + regardless of how they are packaged. This License gives no + permission to license the work in any other way, but it does not + invalidate such permission if you have separately received it. + + d) If the work has interactive user interfaces, each must display + Appropriate Legal Notices; however, if the Program has interactive + interfaces that do not display Appropriate Legal Notices, your + work need not make them do so. + + A compilation of a covered work with other separate and independent + works, which are not by their nature extensions of the covered work, + and which are not combined with it such as to form a larger program, + in or on a volume of a storage or distribution medium, is called an + "aggregate" if the compilation and its resulting copyright are not + used to limit the access or legal rights of the compilation's users + beyond what the individual works permit. Inclusion of a covered work + in an aggregate does not cause this License to apply to the other + parts of the aggregate. + + 6. Conveying Non-Source Forms. + + You may convey a covered work in object code form under the terms + of sections 4 and 5, provided that you also convey the + machine-readable Corresponding Source under the terms of this License, + in one of these ways: + + a) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by the + Corresponding Source fixed on a durable physical medium + customarily used for software interchange. + + b) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by a + written offer, valid for at least three years and valid for as + long as you offer spare parts or customer support for that product + model, to give anyone who possesses the object code either (1) a + copy of the Corresponding Source for all the software in the + product that is covered by this License, on a durable physical + medium customarily used for software interchange, for a price no + more than your reasonable cost of physically performing this + conveying of source, or (2) access to copy the + Corresponding Source from a network server at no charge. + + c) Convey individual copies of the object code with a copy of the + written offer to provide the Corresponding Source. This + alternative is allowed only occasionally and noncommercially, and + only if you received the object code with such an offer, in accord + with subsection 6b. + + d) Convey the object code by offering access from a designated + place (gratis or for a charge), and offer equivalent access to the + Corresponding Source in the same way through the same place at no + further charge. You need not require recipients to copy the + Corresponding Source along with the object code. If the place to + copy the object code is a network server, the Corresponding Source + may be on a different server (operated by you or a third party) + that supports equivalent copying facilities, provided you maintain + clear directions next to the object code saying where to find the + Corresponding Source. Regardless of what server hosts the + Corresponding Source, you remain obligated to ensure that it is + available for as long as needed to satisfy these requirements. + + e) Convey the object code using peer-to-peer transmission, provided + you inform other peers where the object code and Corresponding + Source of the work are being offered to the general public at no + charge under subsection 6d. + + A separable portion of the object code, whose source code is excluded + from the Corresponding Source as a System Library, need not be + included in conveying the object code work. + + A "User Product" is either (1) a "consumer product", which means any + tangible personal property which is normally used for personal, family, + or household purposes, or (2) anything designed or sold for incorporation + into a dwelling. In determining whether a product is a consumer product, + doubtful cases shall be resolved in favor of coverage. For a particular + product received by a particular user, "normally used" refers to a + typical or common use of that class of product, regardless of the status + of the particular user or of the way in which the particular user + actually uses, or expects or is expected to use, the product. A product + is a consumer product regardless of whether the product has substantial + commercial, industrial or non-consumer uses, unless such uses represent + the only significant mode of use of the product. + + "Installation Information" for a User Product means any methods, + procedures, authorization keys, or other information required to install + and execute modified versions of a covered work in that User Product from + a modified version of its Corresponding Source. The information must + suffice to ensure that the continued functioning of the modified object + code is in no case prevented or interfered with solely because + modification has been made. + + If you convey an object code work under this section in, or with, or + specifically for use in, a User Product, and the conveying occurs as + part of a transaction in which the right of possession and use of the + User Product is transferred to the recipient in perpetuity or for a + fixed term (regardless of how the transaction is characterized), the + Corresponding Source conveyed under this section must be accompanied + by the Installation Information. But this requirement does not apply + if neither you nor any third party retains the ability to install + modified object code on the User Product (for example, the work has + been installed in ROM). + + The requirement to provide Installation Information does not include a + requirement to continue to provide support service, warranty, or updates + for a work that has been modified or installed by the recipient, or for + the User Product in which it has been modified or installed. Access to a + network may be denied when the modification itself materially and + adversely affects the operation of the network or violates the rules and + protocols for communication across the network. + + Corresponding Source conveyed, and Installation Information provided, + in accord with this section must be in a format that is publicly + documented (and with an implementation available to the public in + source code form), and must require no special password or key for + unpacking, reading or copying. + + 7. Additional Terms. + + "Additional permissions" are terms that supplement the terms of this + License by making exceptions from one or more of its conditions. + Additional permissions that are applicable to the entire Program shall + be treated as though they were included in this License, to the extent + that they are valid under applicable law. If additional permissions + apply only to part of the Program, that part may be used separately + under those permissions, but the entire Program remains governed by + this License without regard to the additional permissions. + + When you convey a copy of a covered work, you may at your option + remove any additional permissions from that copy, or from any part of + it. (Additional permissions may be written to require their own + removal in certain cases when you modify the work.) You may place + additional permissions on material, added by you to a covered work, + for which you have or can give appropriate copyright permission. + + Notwithstanding any other provision of this License, for material you + add to a covered work, you may (if authorized by the copyright holders of + that material) supplement the terms of this License with terms: + + a) Disclaiming warranty or limiting liability differently from the + terms of sections 15 and 16 of this License; or + + b) Requiring preservation of specified reasonable legal notices or + author attributions in that material or in the Appropriate Legal + Notices displayed by works containing it; or + + c) Prohibiting misrepresentation of the origin of that material, or + requiring that modified versions of such material be marked in + reasonable ways as different from the original version; or + + d) Limiting the use for publicity purposes of names of licensors or + authors of the material; or + + e) Declining to grant rights under trademark law for use of some + trade names, trademarks, or service marks; or + + f) Requiring indemnification of licensors and authors of that + material by anyone who conveys the material (or modified versions of + it) with contractual assumptions of liability to the recipient, for + any liability that these contractual assumptions directly impose on + those licensors and authors. + + All other non-permissive additional terms are considered "further + restrictions" within the meaning of section 10. If the Program as you + received it, or any part of it, contains a notice stating that it is + governed by this License along with a term that is a further + restriction, you may remove that term. If a license document contains + a further restriction but permits relicensing or conveying under this + License, you may add to a covered work material governed by the terms + of that license document, provided that the further restriction does + not survive such relicensing or conveying. + + If you add terms to a covered work in accord with this section, you + must place, in the relevant source files, a statement of the + additional terms that apply to those files, or a notice indicating + where to find the applicable terms. + + Additional terms, permissive or non-permissive, may be stated in the + form of a separately written license, or stated as exceptions; + the above requirements apply either way. + + 8. Termination. + + You may not propagate or modify a covered work except as expressly + provided under this License. Any attempt otherwise to propagate or + modify it is void, and will automatically terminate your rights under + this License (including any patent licenses granted under the third + paragraph of section 11). + + However, if you cease all violation of this License, then your + license from a particular copyright holder is reinstated (a) + provisionally, unless and until the copyright holder explicitly and + finally terminates your license, and (b) permanently, if the copyright + holder fails to notify you of the violation by some reasonable means + prior to 60 days after the cessation. + + Moreover, your license from a particular copyright holder is + reinstated permanently if the copyright holder notifies you of the + violation by some reasonable means, this is the first time you have + received notice of violation of this License (for any work) from that + copyright holder, and you cure the violation prior to 30 days after + your receipt of the notice. + + Termination of your rights under this section does not terminate the + licenses of parties who have received copies or rights from you under + this License. If your rights have been terminated and not permanently + reinstated, you do not qualify to receive new licenses for the same + material under section 10. + + 9. Acceptance Not Required for Having Copies. + + You are not required to accept this License in order to receive or + run a copy of the Program. Ancillary propagation of a covered work + occurring solely as a consequence of using peer-to-peer transmission + to receive a copy likewise does not require acceptance. However, + nothing other than this License grants you permission to propagate or + modify any covered work. These actions infringe copyright if you do + not accept this License. Therefore, by modifying or propagating a + covered work, you indicate your acceptance of this License to do so. + + 10. Automatic Licensing of Downstream Recipients. + + Each time you convey a covered work, the recipient automatically + receives a license from the original licensors, to run, modify and + propagate that work, subject to this License. You are not responsible + for enforcing compliance by third parties with this License. + + An "entity transaction" is a transaction transferring control of an + organization, or substantially all assets of one, or subdividing an + organization, or merging organizations. If propagation of a covered + work results from an entity transaction, each party to that + transaction who receives a copy of the work also receives whatever + licenses to the work the party's predecessor in interest had or could + give under the previous paragraph, plus a right to possession of the + Corresponding Source of the work from the predecessor in interest, if + the predecessor has it or can get it with reasonable efforts. + + You may not impose any further restrictions on the exercise of the + rights granted or affirmed under this License. For example, you may + not impose a license fee, royalty, or other charge for exercise of + rights granted under this License, and you may not initiate litigation + (including a cross-claim or counterclaim in a lawsuit) alleging that + any patent claim is infringed by making, using, selling, offering for + sale, or importing the Program or any portion of it. + + 11. Patents. + + A "contributor" is a copyright holder who authorizes use under this + License of the Program or a work on which the Program is based. The + work thus licensed is called the contributor's "contributor version". + + A contributor's "essential patent claims" are all patent claims + owned or controlled by the contributor, whether already acquired or + hereafter acquired, that would be infringed by some manner, permitted + by this License, of making, using, or selling its contributor version, + but do not include claims that would be infringed only as a + consequence of further modification of the contributor version. For + purposes of this definition, "control" includes the right to grant + patent sublicenses in a manner consistent with the requirements of + this License. + + Each contributor grants you a non-exclusive, worldwide, royalty-free + patent license under the contributor's essential patent claims, to + make, use, sell, offer for sale, import and otherwise run, modify and + propagate the contents of its contributor version. + + In the following three paragraphs, a "patent license" is any express + agreement or commitment, however denominated, not to enforce a patent + (such as an express permission to practice a patent or covenant not to + sue for patent infringement). To "grant" such a patent license to a + party means to make such an agreement or commitment not to enforce a + patent against the party. + + If you convey a covered work, knowingly relying on a patent license, + and the Corresponding Source of the work is not available for anyone + to copy, free of charge and under the terms of this License, through a + publicly available network server or other readily accessible means, + then you must either (1) cause the Corresponding Source to be so + available, or (2) arrange to deprive yourself of the benefit of the + patent license for this particular work, or (3) arrange, in a manner + consistent with the requirements of this License, to extend the patent + license to downstream recipients. "Knowingly relying" means you have + actual knowledge that, but for the patent license, your conveying the + covered work in a country, or your recipient's use of the covered work + in a country, would infringe one or more identifiable patents in that + country that you have reason to believe are valid. + + If, pursuant to or in connection with a single transaction or + arrangement, you convey, or propagate by procuring conveyance of, a + covered work, and grant a patent license to some of the parties + receiving the covered work authorizing them to use, propagate, modify + or convey a specific copy of the covered work, then the patent license + you grant is automatically extended to all recipients of the covered + work and works based on it. + + A patent license is "discriminatory" if it does not include within + the scope of its coverage, prohibits the exercise of, or is + conditioned on the non-exercise of one or more of the rights that are + specifically granted under this License. You may not convey a covered + work if you are a party to an arrangement with a third party that is + in the business of distributing software, under which you make payment + to the third party based on the extent of your activity of conveying + the work, and under which the third party grants, to any of the + parties who would receive the covered work from you, a discriminatory + patent license (a) in connection with copies of the covered work + conveyed by you (or copies made from those copies), or (b) primarily + for and in connection with specific products or compilations that + contain the covered work, unless you entered into that arrangement, + or that patent license was granted, prior to 28 March 2007. + + Nothing in this License shall be construed as excluding or limiting + any implied license or other defenses to infringement that may + otherwise be available to you under applicable patent law. + + 12. No Surrender of Others' Freedom. + + If conditions are imposed on you (whether by court order, agreement or + otherwise) that contradict the conditions of this License, they do not + excuse you from the conditions of this License. If you cannot convey a + covered work so as to satisfy simultaneously your obligations under this + License and any other pertinent obligations, then as a consequence you may + not convey it at all. For example, if you agree to terms that obligate you + to collect a royalty for further conveying from those to whom you convey + the Program, the only way you could satisfy both those terms and this + License would be to refrain entirely from conveying the Program. + + 13. Remote Network Interaction; Use with the GNU General Public License. + + Notwithstanding any other provision of this License, if you modify the + Program, your modified version must prominently offer all users + interacting with it remotely through a computer network (if your version + supports such interaction) an opportunity to receive the Corresponding + Source of your version by providing access to the Corresponding Source + from a network server at no charge, through some standard or customary + means of facilitating copying of software. This Corresponding Source + shall include the Corresponding Source for any work covered by version 3 + of the GNU General Public License that is incorporated pursuant to the + following paragraph. + + Notwithstanding any other provision of this License, you have + permission to link or combine any covered work with a work licensed + under version 3 of the GNU General Public License into a single + combined work, and to convey the resulting work. The terms of this + License will continue to apply to the part which is the covered work, + but the work with which it is combined will remain governed by version + 3 of the GNU General Public License. + + 14. Revised Versions of this License. + + The Free Software Foundation may publish revised and/or new versions of + the GNU Affero General Public License from time to time. Such new versions + will be similar in spirit to the present version, but may differ in detail to + address new problems or concerns. + + Each version is given a distinguishing version number. If the + Program specifies that a certain numbered version of the GNU Affero General + Public License "or any later version" applies to it, you have the + option of following the terms and conditions either of that numbered + version or of any later version published by the Free Software + Foundation. If the Program does not specify a version number of the + GNU Affero General Public License, you may choose any version ever published + by the Free Software Foundation. + + If the Program specifies that a proxy can decide which future + versions of the GNU Affero General Public License can be used, that proxy's + public statement of acceptance of a version permanently authorizes you + to choose that version for the Program. + + Later license versions may give you additional or different + permissions. However, no additional obligations are imposed on any + author or copyright holder as a result of your choosing to follow a + later version. + + 15. Disclaimer of Warranty. + + THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY + APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT + HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY + OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, + THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM + IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF + ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 16. Limitation of Liability. + + IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING + WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS + THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY + GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE + USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF + DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD + PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), + EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF + SUCH DAMAGES. + + 17. Interpretation of Sections 15 and 16. + + If the disclaimer of warranty and limitation of liability provided + above cannot be given local legal effect according to their terms, + reviewing courts shall apply local law that most closely approximates + an absolute waiver of all civil liability in connection with the + Program, unless a warranty or assumption of liability accompanies a + copy of the Program in return for a fee. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest + possible use to the public, the best way to achieve this is to make it + free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest + to attach them to the start of each source file to most effectively + state the exclusion of warranty; and each file should have at least + the "copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU Affero General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Affero General Public License for more details. + + You should have received a copy of the GNU Affero General Public License + along with this program. If not, see . + + Also add information on how to contact you by electronic and paper mail. + + If your software can interact with users remotely through a computer + network, you should also make sure that it provides a way for users to + get its source. For example, if your program is a web application, its + interface could display a "Source" link that leads users to an archive + of the code. There are many ways you could offer source, and different + solutions will be better for different programs; see section 13 for the + specific requirements. + + You should also get your employer (if you work as a programmer) or school, + if any, to sign a "copyright disclaimer" for the program, if necessary. + For more information on this, and how to apply and follow the GNU AGPL, see + . diff --git a/ext/3rd-party-addons/connector/doc/project/roadmap.rst b/ext/3rd-party-addons/connector/doc/project/roadmap.rst new file mode 100644 index 00000000..cb605f5f --- /dev/null +++ b/ext/3rd-party-addons/connector/doc/project/roadmap.rst @@ -0,0 +1,13 @@ +.. _roadmap: + +####### +Roadmap +####### + +Here is a list of things we may agree to merge. + +* Add facilities to parse the errors from the jobs so we can replace it + by more contextual and helpful errors. + +* A logger which keeps in a buffer all the logs and flushes them when an error + occurs in a synchronization, clears them if it succeeded diff --git a/ext/3rd-party-addons/connector/exception.py b/ext/3rd-party-addons/connector/exception.py new file mode 100644 index 00000000..d077ed9d --- /dev/null +++ b/ext/3rd-party-addons/connector/exception.py @@ -0,0 +1,46 @@ +# -*- coding: utf-8 -*- +# Copyright 2012-2017 Camptocamp SA +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html) + +from odoo.addons.queue_job.exception import ( + RetryableJobError, + JobError, +) + + +# Connector related errors + + +class ConnectorException(Exception): + """ Base Exception for the connectors """ + + +class NoConnectorUnitError(ConnectorException): + """ No ConnectorUnit has been found """ + + +class InvalidDataError(ConnectorException): + """ Data Invalid """ + + +# Job related errors + +class MappingError(ConnectorException): + """ An error occurred during a mapping transformation. """ + + +class NetworkRetryableError(RetryableJobError): + """ A network error caused the failure of the job, it can be retried later. + """ + + +class NoExternalId(RetryableJobError): + """ No External ID found, it can be retried later. """ + + +class IDMissingInBackend(JobError): + """ The ID does not exist in the backend """ + + +class ManyIDSInBackend(JobError): + """Unique key exists many times in backend""" diff --git a/ext/3rd-party-addons/connector/i18n/am.po b/ext/3rd-party-addons/connector/i18n/am.po new file mode 100644 index 00000000..6ce9627d --- /dev/null +++ b/ext/3rd-party-addons/connector/i18n/am.po @@ -0,0 +1,317 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * connector +# +# Translators: +# OCA Transbot , 2017 +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server 10.0\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2017-03-10 03:36+0000\n" +"PO-Revision-Date: 2017-03-10 03:36+0000\n" +"Last-Translator: OCA Transbot , 2017\n" +"Language-Team: Amharic (https://www.transifex.com/oca/teams/23907/am/)\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: \n" +"Language: am\n" +"Plural-Forms: nplurals=2; plural=(n > 1);\n" + +#. module: connector +#: code:addons/connector/checkpoint/checkpoint.py:119 +#, python-format +msgid "A %s needs a review." +msgstr "" + +#. module: connector +#: model:ir.ui.view,arch_db:connector.view_connector_config_settings +msgid "Apply" +msgstr "" + +#. module: connector +#: model:ir.ui.view,arch_db:connector.view_connector_config_settings +msgid "Backends" +msgstr "" + +#. module: connector +#: model:ir.ui.view,arch_db:connector.view_connector_checkpoint_review +#: model:ir.ui.view,arch_db:connector.view_connector_config_settings +msgid "Cancel" +msgstr "Cancelar" + +#. module: connector +#: model:ir.ui.menu,name:connector.menu_checkpoint +msgid "Checkpoint" +msgstr "" + +#. module: connector +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_review_checkpoint_ids +msgid "Checkpoints" +msgstr "" + +#. module: connector +#: model:ir.model,name:connector.model_connector_checkpoint_review +msgid "Checkpoints Review" +msgstr "" + +#. module: connector +#: model:ir.ui.view,arch_db:connector.view_connector_checkpoint_form +msgid "Click on the" +msgstr "" + +#. module: connector +#: model:ir.actions.act_window,name:connector.action_connector_config_settings +#: model:ir.ui.view,arch_db:connector.view_connector_config_settings +msgid "Configure Connector" +msgstr "" + +#. module: connector +#: model:ir.module.category,name:connector.module_category_connector +#: model:ir.ui.menu,name:connector.menu_connector_config_settings +msgid "Connector" +msgstr "" + +#. module: connector +#: model:ir.model,name:connector.model_connector_backend +msgid "Connector Backend" +msgstr "" + +#. module: connector +#: model:ir.actions.act_window,name:connector.action_connector_checkpoint +#: model:ir.model,name:connector.model_connector_checkpoint +#: model:ir.ui.view,arch_db:connector.view_connector_checkpoint_form +#: model:ir.ui.view,arch_db:connector.view_connector_checkpoint_search +#: model:ir.ui.view,arch_db:connector.view_connector_checkpoint_tree +msgid "Connector Checkpoint" +msgstr "" + +#. module: connector +#: model:ir.model,name:connector.model_connector_config_settings +msgid "Connector Configuration" +msgstr "" + +#. module: connector +#: model:res.groups,name:connector.group_connector_manager +msgid "Connector Manager" +msgstr "" + +#. module: connector +#: model:ir.ui.menu,name:connector.menu_connector +#: model:ir.ui.menu,name:connector.menu_connector_root +#: model:ir.ui.view,arch_db:connector.view_partner_connector_form +msgid "Connectors" +msgstr "" + +#. module: connector +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_create_uid +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_review_create_uid +#: model:ir.model.fields,field_description:connector.field_connector_config_settings_create_uid +msgid "Created by" +msgstr "Creado por" + +#. module: connector +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_create_date +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_review_create_date +#: model:ir.model.fields,field_description:connector.field_connector_config_settings_create_date +msgid "Created on" +msgstr "Creado en" + +#. module: connector +#: model:ir.model.fields,field_description:connector.field_connector_backend_display_name +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_display_name +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_review_display_name +#: model:ir.model.fields,field_description:connector.field_connector_config_settings_display_name +#: model:ir.model.fields,field_description:connector.field_external_binding_display_name +msgid "Display Name" +msgstr "" + +#. module: connector +#: model:ir.model,name:connector.model_external_binding +msgid "External Binding (abstract)" +msgstr "" + +#. module: connector +#: model:ir.ui.view,arch_db:connector.view_connector_checkpoint_search +msgid "Group By..." +msgstr "" + +#. module: connector +#: model:ir.model.fields,field_description:connector.field_connector_backend_id +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_id +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_review_id +#: model:ir.model.fields,field_description:connector.field_connector_config_settings_id +#: model:ir.model.fields,field_description:connector.field_external_binding_id +msgid "ID" +msgstr "ID" + +#. module: connector +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_backend_id +msgid "Imported from" +msgstr "" + +#. module: connector +#: model:ir.model.fields,field_description:connector.field_connector_backend___last_update +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint___last_update +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_review___last_update +#: model:ir.model.fields,field_description:connector.field_connector_config_settings___last_update +#: model:ir.model.fields,field_description:connector.field_external_binding___last_update +msgid "Last Modified on" +msgstr "" + +#. module: connector +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_review_write_uid +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_write_uid +#: model:ir.model.fields,field_description:connector.field_connector_config_settings_write_uid +msgid "Last Updated by" +msgstr "Última actualización por" + +#. module: connector +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_review_write_date +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_write_date +#: model:ir.model.fields,field_description:connector.field_connector_config_settings_write_date +msgid "Last Updated on" +msgstr "Última actualización en" + +#. module: connector +#: model:ir.model.fields,field_description:connector.field_connector_test_binding_sync_date +#: model:ir.model.fields,field_description:connector.field_external_binding_sync_date +#: model:ir.model.fields,field_description:connector.field_no_inherits_binding_sync_date +msgid "Last synchronization date" +msgstr "" + +#. module: connector +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_model_id +#: model:ir.ui.view,arch_db:connector.view_connector_checkpoint_search +msgid "Model" +msgstr "" + +#. module: connector +#: model:ir.model.fields,field_description:connector.field_connector_backend_name +#: model:ir.model.fields,field_description:connector.field_test_backend_name +msgid "Name" +msgstr "" + +#. module: connector +#: model:ir.model.fields,help:connector.field_connector_checkpoint_name +msgid "Name of the record to review" +msgstr "" + +#. module: connector +#: selection:connector.checkpoint,state:0 +#: model:ir.ui.view,arch_db:connector.view_connector_checkpoint_search +msgid "Need Review" +msgstr "" + +#. module: connector +#: model:ir.actions.act_window,help:connector.action_connector_checkpoint +msgid "No record to check." +msgstr "" + +#. module: connector +#: model:ir.actions.client,name:connector.action_client_connector_menu +msgid "Open Connector Menu" +msgstr "" + +#. module: connector +#: model:ir.model,name:connector.model_queue_job +msgid "Queue Job" +msgstr "" + +#. module: connector +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_record +msgid "Record" +msgstr "" + +#. module: connector +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_record_id +msgid "Record ID" +msgstr "" + +#. module: connector +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_name +msgid "Record Name" +msgstr "" + +#. module: connector +#: code:addons/connector/models/queue_job.py:32 +#, python-format +msgid "Related Record" +msgstr "" + +#. module: connector +#: model:ir.actions.act_window,name:connector.action_connector_checkpoint_review +#: model:ir.ui.view,arch_db:connector.view_connector_checkpoint_review +msgid "Review Checkpoints" +msgstr "" + +#. module: connector +#: selection:connector.checkpoint,state:0 +#: model:ir.ui.view,arch_db:connector.view_connector_checkpoint_form +#: model:ir.ui.view,arch_db:connector.view_connector_checkpoint_search +#: model:ir.ui.view,arch_db:connector.view_connector_checkpoint_tree +msgid "Reviewed" +msgstr "" + +#. module: connector +#: model:ir.ui.view,arch_db:connector.view_connector_checkpoint_review +msgid "Set as reviewed" +msgstr "" + +#. module: connector +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_state +msgid "Status" +msgstr "" + +#. module: connector +#: model:ir.actions.act_window,help:connector.action_connector_checkpoint +msgid "" +"The connectors list the new records to verify\n" +" based on their type. Only some need a manual\n" +" review." +msgstr "" + +#. module: connector +#: model:ir.model.fields,help:connector.field_connector_checkpoint_backend_id +msgid "The record has been imported from this backend" +msgstr "" + +#. module: connector +#: model:ir.model.fields,help:connector.field_connector_checkpoint_record +msgid "The record to review." +msgstr "" + +#. module: connector +#: model:ir.ui.view,arch_db:connector.view_connector_checkpoint_review +msgid "The selected checkpoints will be set as reviewed." +msgstr "" + +#. module: connector +#: model:ir.model.fields,field_description:connector.field_connector_backend_version +msgid "Version" +msgstr "" + +#. module: connector +#: model:ir.actions.act_window,help:connector.action_connector_checkpoint +msgid "" +"When a connector imports new records which have\n" +" configuration or reviews to do manually, they\n" +" will appear in this list. Once a record has been\n" +" checked, click on the 'Reviewed' button." +msgstr "" + +#. module: connector +#: model:ir.model,name:connector.model_base +msgid "base" +msgstr "" + +#. module: connector +#: model:ir.ui.view,arch_db:connector.view_connector_checkpoint_review +#: model:ir.ui.view,arch_db:connector.view_connector_config_settings +msgid "or" +msgstr "" + +#. module: connector +#: model:ir.ui.view,arch_db:connector.view_connector_checkpoint_form +msgid "to verify it:" +msgstr "" diff --git a/ext/3rd-party-addons/connector/i18n/ar.po b/ext/3rd-party-addons/connector/i18n/ar.po new file mode 100644 index 00000000..92d5df9f --- /dev/null +++ b/ext/3rd-party-addons/connector/i18n/ar.po @@ -0,0 +1,317 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * connector +# +# Translators: +# OCA Transbot , 2017 +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server 10.0\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2017-03-10 03:36+0000\n" +"PO-Revision-Date: 2017-03-10 03:36+0000\n" +"Last-Translator: OCA Transbot , 2017\n" +"Language-Team: Arabic (https://www.transifex.com/oca/teams/23907/ar/)\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: \n" +"Language: ar\n" +"Plural-Forms: nplurals=6; plural=n==0 ? 0 : n==1 ? 1 : n==2 ? 2 : n%100>=3 && n%100<=10 ? 3 : n%100>=11 && n%100<=99 ? 4 : 5;\n" + +#. module: connector +#: code:addons/connector/checkpoint/checkpoint.py:119 +#, python-format +msgid "A %s needs a review." +msgstr "" + +#. module: connector +#: model:ir.ui.view,arch_db:connector.view_connector_config_settings +msgid "Apply" +msgstr "" + +#. module: connector +#: model:ir.ui.view,arch_db:connector.view_connector_config_settings +msgid "Backends" +msgstr "" + +#. module: connector +#: model:ir.ui.view,arch_db:connector.view_connector_checkpoint_review +#: model:ir.ui.view,arch_db:connector.view_connector_config_settings +msgid "Cancel" +msgstr "إلغاء" + +#. module: connector +#: model:ir.ui.menu,name:connector.menu_checkpoint +msgid "Checkpoint" +msgstr "" + +#. module: connector +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_review_checkpoint_ids +msgid "Checkpoints" +msgstr "" + +#. module: connector +#: model:ir.model,name:connector.model_connector_checkpoint_review +msgid "Checkpoints Review" +msgstr "" + +#. module: connector +#: model:ir.ui.view,arch_db:connector.view_connector_checkpoint_form +msgid "Click on the" +msgstr "" + +#. module: connector +#: model:ir.actions.act_window,name:connector.action_connector_config_settings +#: model:ir.ui.view,arch_db:connector.view_connector_config_settings +msgid "Configure Connector" +msgstr "" + +#. module: connector +#: model:ir.module.category,name:connector.module_category_connector +#: model:ir.ui.menu,name:connector.menu_connector_config_settings +msgid "Connector" +msgstr "" + +#. module: connector +#: model:ir.model,name:connector.model_connector_backend +msgid "Connector Backend" +msgstr "" + +#. module: connector +#: model:ir.actions.act_window,name:connector.action_connector_checkpoint +#: model:ir.model,name:connector.model_connector_checkpoint +#: model:ir.ui.view,arch_db:connector.view_connector_checkpoint_form +#: model:ir.ui.view,arch_db:connector.view_connector_checkpoint_search +#: model:ir.ui.view,arch_db:connector.view_connector_checkpoint_tree +msgid "Connector Checkpoint" +msgstr "" + +#. module: connector +#: model:ir.model,name:connector.model_connector_config_settings +msgid "Connector Configuration" +msgstr "" + +#. module: connector +#: model:res.groups,name:connector.group_connector_manager +msgid "Connector Manager" +msgstr "" + +#. module: connector +#: model:ir.ui.menu,name:connector.menu_connector +#: model:ir.ui.menu,name:connector.menu_connector_root +#: model:ir.ui.view,arch_db:connector.view_partner_connector_form +msgid "Connectors" +msgstr "" + +#. module: connector +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_create_uid +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_review_create_uid +#: model:ir.model.fields,field_description:connector.field_connector_config_settings_create_uid +msgid "Created by" +msgstr "" + +#. module: connector +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_create_date +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_review_create_date +#: model:ir.model.fields,field_description:connector.field_connector_config_settings_create_date +msgid "Created on" +msgstr "" + +#. module: connector +#: model:ir.model.fields,field_description:connector.field_connector_backend_display_name +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_display_name +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_review_display_name +#: model:ir.model.fields,field_description:connector.field_connector_config_settings_display_name +#: model:ir.model.fields,field_description:connector.field_external_binding_display_name +msgid "Display Name" +msgstr "" + +#. module: connector +#: model:ir.model,name:connector.model_external_binding +msgid "External Binding (abstract)" +msgstr "" + +#. module: connector +#: model:ir.ui.view,arch_db:connector.view_connector_checkpoint_search +msgid "Group By..." +msgstr "" + +#. module: connector +#: model:ir.model.fields,field_description:connector.field_connector_backend_id +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_id +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_review_id +#: model:ir.model.fields,field_description:connector.field_connector_config_settings_id +#: model:ir.model.fields,field_description:connector.field_external_binding_id +msgid "ID" +msgstr "" + +#. module: connector +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_backend_id +msgid "Imported from" +msgstr "" + +#. module: connector +#: model:ir.model.fields,field_description:connector.field_connector_backend___last_update +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint___last_update +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_review___last_update +#: model:ir.model.fields,field_description:connector.field_connector_config_settings___last_update +#: model:ir.model.fields,field_description:connector.field_external_binding___last_update +msgid "Last Modified on" +msgstr "" + +#. module: connector +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_review_write_uid +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_write_uid +#: model:ir.model.fields,field_description:connector.field_connector_config_settings_write_uid +msgid "Last Updated by" +msgstr "" + +#. module: connector +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_review_write_date +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_write_date +#: model:ir.model.fields,field_description:connector.field_connector_config_settings_write_date +msgid "Last Updated on" +msgstr "" + +#. module: connector +#: model:ir.model.fields,field_description:connector.field_connector_test_binding_sync_date +#: model:ir.model.fields,field_description:connector.field_external_binding_sync_date +#: model:ir.model.fields,field_description:connector.field_no_inherits_binding_sync_date +msgid "Last synchronization date" +msgstr "" + +#. module: connector +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_model_id +#: model:ir.ui.view,arch_db:connector.view_connector_checkpoint_search +msgid "Model" +msgstr "" + +#. module: connector +#: model:ir.model.fields,field_description:connector.field_connector_backend_name +#: model:ir.model.fields,field_description:connector.field_test_backend_name +msgid "Name" +msgstr "" + +#. module: connector +#: model:ir.model.fields,help:connector.field_connector_checkpoint_name +msgid "Name of the record to review" +msgstr "" + +#. module: connector +#: selection:connector.checkpoint,state:0 +#: model:ir.ui.view,arch_db:connector.view_connector_checkpoint_search +msgid "Need Review" +msgstr "" + +#. module: connector +#: model:ir.actions.act_window,help:connector.action_connector_checkpoint +msgid "No record to check." +msgstr "" + +#. module: connector +#: model:ir.actions.client,name:connector.action_client_connector_menu +msgid "Open Connector Menu" +msgstr "" + +#. module: connector +#: model:ir.model,name:connector.model_queue_job +msgid "Queue Job" +msgstr "" + +#. module: connector +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_record +msgid "Record" +msgstr "" + +#. module: connector +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_record_id +msgid "Record ID" +msgstr "" + +#. module: connector +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_name +msgid "Record Name" +msgstr "" + +#. module: connector +#: code:addons/connector/models/queue_job.py:32 +#, python-format +msgid "Related Record" +msgstr "" + +#. module: connector +#: model:ir.actions.act_window,name:connector.action_connector_checkpoint_review +#: model:ir.ui.view,arch_db:connector.view_connector_checkpoint_review +msgid "Review Checkpoints" +msgstr "" + +#. module: connector +#: selection:connector.checkpoint,state:0 +#: model:ir.ui.view,arch_db:connector.view_connector_checkpoint_form +#: model:ir.ui.view,arch_db:connector.view_connector_checkpoint_search +#: model:ir.ui.view,arch_db:connector.view_connector_checkpoint_tree +msgid "Reviewed" +msgstr "" + +#. module: connector +#: model:ir.ui.view,arch_db:connector.view_connector_checkpoint_review +msgid "Set as reviewed" +msgstr "" + +#. module: connector +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_state +msgid "Status" +msgstr "" + +#. module: connector +#: model:ir.actions.act_window,help:connector.action_connector_checkpoint +msgid "" +"The connectors list the new records to verify\n" +" based on their type. Only some need a manual\n" +" review." +msgstr "" + +#. module: connector +#: model:ir.model.fields,help:connector.field_connector_checkpoint_backend_id +msgid "The record has been imported from this backend" +msgstr "" + +#. module: connector +#: model:ir.model.fields,help:connector.field_connector_checkpoint_record +msgid "The record to review." +msgstr "" + +#. module: connector +#: model:ir.ui.view,arch_db:connector.view_connector_checkpoint_review +msgid "The selected checkpoints will be set as reviewed." +msgstr "" + +#. module: connector +#: model:ir.model.fields,field_description:connector.field_connector_backend_version +msgid "Version" +msgstr "" + +#. module: connector +#: model:ir.actions.act_window,help:connector.action_connector_checkpoint +msgid "" +"When a connector imports new records which have\n" +" configuration or reviews to do manually, they\n" +" will appear in this list. Once a record has been\n" +" checked, click on the 'Reviewed' button." +msgstr "" + +#. module: connector +#: model:ir.model,name:connector.model_base +msgid "base" +msgstr "" + +#. module: connector +#: model:ir.ui.view,arch_db:connector.view_connector_checkpoint_review +#: model:ir.ui.view,arch_db:connector.view_connector_config_settings +msgid "or" +msgstr "" + +#. module: connector +#: model:ir.ui.view,arch_db:connector.view_connector_checkpoint_form +msgid "to verify it:" +msgstr "" diff --git a/ext/3rd-party-addons/connector/i18n/ca.po b/ext/3rd-party-addons/connector/i18n/ca.po new file mode 100644 index 00000000..02d8270b --- /dev/null +++ b/ext/3rd-party-addons/connector/i18n/ca.po @@ -0,0 +1,317 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * connector +# +# Translators: +# OCA Transbot , 2017 +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server 10.0\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2017-03-10 03:36+0000\n" +"PO-Revision-Date: 2017-03-10 03:36+0000\n" +"Last-Translator: OCA Transbot , 2017\n" +"Language-Team: Catalan (https://www.transifex.com/oca/teams/23907/ca/)\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: \n" +"Language: ca\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" + +#. module: connector +#: code:addons/connector/checkpoint/checkpoint.py:119 +#, python-format +msgid "A %s needs a review." +msgstr "Un %s necessita revisió." + +#. module: connector +#: model:ir.ui.view,arch_db:connector.view_connector_config_settings +msgid "Apply" +msgstr "Aplica" + +#. module: connector +#: model:ir.ui.view,arch_db:connector.view_connector_config_settings +msgid "Backends" +msgstr "Backends" + +#. module: connector +#: model:ir.ui.view,arch_db:connector.view_connector_checkpoint_review +#: model:ir.ui.view,arch_db:connector.view_connector_config_settings +msgid "Cancel" +msgstr "Cancel·la" + +#. module: connector +#: model:ir.ui.menu,name:connector.menu_checkpoint +msgid "Checkpoint" +msgstr "Punt de control" + +#. module: connector +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_review_checkpoint_ids +msgid "Checkpoints" +msgstr "Punts de control" + +#. module: connector +#: model:ir.model,name:connector.model_connector_checkpoint_review +msgid "Checkpoints Review" +msgstr "Revisió de punts de control" + +#. module: connector +#: model:ir.ui.view,arch_db:connector.view_connector_checkpoint_form +msgid "Click on the" +msgstr "Fes clic en el" + +#. module: connector +#: model:ir.actions.act_window,name:connector.action_connector_config_settings +#: model:ir.ui.view,arch_db:connector.view_connector_config_settings +msgid "Configure Connector" +msgstr "Configura el connector" + +#. module: connector +#: model:ir.module.category,name:connector.module_category_connector +#: model:ir.ui.menu,name:connector.menu_connector_config_settings +msgid "Connector" +msgstr "Connector" + +#. module: connector +#: model:ir.model,name:connector.model_connector_backend +msgid "Connector Backend" +msgstr "Backend del Connector" + +#. module: connector +#: model:ir.actions.act_window,name:connector.action_connector_checkpoint +#: model:ir.model,name:connector.model_connector_checkpoint +#: model:ir.ui.view,arch_db:connector.view_connector_checkpoint_form +#: model:ir.ui.view,arch_db:connector.view_connector_checkpoint_search +#: model:ir.ui.view,arch_db:connector.view_connector_checkpoint_tree +msgid "Connector Checkpoint" +msgstr "Punts de control del connector" + +#. module: connector +#: model:ir.model,name:connector.model_connector_config_settings +msgid "Connector Configuration" +msgstr "Configuració del connector" + +#. module: connector +#: model:res.groups,name:connector.group_connector_manager +msgid "Connector Manager" +msgstr "Administrador del connector" + +#. module: connector +#: model:ir.ui.menu,name:connector.menu_connector +#: model:ir.ui.menu,name:connector.menu_connector_root +#: model:ir.ui.view,arch_db:connector.view_partner_connector_form +msgid "Connectors" +msgstr "Connectors" + +#. module: connector +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_create_uid +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_review_create_uid +#: model:ir.model.fields,field_description:connector.field_connector_config_settings_create_uid +msgid "Created by" +msgstr "Creat per" + +#. module: connector +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_create_date +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_review_create_date +#: model:ir.model.fields,field_description:connector.field_connector_config_settings_create_date +msgid "Created on" +msgstr "Creat a" + +#. module: connector +#: model:ir.model.fields,field_description:connector.field_connector_backend_display_name +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_display_name +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_review_display_name +#: model:ir.model.fields,field_description:connector.field_connector_config_settings_display_name +#: model:ir.model.fields,field_description:connector.field_external_binding_display_name +msgid "Display Name" +msgstr "" + +#. module: connector +#: model:ir.model,name:connector.model_external_binding +msgid "External Binding (abstract)" +msgstr "Lligam extern (abstracte)" + +#. module: connector +#: model:ir.ui.view,arch_db:connector.view_connector_checkpoint_search +msgid "Group By..." +msgstr "Agrupa per..." + +#. module: connector +#: model:ir.model.fields,field_description:connector.field_connector_backend_id +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_id +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_review_id +#: model:ir.model.fields,field_description:connector.field_connector_config_settings_id +#: model:ir.model.fields,field_description:connector.field_external_binding_id +msgid "ID" +msgstr "ID" + +#. module: connector +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_backend_id +msgid "Imported from" +msgstr "Importat de" + +#. module: connector +#: model:ir.model.fields,field_description:connector.field_connector_backend___last_update +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint___last_update +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_review___last_update +#: model:ir.model.fields,field_description:connector.field_connector_config_settings___last_update +#: model:ir.model.fields,field_description:connector.field_external_binding___last_update +msgid "Last Modified on" +msgstr "" + +#. module: connector +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_review_write_uid +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_write_uid +#: model:ir.model.fields,field_description:connector.field_connector_config_settings_write_uid +msgid "Last Updated by" +msgstr "Darrear modificació per" + +#. module: connector +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_review_write_date +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_write_date +#: model:ir.model.fields,field_description:connector.field_connector_config_settings_write_date +msgid "Last Updated on" +msgstr "Darrera modificació el" + +#. module: connector +#: model:ir.model.fields,field_description:connector.field_connector_test_binding_sync_date +#: model:ir.model.fields,field_description:connector.field_external_binding_sync_date +#: model:ir.model.fields,field_description:connector.field_no_inherits_binding_sync_date +msgid "Last synchronization date" +msgstr "Darrera data de sincronització" + +#. module: connector +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_model_id +#: model:ir.ui.view,arch_db:connector.view_connector_checkpoint_search +msgid "Model" +msgstr "Model" + +#. module: connector +#: model:ir.model.fields,field_description:connector.field_connector_backend_name +#: model:ir.model.fields,field_description:connector.field_test_backend_name +msgid "Name" +msgstr "Nom" + +#. module: connector +#: model:ir.model.fields,help:connector.field_connector_checkpoint_name +msgid "Name of the record to review" +msgstr "" + +#. module: connector +#: selection:connector.checkpoint,state:0 +#: model:ir.ui.view,arch_db:connector.view_connector_checkpoint_search +msgid "Need Review" +msgstr "Necessita Revisió" + +#. module: connector +#: model:ir.actions.act_window,help:connector.action_connector_checkpoint +msgid "No record to check." +msgstr "" + +#. module: connector +#: model:ir.actions.client,name:connector.action_client_connector_menu +msgid "Open Connector Menu" +msgstr "Menú de Open Connector" + +#. module: connector +#: model:ir.model,name:connector.model_queue_job +msgid "Queue Job" +msgstr "Tasca de Cua" + +#. module: connector +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_record +msgid "Record" +msgstr "" + +#. module: connector +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_record_id +msgid "Record ID" +msgstr "ID Registre" + +#. module: connector +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_name +msgid "Record Name" +msgstr "" + +#. module: connector +#: code:addons/connector/models/queue_job.py:32 +#, python-format +msgid "Related Record" +msgstr "Registre relacionat" + +#. module: connector +#: model:ir.actions.act_window,name:connector.action_connector_checkpoint_review +#: model:ir.ui.view,arch_db:connector.view_connector_checkpoint_review +msgid "Review Checkpoints" +msgstr "Revisa Punts-Control" + +#. module: connector +#: selection:connector.checkpoint,state:0 +#: model:ir.ui.view,arch_db:connector.view_connector_checkpoint_form +#: model:ir.ui.view,arch_db:connector.view_connector_checkpoint_search +#: model:ir.ui.view,arch_db:connector.view_connector_checkpoint_tree +msgid "Reviewed" +msgstr "Revisat" + +#. module: connector +#: model:ir.ui.view,arch_db:connector.view_connector_checkpoint_review +msgid "Set as reviewed" +msgstr "Marcat com revisat" + +#. module: connector +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_state +msgid "Status" +msgstr "Estat" + +#. module: connector +#: model:ir.actions.act_window,help:connector.action_connector_checkpoint +msgid "" +"The connectors list the new records to verify\n" +" based on their type. Only some need a manual\n" +" review." +msgstr "" + +#. module: connector +#: model:ir.model.fields,help:connector.field_connector_checkpoint_backend_id +msgid "The record has been imported from this backend" +msgstr "El registre ha estat importat des d'aquest backend" + +#. module: connector +#: model:ir.model.fields,help:connector.field_connector_checkpoint_record +msgid "The record to review." +msgstr "" + +#. module: connector +#: model:ir.ui.view,arch_db:connector.view_connector_checkpoint_review +msgid "The selected checkpoints will be set as reviewed." +msgstr "Els seleccionats seran marcats com revisats. " + +#. module: connector +#: model:ir.model.fields,field_description:connector.field_connector_backend_version +msgid "Version" +msgstr "Versió" + +#. module: connector +#: model:ir.actions.act_window,help:connector.action_connector_checkpoint +msgid "" +"When a connector imports new records which have\n" +" configuration or reviews to do manually, they\n" +" will appear in this list. Once a record has been\n" +" checked, click on the 'Reviewed' button." +msgstr "" + +#. module: connector +#: model:ir.model,name:connector.model_base +msgid "base" +msgstr "" + +#. module: connector +#: model:ir.ui.view,arch_db:connector.view_connector_checkpoint_review +#: model:ir.ui.view,arch_db:connector.view_connector_config_settings +msgid "or" +msgstr "o " + +#. module: connector +#: model:ir.ui.view,arch_db:connector.view_connector_checkpoint_form +msgid "to verify it:" +msgstr "per verificar:" diff --git a/ext/3rd-party-addons/connector/i18n/connector.pot b/ext/3rd-party-addons/connector/i18n/connector.pot new file mode 100644 index 00000000..377b7681 --- /dev/null +++ b/ext/3rd-party-addons/connector/i18n/connector.pot @@ -0,0 +1,560 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * connector +# +msgid "" +msgstr "" +"Project-Id-Version: Odoo 10.0\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2013-05-01 13:36+0000\n" +"PO-Revision-Date: 2013-05-01 13:36+0000\n" +"Last-Translator: <>\n" +"Language-Team: \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: \n" +"Plural-Forms: \n" + +#. module: connector +#: view:connector.config.settings:0 +msgid "Apply" +msgstr "" + +#. module: connector +#: model:ir.actions.act_window,name:connector.action_queue_worker +#: model:ir.ui.menu,name:connector.menu_queue_worker +msgid "Workers" +msgstr "" + +#. module: connector +#: model:ir.module.category,name:connector.module_category_connector +#: model:ir.ui.menu,name:connector.menu_connector_config_settings +msgid "Connector" +msgstr "" + +#. module: connector +#: view:connector.checkpoint:0 +msgid "Group By..." +msgstr "" + +#. module: connector +#: field:queue.job,date_done:0 +msgid "Date Done" +msgstr "" + +#. module: connector +#: model:ir.actions.act_window,name:connector.action_queue_job +#: model:ir.ui.menu,name:connector.menu_queue_job +#: view:queue.job:0 +#: field:queue.requeue.job,job_ids:0 +#: field:queue.worker,job_ids:0 +msgid "Jobs" +msgstr "" + +#. module: connector +#: field:connector.config.settings,module_multi_company:0 +msgid "Manage multiple companies" +msgstr "" + +#. module: connector +#: field:connector.checkpoint,message_unread:0 +#: field:queue.job,message_unread:0 +msgid "Unread Messages" +msgstr "" + +#. module: connector +#: field:queue.worker,pid:0 +msgid "PID" +msgstr "" + +#. module: connector +#: field:queue.job,user_id:0 +msgid "User ID" +msgstr "" + +#. module: connector +#: field:connector.checkpoint.review,checkpoint_ids:0 +msgid "Checkpoints" +msgstr "" + +#. module: connector +#: view:queue.requeue.job:0 +msgid "The selected jobs will be requeued." +msgstr "" + +#. module: connector +#: field:queue.job,func_string:0 +msgid "Task" +msgstr "" + +#. module: connector +#: help:connector.checkpoint,record:0 +msgid "The record to check." +msgstr "" + +#. module: connector +#: help:connector.checkpoint,backend_id:0 +msgid "The record has been imported from this backend" +msgstr "" + +#. module: connector +#: model:ir.actions.client,name:connector.action_client_connector_menu +msgid "Open Connector Menu" +msgstr "" + +#. module: connector +#: field:connector.checkpoint,message_ids:0 +#: field:queue.job,message_ids:0 +msgid "Messages" +msgstr "" + +#. module: connector +#: view:queue.job:0 +#: selection:queue.job,state:0 +msgid "Enqueued" +msgstr "" + +#. module: connector +#: help:connector.config.settings,module_portal_anonymous:0 +msgid "Enable the public part of odoo, odoo becomes a public website." +msgstr "" + +#. module: connector +#: field:queue.job,max_retries:0 +msgid "Max. retries" +msgstr "" + +#. module: connector +#: help:connector.checkpoint,message_unread:0 +#: help:queue.job,message_unread:0 +msgid "If checked new messages require your attention." +msgstr "" + +#. module: connector +#: field:queue.job,uuid:0 +#: field:queue.worker,uuid:0 +msgid "UUID" +msgstr "" + +#. module: connector +#: view:connector.config.settings:0 +#: model:ir.actions.act_window,name:connector.action_connector_config_settings +msgid "Configure Connector" +msgstr "" + +#. module: connector +#: field:external.binding,sync_date:0 +msgid "Last synchronization date" +msgstr "" + +#. module: connector +#: model:ir.actions.act_window,help:connector.action_connector_checkpoint +msgid "

No record to check.

\n" +"

When a connector imports new records which have\n" +" configuration or reviews to do manually, they\n" +" will appear in this list. Once a record has been\n" +" checked, click on the 'Reviewed' button.

\n" +"

The connectors list the new records to verify\n" +" based on their type. Only some need a manual\n" +" review.

\n" +" " +msgstr "" + +#. module: connector +#: help:connector.checkpoint,message_summary:0 +#: help:queue.job,message_summary:0 +msgid "Holds the Chatter summary (number of messages, ...). This summary is directly in html format in order to be inserted in kanban views." +msgstr "" + +#. module: connector +#: model:ir.model,name:connector.model_connector_config_settings +msgid "connector.config.settings" +msgstr "" + +#. module: connector +#: model:ir.model,name:connector.model_queue_worker +msgid "queue.worker" +msgstr "" + +#. module: connector +#: help:connector.config.settings,module_magentoerpconnect:0 +msgid "This installs the module magentoerpconnect." +msgstr "" + +#. module: connector +#: field:connector.checkpoint,backend_id:0 +msgid "Imported from" +msgstr "" + +#. module: connector +#: model:ir.model,name:connector.model_queue_requeue_job +msgid "Wizard to requeue a selection of jobs" +msgstr "" + +#. module: connector +#: field:queue.job,priority:0 +msgid "Priority" +msgstr "" + +#. module: connector +#: view:queue.job:0 +#: selection:queue.job,state:0 +msgid "Failed" +msgstr "" + +#. module: connector +#: field:queue.job,state:0 +msgid "State" +msgstr "" + +#. module: connector +#: view:connector.config.settings:0 +msgid "Backends" +msgstr "" + +#. module: connector +#: field:connector.checkpoint,message_follower_ids:0 +#: field:queue.job,message_follower_ids:0 +msgid "Followers" +msgstr "" + +#. module: connector +#: model:ir.model,name:connector.model_queue_job +msgid "Queue Job" +msgstr "" + +#. module: connector +#: field:connector.config.settings,module_base_import:0 +msgid "Allow users to import data from CSV files" +msgstr "" + +#. module: connector +#: field:queue.job,worker_id:0 +#: view:queue.worker:0 +msgid "Worker" +msgstr "" + +#. module: connector +#: view:connector.checkpoint:0 +#: model:ir.actions.act_window,name:connector.action_connector_checkpoint +#: model:ir.model,name:connector.model_connector_checkpoint +msgid "Connector Checkpoint" +msgstr "" + +#. module: connector +#: view:connector.checkpoint.review:0 +#: view:connector.config.settings:0 +#: view:queue.requeue.job:0 +msgid "Cancel" +msgstr "" + +#. module: connector +#: field:queue.job,func:0 +msgid "Pickled Function" +msgstr "" + +#. module: connector +#: model:ir.model,name:connector.model_connector_checkpoint_review +msgid "Checkpoints Review" +msgstr "" + +#. module: connector +#: model:ir.ui.menu,name:connector.menu_queue +msgid "Queue" +msgstr "" + +#. module: connector +#: view:connector.checkpoint.review:0 +msgid "Set as reviewed" +msgstr "" + +#. module: connector +#: field:queue.job,retry:0 +msgid "Current try" +msgstr "" + +#. module: connector +#: field:connector.config.settings,module_portal:0 +msgid "Activate the customer portal" +msgstr "" + +#. module: connector +#: field:queue.job,date_created:0 +msgid "Created Date" +msgstr "" + +#. module: connector +#: field:connector.checkpoint,record:0 +msgid "Record" +msgstr "" + +#. module: connector +#: field:queue.worker,date_alive:0 +msgid "Last Alive Check" +msgstr "" + +#. module: connector +#: view:queue.job:0 +msgid "Set to 'Done'" +msgstr "" + +#. module: connector +#: model:ir.ui.menu,name:connector.menu_connector +#: model:ir.ui.menu,name:connector.menu_connector_root +#: view:res.partner:0 +msgid "Connectors" +msgstr "" + +#. module: connector +#: view:queue.job:0 +#: field:queue.job,result:0 +msgid "Result" +msgstr "" + +#. module: connector +#: field:queue.job,date_started:0 +#: field:queue.worker,date_start:0 +msgid "Start Date" +msgstr "" + +#. module: connector +#: view:connector.checkpoint.review:0 +#: view:connector.config.settings:0 +#: view:queue.requeue.job:0 +msgid "or" +msgstr "" + +#. module: connector +#: field:connector.config.settings,module_auth_oauth:0 +msgid "Use external authentication providers, sign in with google, facebook, ..." +msgstr "" + +#. module: connector +#: model:ir.model,name:connector.model_connector_backend +msgid "connector.backend" +msgstr "" + +#. module: connector +#: view:connector.checkpoint.review:0 +#: model:ir.actions.act_window,name:connector.action_connector_checkpoint_review +msgid "Review Checkpoints" +msgstr "" + +#. module: connector +#: view:queue.job:0 +#: selection:queue.job,state:0 +msgid "Pending" +msgstr "" + +#. module: connector +#: field:connector.checkpoint,state:0 +msgid "Status" +msgstr "" + +#. module: connector +#: view:queue.job:0 +#: selection:queue.job,state:0 +msgid "Started" +msgstr "" + +#. module: connector +#: model:ir.model,name:connector.model_connector_installed +msgid "connector.installed" +msgstr "" + +#. module: connector +#: field:connector.checkpoint,message_is_follower:0 +#: field:queue.job,message_is_follower:0 +msgid "Is a Follower" +msgstr "" + +#. module: connector +#: help:connector.config.settings,module_share:0 +msgid "Share or embbed any screen of odoo." +msgstr "" + +#. module: connector +#: field:queue.job,active:0 +msgid "Active" +msgstr "" + +#. module: connector +#: help:queue.job,max_retries:0 +msgid "The job will fail if the number of tries reach the max. retries.\n" +"Retries are infinite when empty." +msgstr "" + +#. module: connector +#: view:connector.checkpoint:0 +msgid "Click on the" +msgstr "" + +#. module: connector +#: field:connector.checkpoint,message_summary:0 +#: field:queue.job,message_summary:0 +msgid "Summary" +msgstr "" + +#. module: connector +#: view:queue.job:0 +msgid "Exception Information" +msgstr "" + +#. module: connector +#: view:queue.requeue.job:0 +msgid "Requeue" +msgstr "" + +#. module: connector +#: model:ir.ui.menu,name:connector.menu_checkpoint +msgid "Checkpoint" +msgstr "" + +#. module: connector +#: view:connector.checkpoint:0 +#: selection:connector.checkpoint,state:0 +msgid "Reviewed" +msgstr "" + +#. module: connector +#: field:connector.backend,version:0 +msgid "Version" +msgstr "" + +#. module: connector +#: view:queue.job:0 +#: selection:queue.job,state:0 +msgid "Done" +msgstr "" + +#. module: connector +#: view:connector.checkpoint.review:0 +msgid "The selected checkpoints will be set as reviewed." +msgstr "" + +#. module: connector +#: model:ir.actions.act_window,name:connector.action_requeue_job +#: view:queue.requeue.job:0 +msgid "Requeue Jobs" +msgstr "" + +#. module: connector +#: field:queue.job,exc_info:0 +msgid "Exception Info" +msgstr "" + +#. module: connector +#: view:queue.job:0 +msgid "Requeue Job" +msgstr "" + +#. module: connector +#: model:ir.model,name:connector.model_external_binding +msgid "External Binding (abstract)" +msgstr "" + +#. module: connector +#: field:queue.job,name:0 +msgid "Description" +msgstr "" + +#. module: connector +#: view:queue.job:0 +msgid "If the max. retries is 0, the number of retries is infinite." +msgstr "" + +#. module: connector +#: field:queue.job,date_enqueued:0 +msgid "Enqueue Time" +msgstr "" + +#. module: connector +#: field:connector.checkpoint,record_id:0 +msgid "Record ID" +msgstr "" + +#. module: connector +#: help:connector.config.settings,module_multi_company:0 +msgid "Work in multi-company environments, with appropriate security access between companies.\n" +" This installs the module multi_company." +msgstr "" + +#. module: connector +#: field:connector.backend,name:0 +msgid "Name" +msgstr "" + +#. module: connector +#: help:connector.config.settings,alias_domain:0 +msgid "If you have setup a catch-all email domain redirected to the Odoo server, enter the domain name here." +msgstr "" + +#. module: connector +#: field:connector.config.settings,alias_domain:0 +msgid "Alias Domain" +msgstr "" + +#. module: connector +#: view:queue.job:0 +msgid "Current try / max. retries" +msgstr "" + +#. module: connector +#: field:connector.config.settings,module_magentoerpconnect:0 +msgid "Synchronize with Magento" +msgstr "" + +#. module: connector +#: view:connector.checkpoint:0 +msgid "to verify it:" +msgstr "" + +#. module: connector +#: view:connector.checkpoint:0 +#: field:connector.checkpoint,model_id:0 +#: field:queue.job,model_name:0 +msgid "Model" +msgstr "" + +#. module: connector +#: help:connector.checkpoint,message_ids:0 +#: help:queue.job,message_ids:0 +msgid "Messages and communication history" +msgstr "" + +#. module: connector +#: field:connector.config.settings,module_share:0 +msgid "Allow documents sharing" +msgstr "" + +#. module: connector +#: field:connector.config.settings,module_portal_anonymous:0 +msgid "Activate the public portal" +msgstr "" + +#. module: connector +#: model:res.groups,name:connector.group_connector_manager +msgid "Connector Manager" +msgstr "" + +#. module: connector +#: model:mail.message.subtype,name:connector.mt_job_failed +msgid "Job failed" +msgstr "" + +#. module: connector +#: help:connector.config.settings,module_portal:0 +msgid "Give your customers access to their documents." +msgstr "" + +#. module: connector +#: field:queue.job,eta:0 +msgid "Execute only after" +msgstr "" + +#. module: connector +#: view:connector.checkpoint:0 +#: selection:connector.checkpoint,state:0 +msgid "Need Review" +msgstr "" + diff --git a/ext/3rd-party-addons/connector/i18n/cs.po b/ext/3rd-party-addons/connector/i18n/cs.po new file mode 100644 index 00000000..d87bd90f --- /dev/null +++ b/ext/3rd-party-addons/connector/i18n/cs.po @@ -0,0 +1,317 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * connector +# +# Translators: +# OCA Transbot , 2017 +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server 10.0\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2017-03-10 03:36+0000\n" +"PO-Revision-Date: 2017-03-10 03:36+0000\n" +"Last-Translator: OCA Transbot , 2017\n" +"Language-Team: Czech (https://www.transifex.com/oca/teams/23907/cs/)\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: \n" +"Language: cs\n" +"Plural-Forms: nplurals=3; plural=(n==1) ? 0 : (n>=2 && n<=4) ? 1 : 2;\n" + +#. module: connector +#: code:addons/connector/checkpoint/checkpoint.py:119 +#, python-format +msgid "A %s needs a review." +msgstr "" + +#. module: connector +#: model:ir.ui.view,arch_db:connector.view_connector_config_settings +msgid "Apply" +msgstr "" + +#. module: connector +#: model:ir.ui.view,arch_db:connector.view_connector_config_settings +msgid "Backends" +msgstr "" + +#. module: connector +#: model:ir.ui.view,arch_db:connector.view_connector_checkpoint_review +#: model:ir.ui.view,arch_db:connector.view_connector_config_settings +msgid "Cancel" +msgstr "Zrušit" + +#. module: connector +#: model:ir.ui.menu,name:connector.menu_checkpoint +msgid "Checkpoint" +msgstr "" + +#. module: connector +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_review_checkpoint_ids +msgid "Checkpoints" +msgstr "" + +#. module: connector +#: model:ir.model,name:connector.model_connector_checkpoint_review +msgid "Checkpoints Review" +msgstr "" + +#. module: connector +#: model:ir.ui.view,arch_db:connector.view_connector_checkpoint_form +msgid "Click on the" +msgstr "" + +#. module: connector +#: model:ir.actions.act_window,name:connector.action_connector_config_settings +#: model:ir.ui.view,arch_db:connector.view_connector_config_settings +msgid "Configure Connector" +msgstr "" + +#. module: connector +#: model:ir.module.category,name:connector.module_category_connector +#: model:ir.ui.menu,name:connector.menu_connector_config_settings +msgid "Connector" +msgstr "" + +#. module: connector +#: model:ir.model,name:connector.model_connector_backend +msgid "Connector Backend" +msgstr "" + +#. module: connector +#: model:ir.actions.act_window,name:connector.action_connector_checkpoint +#: model:ir.model,name:connector.model_connector_checkpoint +#: model:ir.ui.view,arch_db:connector.view_connector_checkpoint_form +#: model:ir.ui.view,arch_db:connector.view_connector_checkpoint_search +#: model:ir.ui.view,arch_db:connector.view_connector_checkpoint_tree +msgid "Connector Checkpoint" +msgstr "" + +#. module: connector +#: model:ir.model,name:connector.model_connector_config_settings +msgid "Connector Configuration" +msgstr "" + +#. module: connector +#: model:res.groups,name:connector.group_connector_manager +msgid "Connector Manager" +msgstr "" + +#. module: connector +#: model:ir.ui.menu,name:connector.menu_connector +#: model:ir.ui.menu,name:connector.menu_connector_root +#: model:ir.ui.view,arch_db:connector.view_partner_connector_form +msgid "Connectors" +msgstr "" + +#. module: connector +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_create_uid +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_review_create_uid +#: model:ir.model.fields,field_description:connector.field_connector_config_settings_create_uid +msgid "Created by" +msgstr "" + +#. module: connector +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_create_date +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_review_create_date +#: model:ir.model.fields,field_description:connector.field_connector_config_settings_create_date +msgid "Created on" +msgstr "" + +#. module: connector +#: model:ir.model.fields,field_description:connector.field_connector_backend_display_name +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_display_name +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_review_display_name +#: model:ir.model.fields,field_description:connector.field_connector_config_settings_display_name +#: model:ir.model.fields,field_description:connector.field_external_binding_display_name +msgid "Display Name" +msgstr "" + +#. module: connector +#: model:ir.model,name:connector.model_external_binding +msgid "External Binding (abstract)" +msgstr "" + +#. module: connector +#: model:ir.ui.view,arch_db:connector.view_connector_checkpoint_search +msgid "Group By..." +msgstr "" + +#. module: connector +#: model:ir.model.fields,field_description:connector.field_connector_backend_id +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_id +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_review_id +#: model:ir.model.fields,field_description:connector.field_connector_config_settings_id +#: model:ir.model.fields,field_description:connector.field_external_binding_id +msgid "ID" +msgstr "" + +#. module: connector +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_backend_id +msgid "Imported from" +msgstr "" + +#. module: connector +#: model:ir.model.fields,field_description:connector.field_connector_backend___last_update +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint___last_update +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_review___last_update +#: model:ir.model.fields,field_description:connector.field_connector_config_settings___last_update +#: model:ir.model.fields,field_description:connector.field_external_binding___last_update +msgid "Last Modified on" +msgstr "" + +#. module: connector +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_review_write_uid +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_write_uid +#: model:ir.model.fields,field_description:connector.field_connector_config_settings_write_uid +msgid "Last Updated by" +msgstr "" + +#. module: connector +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_review_write_date +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_write_date +#: model:ir.model.fields,field_description:connector.field_connector_config_settings_write_date +msgid "Last Updated on" +msgstr "" + +#. module: connector +#: model:ir.model.fields,field_description:connector.field_connector_test_binding_sync_date +#: model:ir.model.fields,field_description:connector.field_external_binding_sync_date +#: model:ir.model.fields,field_description:connector.field_no_inherits_binding_sync_date +msgid "Last synchronization date" +msgstr "" + +#. module: connector +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_model_id +#: model:ir.ui.view,arch_db:connector.view_connector_checkpoint_search +msgid "Model" +msgstr "" + +#. module: connector +#: model:ir.model.fields,field_description:connector.field_connector_backend_name +#: model:ir.model.fields,field_description:connector.field_test_backend_name +msgid "Name" +msgstr "" + +#. module: connector +#: model:ir.model.fields,help:connector.field_connector_checkpoint_name +msgid "Name of the record to review" +msgstr "" + +#. module: connector +#: selection:connector.checkpoint,state:0 +#: model:ir.ui.view,arch_db:connector.view_connector_checkpoint_search +msgid "Need Review" +msgstr "" + +#. module: connector +#: model:ir.actions.act_window,help:connector.action_connector_checkpoint +msgid "No record to check." +msgstr "" + +#. module: connector +#: model:ir.actions.client,name:connector.action_client_connector_menu +msgid "Open Connector Menu" +msgstr "" + +#. module: connector +#: model:ir.model,name:connector.model_queue_job +msgid "Queue Job" +msgstr "" + +#. module: connector +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_record +msgid "Record" +msgstr "" + +#. module: connector +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_record_id +msgid "Record ID" +msgstr "" + +#. module: connector +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_name +msgid "Record Name" +msgstr "" + +#. module: connector +#: code:addons/connector/models/queue_job.py:32 +#, python-format +msgid "Related Record" +msgstr "" + +#. module: connector +#: model:ir.actions.act_window,name:connector.action_connector_checkpoint_review +#: model:ir.ui.view,arch_db:connector.view_connector_checkpoint_review +msgid "Review Checkpoints" +msgstr "" + +#. module: connector +#: selection:connector.checkpoint,state:0 +#: model:ir.ui.view,arch_db:connector.view_connector_checkpoint_form +#: model:ir.ui.view,arch_db:connector.view_connector_checkpoint_search +#: model:ir.ui.view,arch_db:connector.view_connector_checkpoint_tree +msgid "Reviewed" +msgstr "" + +#. module: connector +#: model:ir.ui.view,arch_db:connector.view_connector_checkpoint_review +msgid "Set as reviewed" +msgstr "" + +#. module: connector +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_state +msgid "Status" +msgstr "" + +#. module: connector +#: model:ir.actions.act_window,help:connector.action_connector_checkpoint +msgid "" +"The connectors list the new records to verify\n" +" based on their type. Only some need a manual\n" +" review." +msgstr "" + +#. module: connector +#: model:ir.model.fields,help:connector.field_connector_checkpoint_backend_id +msgid "The record has been imported from this backend" +msgstr "" + +#. module: connector +#: model:ir.model.fields,help:connector.field_connector_checkpoint_record +msgid "The record to review." +msgstr "" + +#. module: connector +#: model:ir.ui.view,arch_db:connector.view_connector_checkpoint_review +msgid "The selected checkpoints will be set as reviewed." +msgstr "" + +#. module: connector +#: model:ir.model.fields,field_description:connector.field_connector_backend_version +msgid "Version" +msgstr "" + +#. module: connector +#: model:ir.actions.act_window,help:connector.action_connector_checkpoint +msgid "" +"When a connector imports new records which have\n" +" configuration or reviews to do manually, they\n" +" will appear in this list. Once a record has been\n" +" checked, click on the 'Reviewed' button." +msgstr "" + +#. module: connector +#: model:ir.model,name:connector.model_base +msgid "base" +msgstr "" + +#. module: connector +#: model:ir.ui.view,arch_db:connector.view_connector_checkpoint_review +#: model:ir.ui.view,arch_db:connector.view_connector_config_settings +msgid "or" +msgstr "" + +#. module: connector +#: model:ir.ui.view,arch_db:connector.view_connector_checkpoint_form +msgid "to verify it:" +msgstr "" diff --git a/ext/3rd-party-addons/connector/i18n/de.po b/ext/3rd-party-addons/connector/i18n/de.po new file mode 100644 index 00000000..5d370a27 --- /dev/null +++ b/ext/3rd-party-addons/connector/i18n/de.po @@ -0,0 +1,317 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * connector +# +# Translators: +# OCA Transbot , 2017 +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server 10.0\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2017-03-10 03:36+0000\n" +"PO-Revision-Date: 2017-03-10 03:36+0000\n" +"Last-Translator: OCA Transbot , 2017\n" +"Language-Team: German (https://www.transifex.com/oca/teams/23907/de/)\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: \n" +"Language: de\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" + +#. module: connector +#: code:addons/connector/checkpoint/checkpoint.py:119 +#, python-format +msgid "A %s needs a review." +msgstr "Ein %s erfordert Sichtung" + +#. module: connector +#: model:ir.ui.view,arch_db:connector.view_connector_config_settings +msgid "Apply" +msgstr "anwenden" + +#. module: connector +#: model:ir.ui.view,arch_db:connector.view_connector_config_settings +msgid "Backends" +msgstr "Backends" + +#. module: connector +#: model:ir.ui.view,arch_db:connector.view_connector_checkpoint_review +#: model:ir.ui.view,arch_db:connector.view_connector_config_settings +msgid "Cancel" +msgstr "Abbrechen" + +#. module: connector +#: model:ir.ui.menu,name:connector.menu_checkpoint +msgid "Checkpoint" +msgstr "Checkpunkt" + +#. module: connector +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_review_checkpoint_ids +msgid "Checkpoints" +msgstr "Checkpunkte" + +#. module: connector +#: model:ir.model,name:connector.model_connector_checkpoint_review +msgid "Checkpoints Review" +msgstr "Checkpunkt Überprüfung" + +#. module: connector +#: model:ir.ui.view,arch_db:connector.view_connector_checkpoint_form +msgid "Click on the" +msgstr "Klicken Sie auf den" + +#. module: connector +#: model:ir.actions.act_window,name:connector.action_connector_config_settings +#: model:ir.ui.view,arch_db:connector.view_connector_config_settings +msgid "Configure Connector" +msgstr "Connector konfigurieren" + +#. module: connector +#: model:ir.module.category,name:connector.module_category_connector +#: model:ir.ui.menu,name:connector.menu_connector_config_settings +msgid "Connector" +msgstr "Connector" + +#. module: connector +#: model:ir.model,name:connector.model_connector_backend +msgid "Connector Backend" +msgstr "Connector Backend" + +#. module: connector +#: model:ir.actions.act_window,name:connector.action_connector_checkpoint +#: model:ir.model,name:connector.model_connector_checkpoint +#: model:ir.ui.view,arch_db:connector.view_connector_checkpoint_form +#: model:ir.ui.view,arch_db:connector.view_connector_checkpoint_search +#: model:ir.ui.view,arch_db:connector.view_connector_checkpoint_tree +msgid "Connector Checkpoint" +msgstr "Connector Checkpunkt" + +#. module: connector +#: model:ir.model,name:connector.model_connector_config_settings +msgid "Connector Configuration" +msgstr "Connector-Einstellungen" + +#. module: connector +#: model:res.groups,name:connector.group_connector_manager +msgid "Connector Manager" +msgstr "Connector Manager" + +#. module: connector +#: model:ir.ui.menu,name:connector.menu_connector +#: model:ir.ui.menu,name:connector.menu_connector_root +#: model:ir.ui.view,arch_db:connector.view_partner_connector_form +msgid "Connectors" +msgstr "Connector" + +#. module: connector +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_create_uid +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_review_create_uid +#: model:ir.model.fields,field_description:connector.field_connector_config_settings_create_uid +msgid "Created by" +msgstr "Angelegt durch" + +#. module: connector +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_create_date +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_review_create_date +#: model:ir.model.fields,field_description:connector.field_connector_config_settings_create_date +msgid "Created on" +msgstr "Angelegt am" + +#. module: connector +#: model:ir.model.fields,field_description:connector.field_connector_backend_display_name +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_display_name +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_review_display_name +#: model:ir.model.fields,field_description:connector.field_connector_config_settings_display_name +#: model:ir.model.fields,field_description:connector.field_external_binding_display_name +msgid "Display Name" +msgstr "Anzeigebezeichnung" + +#. module: connector +#: model:ir.model,name:connector.model_external_binding +msgid "External Binding (abstract)" +msgstr "Externe Verbindung (abstrakt)" + +#. module: connector +#: model:ir.ui.view,arch_db:connector.view_connector_checkpoint_search +msgid "Group By..." +msgstr "Gruppieren nach ..." + +#. module: connector +#: model:ir.model.fields,field_description:connector.field_connector_backend_id +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_id +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_review_id +#: model:ir.model.fields,field_description:connector.field_connector_config_settings_id +#: model:ir.model.fields,field_description:connector.field_external_binding_id +msgid "ID" +msgstr "ID" + +#. module: connector +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_backend_id +msgid "Imported from" +msgstr "Importiert von" + +#. module: connector +#: model:ir.model.fields,field_description:connector.field_connector_backend___last_update +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint___last_update +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_review___last_update +#: model:ir.model.fields,field_description:connector.field_connector_config_settings___last_update +#: model:ir.model.fields,field_description:connector.field_external_binding___last_update +msgid "Last Modified on" +msgstr "Zuletzt aktualisiert am" + +#. module: connector +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_review_write_uid +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_write_uid +#: model:ir.model.fields,field_description:connector.field_connector_config_settings_write_uid +msgid "Last Updated by" +msgstr "Zuletzt aktualisiert durch" + +#. module: connector +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_review_write_date +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_write_date +#: model:ir.model.fields,field_description:connector.field_connector_config_settings_write_date +msgid "Last Updated on" +msgstr "Zuletzt aktualisiert am" + +#. module: connector +#: model:ir.model.fields,field_description:connector.field_connector_test_binding_sync_date +#: model:ir.model.fields,field_description:connector.field_external_binding_sync_date +#: model:ir.model.fields,field_description:connector.field_no_inherits_binding_sync_date +msgid "Last synchronization date" +msgstr "Letztes Synchronisationsdatum" + +#. module: connector +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_model_id +#: model:ir.ui.view,arch_db:connector.view_connector_checkpoint_search +msgid "Model" +msgstr "Modell" + +#. module: connector +#: model:ir.model.fields,field_description:connector.field_connector_backend_name +#: model:ir.model.fields,field_description:connector.field_test_backend_name +msgid "Name" +msgstr "Name" + +#. module: connector +#: model:ir.model.fields,help:connector.field_connector_checkpoint_name +msgid "Name of the record to review" +msgstr "Bezeichnung des zu prüfenden Datensatzes" + +#. module: connector +#: selection:connector.checkpoint,state:0 +#: model:ir.ui.view,arch_db:connector.view_connector_checkpoint_search +msgid "Need Review" +msgstr "Benötigt Prüfung" + +#. module: connector +#: model:ir.actions.act_window,help:connector.action_connector_checkpoint +msgid "No record to check." +msgstr "Kein Datensatz zu prüfen." + +#. module: connector +#: model:ir.actions.client,name:connector.action_client_connector_menu +msgid "Open Connector Menu" +msgstr "Open Connector Menü" + +#. module: connector +#: model:ir.model,name:connector.model_queue_job +msgid "Queue Job" +msgstr "Aufgabe in Warteschlange einreihen" + +#. module: connector +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_record +msgid "Record" +msgstr "Datensatz" + +#. module: connector +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_record_id +msgid "Record ID" +msgstr "Datensatz Nr." + +#. module: connector +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_name +msgid "Record Name" +msgstr "Datensatz-Bezeichnung" + +#. module: connector +#: code:addons/connector/models/queue_job.py:32 +#, python-format +msgid "Related Record" +msgstr "Zugehöriger Datensatz" + +#. module: connector +#: model:ir.actions.act_window,name:connector.action_connector_checkpoint_review +#: model:ir.ui.view,arch_db:connector.view_connector_checkpoint_review +msgid "Review Checkpoints" +msgstr "Überprüfungs Checkpunkte" + +#. module: connector +#: selection:connector.checkpoint,state:0 +#: model:ir.ui.view,arch_db:connector.view_connector_checkpoint_form +#: model:ir.ui.view,arch_db:connector.view_connector_checkpoint_search +#: model:ir.ui.view,arch_db:connector.view_connector_checkpoint_tree +msgid "Reviewed" +msgstr "Überprüft" + +#. module: connector +#: model:ir.ui.view,arch_db:connector.view_connector_checkpoint_review +msgid "Set as reviewed" +msgstr "Als Überprüft markieren" + +#. module: connector +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_state +msgid "Status" +msgstr "Status" + +#. module: connector +#: model:ir.actions.act_window,help:connector.action_connector_checkpoint +msgid "" +"The connectors list the new records to verify\n" +" based on their type. Only some need a manual\n" +" review." +msgstr "" + +#. module: connector +#: model:ir.model.fields,help:connector.field_connector_checkpoint_backend_id +msgid "The record has been imported from this backend" +msgstr "Der Eintrag wurde von diesem Backend importiert." + +#. module: connector +#: model:ir.model.fields,help:connector.field_connector_checkpoint_record +msgid "The record to review." +msgstr "Der zu prüfende Datensatz." + +#. module: connector +#: model:ir.ui.view,arch_db:connector.view_connector_checkpoint_review +msgid "The selected checkpoints will be set as reviewed." +msgstr "Die ausgewählten Checkpunkte werden als überprüft markiert." + +#. module: connector +#: model:ir.model.fields,field_description:connector.field_connector_backend_version +msgid "Version" +msgstr "Version" + +#. module: connector +#: model:ir.actions.act_window,help:connector.action_connector_checkpoint +msgid "" +"When a connector imports new records which have\n" +" configuration or reviews to do manually, they\n" +" will appear in this list. Once a record has been\n" +" checked, click on the 'Reviewed' button." +msgstr "" + +#. module: connector +#: model:ir.model,name:connector.model_base +msgid "base" +msgstr "" + +#. module: connector +#: model:ir.ui.view,arch_db:connector.view_connector_checkpoint_review +#: model:ir.ui.view,arch_db:connector.view_connector_config_settings +msgid "or" +msgstr "oder" + +#. module: connector +#: model:ir.ui.view,arch_db:connector.view_connector_checkpoint_form +msgid "to verify it:" +msgstr "es zu überprüfen:" diff --git a/ext/3rd-party-addons/connector/i18n/el_GR.po b/ext/3rd-party-addons/connector/i18n/el_GR.po new file mode 100644 index 00000000..4bcb5284 --- /dev/null +++ b/ext/3rd-party-addons/connector/i18n/el_GR.po @@ -0,0 +1,317 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * connector +# +# Translators: +# OCA Transbot , 2017 +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server 10.0\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2017-03-10 03:36+0000\n" +"PO-Revision-Date: 2017-03-10 03:36+0000\n" +"Last-Translator: OCA Transbot , 2017\n" +"Language-Team: Greek (Greece) (https://www.transifex.com/oca/teams/23907/el_GR/)\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: \n" +"Language: el_GR\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" + +#. module: connector +#: code:addons/connector/checkpoint/checkpoint.py:119 +#, python-format +msgid "A %s needs a review." +msgstr "" + +#. module: connector +#: model:ir.ui.view,arch_db:connector.view_connector_config_settings +msgid "Apply" +msgstr "" + +#. module: connector +#: model:ir.ui.view,arch_db:connector.view_connector_config_settings +msgid "Backends" +msgstr "" + +#. module: connector +#: model:ir.ui.view,arch_db:connector.view_connector_checkpoint_review +#: model:ir.ui.view,arch_db:connector.view_connector_config_settings +msgid "Cancel" +msgstr "" + +#. module: connector +#: model:ir.ui.menu,name:connector.menu_checkpoint +msgid "Checkpoint" +msgstr "" + +#. module: connector +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_review_checkpoint_ids +msgid "Checkpoints" +msgstr "" + +#. module: connector +#: model:ir.model,name:connector.model_connector_checkpoint_review +msgid "Checkpoints Review" +msgstr "" + +#. module: connector +#: model:ir.ui.view,arch_db:connector.view_connector_checkpoint_form +msgid "Click on the" +msgstr "" + +#. module: connector +#: model:ir.actions.act_window,name:connector.action_connector_config_settings +#: model:ir.ui.view,arch_db:connector.view_connector_config_settings +msgid "Configure Connector" +msgstr "" + +#. module: connector +#: model:ir.module.category,name:connector.module_category_connector +#: model:ir.ui.menu,name:connector.menu_connector_config_settings +msgid "Connector" +msgstr "" + +#. module: connector +#: model:ir.model,name:connector.model_connector_backend +msgid "Connector Backend" +msgstr "" + +#. module: connector +#: model:ir.actions.act_window,name:connector.action_connector_checkpoint +#: model:ir.model,name:connector.model_connector_checkpoint +#: model:ir.ui.view,arch_db:connector.view_connector_checkpoint_form +#: model:ir.ui.view,arch_db:connector.view_connector_checkpoint_search +#: model:ir.ui.view,arch_db:connector.view_connector_checkpoint_tree +msgid "Connector Checkpoint" +msgstr "" + +#. module: connector +#: model:ir.model,name:connector.model_connector_config_settings +msgid "Connector Configuration" +msgstr "" + +#. module: connector +#: model:res.groups,name:connector.group_connector_manager +msgid "Connector Manager" +msgstr "" + +#. module: connector +#: model:ir.ui.menu,name:connector.menu_connector +#: model:ir.ui.menu,name:connector.menu_connector_root +#: model:ir.ui.view,arch_db:connector.view_partner_connector_form +msgid "Connectors" +msgstr "" + +#. module: connector +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_create_uid +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_review_create_uid +#: model:ir.model.fields,field_description:connector.field_connector_config_settings_create_uid +msgid "Created by" +msgstr "Δημιουργήθηκε από " + +#. module: connector +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_create_date +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_review_create_date +#: model:ir.model.fields,field_description:connector.field_connector_config_settings_create_date +msgid "Created on" +msgstr "Δημιουργήθηκε στις" + +#. module: connector +#: model:ir.model.fields,field_description:connector.field_connector_backend_display_name +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_display_name +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_review_display_name +#: model:ir.model.fields,field_description:connector.field_connector_config_settings_display_name +#: model:ir.model.fields,field_description:connector.field_external_binding_display_name +msgid "Display Name" +msgstr "" + +#. module: connector +#: model:ir.model,name:connector.model_external_binding +msgid "External Binding (abstract)" +msgstr "" + +#. module: connector +#: model:ir.ui.view,arch_db:connector.view_connector_checkpoint_search +msgid "Group By..." +msgstr "" + +#. module: connector +#: model:ir.model.fields,field_description:connector.field_connector_backend_id +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_id +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_review_id +#: model:ir.model.fields,field_description:connector.field_connector_config_settings_id +#: model:ir.model.fields,field_description:connector.field_external_binding_id +msgid "ID" +msgstr "Κωδικός" + +#. module: connector +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_backend_id +msgid "Imported from" +msgstr "" + +#. module: connector +#: model:ir.model.fields,field_description:connector.field_connector_backend___last_update +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint___last_update +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_review___last_update +#: model:ir.model.fields,field_description:connector.field_connector_config_settings___last_update +#: model:ir.model.fields,field_description:connector.field_external_binding___last_update +msgid "Last Modified on" +msgstr "" + +#. module: connector +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_review_write_uid +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_write_uid +#: model:ir.model.fields,field_description:connector.field_connector_config_settings_write_uid +msgid "Last Updated by" +msgstr "Τελευταία ενημέρωση από" + +#. module: connector +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_review_write_date +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_write_date +#: model:ir.model.fields,field_description:connector.field_connector_config_settings_write_date +msgid "Last Updated on" +msgstr "Τελευταία ενημέρωση στις" + +#. module: connector +#: model:ir.model.fields,field_description:connector.field_connector_test_binding_sync_date +#: model:ir.model.fields,field_description:connector.field_external_binding_sync_date +#: model:ir.model.fields,field_description:connector.field_no_inherits_binding_sync_date +msgid "Last synchronization date" +msgstr "" + +#. module: connector +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_model_id +#: model:ir.ui.view,arch_db:connector.view_connector_checkpoint_search +msgid "Model" +msgstr "" + +#. module: connector +#: model:ir.model.fields,field_description:connector.field_connector_backend_name +#: model:ir.model.fields,field_description:connector.field_test_backend_name +msgid "Name" +msgstr "" + +#. module: connector +#: model:ir.model.fields,help:connector.field_connector_checkpoint_name +msgid "Name of the record to review" +msgstr "" + +#. module: connector +#: selection:connector.checkpoint,state:0 +#: model:ir.ui.view,arch_db:connector.view_connector_checkpoint_search +msgid "Need Review" +msgstr "" + +#. module: connector +#: model:ir.actions.act_window,help:connector.action_connector_checkpoint +msgid "No record to check." +msgstr "" + +#. module: connector +#: model:ir.actions.client,name:connector.action_client_connector_menu +msgid "Open Connector Menu" +msgstr "" + +#. module: connector +#: model:ir.model,name:connector.model_queue_job +msgid "Queue Job" +msgstr "" + +#. module: connector +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_record +msgid "Record" +msgstr "" + +#. module: connector +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_record_id +msgid "Record ID" +msgstr "" + +#. module: connector +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_name +msgid "Record Name" +msgstr "" + +#. module: connector +#: code:addons/connector/models/queue_job.py:32 +#, python-format +msgid "Related Record" +msgstr "" + +#. module: connector +#: model:ir.actions.act_window,name:connector.action_connector_checkpoint_review +#: model:ir.ui.view,arch_db:connector.view_connector_checkpoint_review +msgid "Review Checkpoints" +msgstr "" + +#. module: connector +#: selection:connector.checkpoint,state:0 +#: model:ir.ui.view,arch_db:connector.view_connector_checkpoint_form +#: model:ir.ui.view,arch_db:connector.view_connector_checkpoint_search +#: model:ir.ui.view,arch_db:connector.view_connector_checkpoint_tree +msgid "Reviewed" +msgstr "" + +#. module: connector +#: model:ir.ui.view,arch_db:connector.view_connector_checkpoint_review +msgid "Set as reviewed" +msgstr "" + +#. module: connector +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_state +msgid "Status" +msgstr "" + +#. module: connector +#: model:ir.actions.act_window,help:connector.action_connector_checkpoint +msgid "" +"The connectors list the new records to verify\n" +" based on their type. Only some need a manual\n" +" review." +msgstr "" + +#. module: connector +#: model:ir.model.fields,help:connector.field_connector_checkpoint_backend_id +msgid "The record has been imported from this backend" +msgstr "" + +#. module: connector +#: model:ir.model.fields,help:connector.field_connector_checkpoint_record +msgid "The record to review." +msgstr "" + +#. module: connector +#: model:ir.ui.view,arch_db:connector.view_connector_checkpoint_review +msgid "The selected checkpoints will be set as reviewed." +msgstr "" + +#. module: connector +#: model:ir.model.fields,field_description:connector.field_connector_backend_version +msgid "Version" +msgstr "" + +#. module: connector +#: model:ir.actions.act_window,help:connector.action_connector_checkpoint +msgid "" +"When a connector imports new records which have\n" +" configuration or reviews to do manually, they\n" +" will appear in this list. Once a record has been\n" +" checked, click on the 'Reviewed' button." +msgstr "" + +#. module: connector +#: model:ir.model,name:connector.model_base +msgid "base" +msgstr "" + +#. module: connector +#: model:ir.ui.view,arch_db:connector.view_connector_checkpoint_review +#: model:ir.ui.view,arch_db:connector.view_connector_config_settings +msgid "or" +msgstr "" + +#. module: connector +#: model:ir.ui.view,arch_db:connector.view_connector_checkpoint_form +msgid "to verify it:" +msgstr "" diff --git a/ext/3rd-party-addons/connector/i18n/es.po b/ext/3rd-party-addons/connector/i18n/es.po new file mode 100644 index 00000000..987ba73b --- /dev/null +++ b/ext/3rd-party-addons/connector/i18n/es.po @@ -0,0 +1,317 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * connector +# +# Translators: +# OCA Transbot , 2017 +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server 10.0\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2017-03-10 03:36+0000\n" +"PO-Revision-Date: 2017-03-10 03:36+0000\n" +"Last-Translator: OCA Transbot , 2017\n" +"Language-Team: Spanish (https://www.transifex.com/oca/teams/23907/es/)\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: \n" +"Language: es\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" + +#. module: connector +#: code:addons/connector/checkpoint/checkpoint.py:119 +#, python-format +msgid "A %s needs a review." +msgstr "" + +#. module: connector +#: model:ir.ui.view,arch_db:connector.view_connector_config_settings +msgid "Apply" +msgstr "Aplicar" + +#. module: connector +#: model:ir.ui.view,arch_db:connector.view_connector_config_settings +msgid "Backends" +msgstr "Áreas de administración" + +#. module: connector +#: model:ir.ui.view,arch_db:connector.view_connector_checkpoint_review +#: model:ir.ui.view,arch_db:connector.view_connector_config_settings +msgid "Cancel" +msgstr "Cancelar" + +#. module: connector +#: model:ir.ui.menu,name:connector.menu_checkpoint +msgid "Checkpoint" +msgstr "Punto Control" + +#. module: connector +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_review_checkpoint_ids +msgid "Checkpoints" +msgstr "Puntos de control" + +#. module: connector +#: model:ir.model,name:connector.model_connector_checkpoint_review +msgid "Checkpoints Review" +msgstr "Revisión de puntos de control" + +#. module: connector +#: model:ir.ui.view,arch_db:connector.view_connector_checkpoint_form +msgid "Click on the" +msgstr "Hcer clic en" + +#. module: connector +#: model:ir.actions.act_window,name:connector.action_connector_config_settings +#: model:ir.ui.view,arch_db:connector.view_connector_config_settings +msgid "Configure Connector" +msgstr "Configurar el conector" + +#. module: connector +#: model:ir.module.category,name:connector.module_category_connector +#: model:ir.ui.menu,name:connector.menu_connector_config_settings +msgid "Connector" +msgstr "Conector" + +#. module: connector +#: model:ir.model,name:connector.model_connector_backend +msgid "Connector Backend" +msgstr "" + +#. module: connector +#: model:ir.actions.act_window,name:connector.action_connector_checkpoint +#: model:ir.model,name:connector.model_connector_checkpoint +#: model:ir.ui.view,arch_db:connector.view_connector_checkpoint_form +#: model:ir.ui.view,arch_db:connector.view_connector_checkpoint_search +#: model:ir.ui.view,arch_db:connector.view_connector_checkpoint_tree +msgid "Connector Checkpoint" +msgstr "Punto de Control del Conector" + +#. module: connector +#: model:ir.model,name:connector.model_connector_config_settings +msgid "Connector Configuration" +msgstr "" + +#. module: connector +#: model:res.groups,name:connector.group_connector_manager +msgid "Connector Manager" +msgstr "Administrador del Conector" + +#. module: connector +#: model:ir.ui.menu,name:connector.menu_connector +#: model:ir.ui.menu,name:connector.menu_connector_root +#: model:ir.ui.view,arch_db:connector.view_partner_connector_form +msgid "Connectors" +msgstr "Conectores" + +#. module: connector +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_create_uid +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_review_create_uid +#: model:ir.model.fields,field_description:connector.field_connector_config_settings_create_uid +msgid "Created by" +msgstr "Creado por" + +#. module: connector +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_create_date +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_review_create_date +#: model:ir.model.fields,field_description:connector.field_connector_config_settings_create_date +msgid "Created on" +msgstr "Creado en" + +#. module: connector +#: model:ir.model.fields,field_description:connector.field_connector_backend_display_name +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_display_name +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_review_display_name +#: model:ir.model.fields,field_description:connector.field_connector_config_settings_display_name +#: model:ir.model.fields,field_description:connector.field_external_binding_display_name +msgid "Display Name" +msgstr "Nombre mostrado" + +#. module: connector +#: model:ir.model,name:connector.model_external_binding +msgid "External Binding (abstract)" +msgstr "Unión Externa (abstracto)" + +#. module: connector +#: model:ir.ui.view,arch_db:connector.view_connector_checkpoint_search +msgid "Group By..." +msgstr "Agrupar Por..." + +#. module: connector +#: model:ir.model.fields,field_description:connector.field_connector_backend_id +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_id +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_review_id +#: model:ir.model.fields,field_description:connector.field_connector_config_settings_id +#: model:ir.model.fields,field_description:connector.field_external_binding_id +msgid "ID" +msgstr "ID" + +#. module: connector +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_backend_id +msgid "Imported from" +msgstr "Importado de" + +#. module: connector +#: model:ir.model.fields,field_description:connector.field_connector_backend___last_update +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint___last_update +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_review___last_update +#: model:ir.model.fields,field_description:connector.field_connector_config_settings___last_update +#: model:ir.model.fields,field_description:connector.field_external_binding___last_update +msgid "Last Modified on" +msgstr "Última modificación el" + +#. module: connector +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_review_write_uid +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_write_uid +#: model:ir.model.fields,field_description:connector.field_connector_config_settings_write_uid +msgid "Last Updated by" +msgstr "Última actualización por" + +#. module: connector +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_review_write_date +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_write_date +#: model:ir.model.fields,field_description:connector.field_connector_config_settings_write_date +msgid "Last Updated on" +msgstr "Última actualización el" + +#. module: connector +#: model:ir.model.fields,field_description:connector.field_connector_test_binding_sync_date +#: model:ir.model.fields,field_description:connector.field_external_binding_sync_date +#: model:ir.model.fields,field_description:connector.field_no_inherits_binding_sync_date +msgid "Last synchronization date" +msgstr "Última fecha de sincronización" + +#. module: connector +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_model_id +#: model:ir.ui.view,arch_db:connector.view_connector_checkpoint_search +msgid "Model" +msgstr "Modelo" + +#. module: connector +#: model:ir.model.fields,field_description:connector.field_connector_backend_name +#: model:ir.model.fields,field_description:connector.field_test_backend_name +msgid "Name" +msgstr "Nombre" + +#. module: connector +#: model:ir.model.fields,help:connector.field_connector_checkpoint_name +msgid "Name of the record to review" +msgstr "" + +#. module: connector +#: selection:connector.checkpoint,state:0 +#: model:ir.ui.view,arch_db:connector.view_connector_checkpoint_search +msgid "Need Review" +msgstr "Necesita Revisión" + +#. module: connector +#: model:ir.actions.act_window,help:connector.action_connector_checkpoint +msgid "No record to check." +msgstr "" + +#. module: connector +#: model:ir.actions.client,name:connector.action_client_connector_menu +msgid "Open Connector Menu" +msgstr "Menú del Open Connector" + +#. module: connector +#: model:ir.model,name:connector.model_queue_job +msgid "Queue Job" +msgstr "Trabajo de Cola" + +#. module: connector +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_record +msgid "Record" +msgstr "" + +#. module: connector +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_record_id +msgid "Record ID" +msgstr "ID de Registro" + +#. module: connector +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_name +msgid "Record Name" +msgstr "" + +#. module: connector +#: code:addons/connector/models/queue_job.py:32 +#, python-format +msgid "Related Record" +msgstr "" + +#. module: connector +#: model:ir.actions.act_window,name:connector.action_connector_checkpoint_review +#: model:ir.ui.view,arch_db:connector.view_connector_checkpoint_review +msgid "Review Checkpoints" +msgstr "Puntos de Control de Revisión" + +#. module: connector +#: selection:connector.checkpoint,state:0 +#: model:ir.ui.view,arch_db:connector.view_connector_checkpoint_form +#: model:ir.ui.view,arch_db:connector.view_connector_checkpoint_search +#: model:ir.ui.view,arch_db:connector.view_connector_checkpoint_tree +msgid "Reviewed" +msgstr "Revisado" + +#. module: connector +#: model:ir.ui.view,arch_db:connector.view_connector_checkpoint_review +msgid "Set as reviewed" +msgstr "Marcar como Revisado" + +#. module: connector +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_state +msgid "Status" +msgstr "Estado" + +#. module: connector +#: model:ir.actions.act_window,help:connector.action_connector_checkpoint +msgid "" +"The connectors list the new records to verify\n" +" based on their type. Only some need a manual\n" +" review." +msgstr "" + +#. module: connector +#: model:ir.model.fields,help:connector.field_connector_checkpoint_backend_id +msgid "The record has been imported from this backend" +msgstr "El registro ha sido importado de esta área de administación" + +#. module: connector +#: model:ir.model.fields,help:connector.field_connector_checkpoint_record +msgid "The record to review." +msgstr "" + +#. module: connector +#: model:ir.ui.view,arch_db:connector.view_connector_checkpoint_review +msgid "The selected checkpoints will be set as reviewed." +msgstr "Los puntos de control seleccionados serán marcados como revisados" + +#. module: connector +#: model:ir.model.fields,field_description:connector.field_connector_backend_version +msgid "Version" +msgstr "Versión" + +#. module: connector +#: model:ir.actions.act_window,help:connector.action_connector_checkpoint +msgid "" +"When a connector imports new records which have\n" +" configuration or reviews to do manually, they\n" +" will appear in this list. Once a record has been\n" +" checked, click on the 'Reviewed' button." +msgstr "" + +#. module: connector +#: model:ir.model,name:connector.model_base +msgid "base" +msgstr "" + +#. module: connector +#: model:ir.ui.view,arch_db:connector.view_connector_checkpoint_review +#: model:ir.ui.view,arch_db:connector.view_connector_config_settings +msgid "or" +msgstr "o" + +#. module: connector +#: model:ir.ui.view,arch_db:connector.view_connector_checkpoint_form +msgid "to verify it:" +msgstr "para verificar:" diff --git a/ext/3rd-party-addons/connector/i18n/es_CR.po b/ext/3rd-party-addons/connector/i18n/es_CR.po new file mode 100644 index 00000000..581a5e49 --- /dev/null +++ b/ext/3rd-party-addons/connector/i18n/es_CR.po @@ -0,0 +1,317 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * connector +# +# Translators: +# OCA Transbot , 2017 +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server 10.0\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2017-03-10 03:36+0000\n" +"PO-Revision-Date: 2017-03-10 03:36+0000\n" +"Last-Translator: OCA Transbot , 2017\n" +"Language-Team: Spanish (Costa Rica) (https://www.transifex.com/oca/teams/23907/es_CR/)\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: \n" +"Language: es_CR\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" + +#. module: connector +#: code:addons/connector/checkpoint/checkpoint.py:119 +#, python-format +msgid "A %s needs a review." +msgstr "" + +#. module: connector +#: model:ir.ui.view,arch_db:connector.view_connector_config_settings +msgid "Apply" +msgstr "" + +#. module: connector +#: model:ir.ui.view,arch_db:connector.view_connector_config_settings +msgid "Backends" +msgstr "" + +#. module: connector +#: model:ir.ui.view,arch_db:connector.view_connector_checkpoint_review +#: model:ir.ui.view,arch_db:connector.view_connector_config_settings +msgid "Cancel" +msgstr "Cancelar" + +#. module: connector +#: model:ir.ui.menu,name:connector.menu_checkpoint +msgid "Checkpoint" +msgstr "" + +#. module: connector +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_review_checkpoint_ids +msgid "Checkpoints" +msgstr "" + +#. module: connector +#: model:ir.model,name:connector.model_connector_checkpoint_review +msgid "Checkpoints Review" +msgstr "" + +#. module: connector +#: model:ir.ui.view,arch_db:connector.view_connector_checkpoint_form +msgid "Click on the" +msgstr "" + +#. module: connector +#: model:ir.actions.act_window,name:connector.action_connector_config_settings +#: model:ir.ui.view,arch_db:connector.view_connector_config_settings +msgid "Configure Connector" +msgstr "" + +#. module: connector +#: model:ir.module.category,name:connector.module_category_connector +#: model:ir.ui.menu,name:connector.menu_connector_config_settings +msgid "Connector" +msgstr "" + +#. module: connector +#: model:ir.model,name:connector.model_connector_backend +msgid "Connector Backend" +msgstr "" + +#. module: connector +#: model:ir.actions.act_window,name:connector.action_connector_checkpoint +#: model:ir.model,name:connector.model_connector_checkpoint +#: model:ir.ui.view,arch_db:connector.view_connector_checkpoint_form +#: model:ir.ui.view,arch_db:connector.view_connector_checkpoint_search +#: model:ir.ui.view,arch_db:connector.view_connector_checkpoint_tree +msgid "Connector Checkpoint" +msgstr "" + +#. module: connector +#: model:ir.model,name:connector.model_connector_config_settings +msgid "Connector Configuration" +msgstr "" + +#. module: connector +#: model:res.groups,name:connector.group_connector_manager +msgid "Connector Manager" +msgstr "" + +#. module: connector +#: model:ir.ui.menu,name:connector.menu_connector +#: model:ir.ui.menu,name:connector.menu_connector_root +#: model:ir.ui.view,arch_db:connector.view_partner_connector_form +msgid "Connectors" +msgstr "" + +#. module: connector +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_create_uid +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_review_create_uid +#: model:ir.model.fields,field_description:connector.field_connector_config_settings_create_uid +msgid "Created by" +msgstr "" + +#. module: connector +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_create_date +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_review_create_date +#: model:ir.model.fields,field_description:connector.field_connector_config_settings_create_date +msgid "Created on" +msgstr "" + +#. module: connector +#: model:ir.model.fields,field_description:connector.field_connector_backend_display_name +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_display_name +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_review_display_name +#: model:ir.model.fields,field_description:connector.field_connector_config_settings_display_name +#: model:ir.model.fields,field_description:connector.field_external_binding_display_name +msgid "Display Name" +msgstr "" + +#. module: connector +#: model:ir.model,name:connector.model_external_binding +msgid "External Binding (abstract)" +msgstr "" + +#. module: connector +#: model:ir.ui.view,arch_db:connector.view_connector_checkpoint_search +msgid "Group By..." +msgstr "" + +#. module: connector +#: model:ir.model.fields,field_description:connector.field_connector_backend_id +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_id +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_review_id +#: model:ir.model.fields,field_description:connector.field_connector_config_settings_id +#: model:ir.model.fields,field_description:connector.field_external_binding_id +msgid "ID" +msgstr "" + +#. module: connector +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_backend_id +msgid "Imported from" +msgstr "" + +#. module: connector +#: model:ir.model.fields,field_description:connector.field_connector_backend___last_update +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint___last_update +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_review___last_update +#: model:ir.model.fields,field_description:connector.field_connector_config_settings___last_update +#: model:ir.model.fields,field_description:connector.field_external_binding___last_update +msgid "Last Modified on" +msgstr "" + +#. module: connector +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_review_write_uid +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_write_uid +#: model:ir.model.fields,field_description:connector.field_connector_config_settings_write_uid +msgid "Last Updated by" +msgstr "" + +#. module: connector +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_review_write_date +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_write_date +#: model:ir.model.fields,field_description:connector.field_connector_config_settings_write_date +msgid "Last Updated on" +msgstr "" + +#. module: connector +#: model:ir.model.fields,field_description:connector.field_connector_test_binding_sync_date +#: model:ir.model.fields,field_description:connector.field_external_binding_sync_date +#: model:ir.model.fields,field_description:connector.field_no_inherits_binding_sync_date +msgid "Last synchronization date" +msgstr "" + +#. module: connector +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_model_id +#: model:ir.ui.view,arch_db:connector.view_connector_checkpoint_search +msgid "Model" +msgstr "" + +#. module: connector +#: model:ir.model.fields,field_description:connector.field_connector_backend_name +#: model:ir.model.fields,field_description:connector.field_test_backend_name +msgid "Name" +msgstr "" + +#. module: connector +#: model:ir.model.fields,help:connector.field_connector_checkpoint_name +msgid "Name of the record to review" +msgstr "" + +#. module: connector +#: selection:connector.checkpoint,state:0 +#: model:ir.ui.view,arch_db:connector.view_connector_checkpoint_search +msgid "Need Review" +msgstr "" + +#. module: connector +#: model:ir.actions.act_window,help:connector.action_connector_checkpoint +msgid "No record to check." +msgstr "" + +#. module: connector +#: model:ir.actions.client,name:connector.action_client_connector_menu +msgid "Open Connector Menu" +msgstr "" + +#. module: connector +#: model:ir.model,name:connector.model_queue_job +msgid "Queue Job" +msgstr "" + +#. module: connector +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_record +msgid "Record" +msgstr "" + +#. module: connector +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_record_id +msgid "Record ID" +msgstr "" + +#. module: connector +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_name +msgid "Record Name" +msgstr "" + +#. module: connector +#: code:addons/connector/models/queue_job.py:32 +#, python-format +msgid "Related Record" +msgstr "" + +#. module: connector +#: model:ir.actions.act_window,name:connector.action_connector_checkpoint_review +#: model:ir.ui.view,arch_db:connector.view_connector_checkpoint_review +msgid "Review Checkpoints" +msgstr "" + +#. module: connector +#: selection:connector.checkpoint,state:0 +#: model:ir.ui.view,arch_db:connector.view_connector_checkpoint_form +#: model:ir.ui.view,arch_db:connector.view_connector_checkpoint_search +#: model:ir.ui.view,arch_db:connector.view_connector_checkpoint_tree +msgid "Reviewed" +msgstr "" + +#. module: connector +#: model:ir.ui.view,arch_db:connector.view_connector_checkpoint_review +msgid "Set as reviewed" +msgstr "" + +#. module: connector +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_state +msgid "Status" +msgstr "" + +#. module: connector +#: model:ir.actions.act_window,help:connector.action_connector_checkpoint +msgid "" +"The connectors list the new records to verify\n" +" based on their type. Only some need a manual\n" +" review." +msgstr "" + +#. module: connector +#: model:ir.model.fields,help:connector.field_connector_checkpoint_backend_id +msgid "The record has been imported from this backend" +msgstr "" + +#. module: connector +#: model:ir.model.fields,help:connector.field_connector_checkpoint_record +msgid "The record to review." +msgstr "" + +#. module: connector +#: model:ir.ui.view,arch_db:connector.view_connector_checkpoint_review +msgid "The selected checkpoints will be set as reviewed." +msgstr "" + +#. module: connector +#: model:ir.model.fields,field_description:connector.field_connector_backend_version +msgid "Version" +msgstr "" + +#. module: connector +#: model:ir.actions.act_window,help:connector.action_connector_checkpoint +msgid "" +"When a connector imports new records which have\n" +" configuration or reviews to do manually, they\n" +" will appear in this list. Once a record has been\n" +" checked, click on the 'Reviewed' button." +msgstr "" + +#. module: connector +#: model:ir.model,name:connector.model_base +msgid "base" +msgstr "" + +#. module: connector +#: model:ir.ui.view,arch_db:connector.view_connector_checkpoint_review +#: model:ir.ui.view,arch_db:connector.view_connector_config_settings +msgid "or" +msgstr "" + +#. module: connector +#: model:ir.ui.view,arch_db:connector.view_connector_checkpoint_form +msgid "to verify it:" +msgstr "" diff --git a/ext/3rd-party-addons/connector/i18n/es_EC.po b/ext/3rd-party-addons/connector/i18n/es_EC.po new file mode 100644 index 00000000..236f57f9 --- /dev/null +++ b/ext/3rd-party-addons/connector/i18n/es_EC.po @@ -0,0 +1,317 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * connector +# +# Translators: +# OCA Transbot , 2017 +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server 10.0\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2017-03-10 03:36+0000\n" +"PO-Revision-Date: 2017-03-10 03:36+0000\n" +"Last-Translator: OCA Transbot , 2017\n" +"Language-Team: Spanish (Ecuador) (https://www.transifex.com/oca/teams/23907/es_EC/)\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: \n" +"Language: es_EC\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" + +#. module: connector +#: code:addons/connector/checkpoint/checkpoint.py:119 +#, python-format +msgid "A %s needs a review." +msgstr "" + +#. module: connector +#: model:ir.ui.view,arch_db:connector.view_connector_config_settings +msgid "Apply" +msgstr "" + +#. module: connector +#: model:ir.ui.view,arch_db:connector.view_connector_config_settings +msgid "Backends" +msgstr "" + +#. module: connector +#: model:ir.ui.view,arch_db:connector.view_connector_checkpoint_review +#: model:ir.ui.view,arch_db:connector.view_connector_config_settings +msgid "Cancel" +msgstr "Cancelar" + +#. module: connector +#: model:ir.ui.menu,name:connector.menu_checkpoint +msgid "Checkpoint" +msgstr "" + +#. module: connector +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_review_checkpoint_ids +msgid "Checkpoints" +msgstr "" + +#. module: connector +#: model:ir.model,name:connector.model_connector_checkpoint_review +msgid "Checkpoints Review" +msgstr "" + +#. module: connector +#: model:ir.ui.view,arch_db:connector.view_connector_checkpoint_form +msgid "Click on the" +msgstr "" + +#. module: connector +#: model:ir.actions.act_window,name:connector.action_connector_config_settings +#: model:ir.ui.view,arch_db:connector.view_connector_config_settings +msgid "Configure Connector" +msgstr "" + +#. module: connector +#: model:ir.module.category,name:connector.module_category_connector +#: model:ir.ui.menu,name:connector.menu_connector_config_settings +msgid "Connector" +msgstr "" + +#. module: connector +#: model:ir.model,name:connector.model_connector_backend +msgid "Connector Backend" +msgstr "" + +#. module: connector +#: model:ir.actions.act_window,name:connector.action_connector_checkpoint +#: model:ir.model,name:connector.model_connector_checkpoint +#: model:ir.ui.view,arch_db:connector.view_connector_checkpoint_form +#: model:ir.ui.view,arch_db:connector.view_connector_checkpoint_search +#: model:ir.ui.view,arch_db:connector.view_connector_checkpoint_tree +msgid "Connector Checkpoint" +msgstr "" + +#. module: connector +#: model:ir.model,name:connector.model_connector_config_settings +msgid "Connector Configuration" +msgstr "" + +#. module: connector +#: model:res.groups,name:connector.group_connector_manager +msgid "Connector Manager" +msgstr "" + +#. module: connector +#: model:ir.ui.menu,name:connector.menu_connector +#: model:ir.ui.menu,name:connector.menu_connector_root +#: model:ir.ui.view,arch_db:connector.view_partner_connector_form +msgid "Connectors" +msgstr "" + +#. module: connector +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_create_uid +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_review_create_uid +#: model:ir.model.fields,field_description:connector.field_connector_config_settings_create_uid +msgid "Created by" +msgstr "" + +#. module: connector +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_create_date +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_review_create_date +#: model:ir.model.fields,field_description:connector.field_connector_config_settings_create_date +msgid "Created on" +msgstr "" + +#. module: connector +#: model:ir.model.fields,field_description:connector.field_connector_backend_display_name +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_display_name +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_review_display_name +#: model:ir.model.fields,field_description:connector.field_connector_config_settings_display_name +#: model:ir.model.fields,field_description:connector.field_external_binding_display_name +msgid "Display Name" +msgstr "" + +#. module: connector +#: model:ir.model,name:connector.model_external_binding +msgid "External Binding (abstract)" +msgstr "" + +#. module: connector +#: model:ir.ui.view,arch_db:connector.view_connector_checkpoint_search +msgid "Group By..." +msgstr "" + +#. module: connector +#: model:ir.model.fields,field_description:connector.field_connector_backend_id +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_id +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_review_id +#: model:ir.model.fields,field_description:connector.field_connector_config_settings_id +#: model:ir.model.fields,field_description:connector.field_external_binding_id +msgid "ID" +msgstr "" + +#. module: connector +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_backend_id +msgid "Imported from" +msgstr "" + +#. module: connector +#: model:ir.model.fields,field_description:connector.field_connector_backend___last_update +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint___last_update +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_review___last_update +#: model:ir.model.fields,field_description:connector.field_connector_config_settings___last_update +#: model:ir.model.fields,field_description:connector.field_external_binding___last_update +msgid "Last Modified on" +msgstr "" + +#. module: connector +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_review_write_uid +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_write_uid +#: model:ir.model.fields,field_description:connector.field_connector_config_settings_write_uid +msgid "Last Updated by" +msgstr "" + +#. module: connector +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_review_write_date +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_write_date +#: model:ir.model.fields,field_description:connector.field_connector_config_settings_write_date +msgid "Last Updated on" +msgstr "" + +#. module: connector +#: model:ir.model.fields,field_description:connector.field_connector_test_binding_sync_date +#: model:ir.model.fields,field_description:connector.field_external_binding_sync_date +#: model:ir.model.fields,field_description:connector.field_no_inherits_binding_sync_date +msgid "Last synchronization date" +msgstr "" + +#. module: connector +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_model_id +#: model:ir.ui.view,arch_db:connector.view_connector_checkpoint_search +msgid "Model" +msgstr "" + +#. module: connector +#: model:ir.model.fields,field_description:connector.field_connector_backend_name +#: model:ir.model.fields,field_description:connector.field_test_backend_name +msgid "Name" +msgstr "" + +#. module: connector +#: model:ir.model.fields,help:connector.field_connector_checkpoint_name +msgid "Name of the record to review" +msgstr "" + +#. module: connector +#: selection:connector.checkpoint,state:0 +#: model:ir.ui.view,arch_db:connector.view_connector_checkpoint_search +msgid "Need Review" +msgstr "" + +#. module: connector +#: model:ir.actions.act_window,help:connector.action_connector_checkpoint +msgid "No record to check." +msgstr "" + +#. module: connector +#: model:ir.actions.client,name:connector.action_client_connector_menu +msgid "Open Connector Menu" +msgstr "" + +#. module: connector +#: model:ir.model,name:connector.model_queue_job +msgid "Queue Job" +msgstr "" + +#. module: connector +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_record +msgid "Record" +msgstr "" + +#. module: connector +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_record_id +msgid "Record ID" +msgstr "" + +#. module: connector +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_name +msgid "Record Name" +msgstr "" + +#. module: connector +#: code:addons/connector/models/queue_job.py:32 +#, python-format +msgid "Related Record" +msgstr "" + +#. module: connector +#: model:ir.actions.act_window,name:connector.action_connector_checkpoint_review +#: model:ir.ui.view,arch_db:connector.view_connector_checkpoint_review +msgid "Review Checkpoints" +msgstr "" + +#. module: connector +#: selection:connector.checkpoint,state:0 +#: model:ir.ui.view,arch_db:connector.view_connector_checkpoint_form +#: model:ir.ui.view,arch_db:connector.view_connector_checkpoint_search +#: model:ir.ui.view,arch_db:connector.view_connector_checkpoint_tree +msgid "Reviewed" +msgstr "" + +#. module: connector +#: model:ir.ui.view,arch_db:connector.view_connector_checkpoint_review +msgid "Set as reviewed" +msgstr "" + +#. module: connector +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_state +msgid "Status" +msgstr "" + +#. module: connector +#: model:ir.actions.act_window,help:connector.action_connector_checkpoint +msgid "" +"The connectors list the new records to verify\n" +" based on their type. Only some need a manual\n" +" review." +msgstr "" + +#. module: connector +#: model:ir.model.fields,help:connector.field_connector_checkpoint_backend_id +msgid "The record has been imported from this backend" +msgstr "" + +#. module: connector +#: model:ir.model.fields,help:connector.field_connector_checkpoint_record +msgid "The record to review." +msgstr "" + +#. module: connector +#: model:ir.ui.view,arch_db:connector.view_connector_checkpoint_review +msgid "The selected checkpoints will be set as reviewed." +msgstr "" + +#. module: connector +#: model:ir.model.fields,field_description:connector.field_connector_backend_version +msgid "Version" +msgstr "" + +#. module: connector +#: model:ir.actions.act_window,help:connector.action_connector_checkpoint +msgid "" +"When a connector imports new records which have\n" +" configuration or reviews to do manually, they\n" +" will appear in this list. Once a record has been\n" +" checked, click on the 'Reviewed' button." +msgstr "" + +#. module: connector +#: model:ir.model,name:connector.model_base +msgid "base" +msgstr "" + +#. module: connector +#: model:ir.ui.view,arch_db:connector.view_connector_checkpoint_review +#: model:ir.ui.view,arch_db:connector.view_connector_config_settings +msgid "or" +msgstr "" + +#. module: connector +#: model:ir.ui.view,arch_db:connector.view_connector_checkpoint_form +msgid "to verify it:" +msgstr "" diff --git a/ext/3rd-party-addons/connector/i18n/es_ES.po b/ext/3rd-party-addons/connector/i18n/es_ES.po new file mode 100644 index 00000000..8331e2e4 --- /dev/null +++ b/ext/3rd-party-addons/connector/i18n/es_ES.po @@ -0,0 +1,317 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * connector +# +# Translators: +# OCA Transbot , 2017 +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server 10.0\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2017-03-10 03:36+0000\n" +"PO-Revision-Date: 2017-03-10 03:36+0000\n" +"Last-Translator: OCA Transbot , 2017\n" +"Language-Team: Spanish (Spain) (https://www.transifex.com/oca/teams/23907/es_ES/)\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: \n" +"Language: es_ES\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" + +#. module: connector +#: code:addons/connector/checkpoint/checkpoint.py:119 +#, python-format +msgid "A %s needs a review." +msgstr "" + +#. module: connector +#: model:ir.ui.view,arch_db:connector.view_connector_config_settings +msgid "Apply" +msgstr "" + +#. module: connector +#: model:ir.ui.view,arch_db:connector.view_connector_config_settings +msgid "Backends" +msgstr "" + +#. module: connector +#: model:ir.ui.view,arch_db:connector.view_connector_checkpoint_review +#: model:ir.ui.view,arch_db:connector.view_connector_config_settings +msgid "Cancel" +msgstr "Cancelar" + +#. module: connector +#: model:ir.ui.menu,name:connector.menu_checkpoint +msgid "Checkpoint" +msgstr "" + +#. module: connector +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_review_checkpoint_ids +msgid "Checkpoints" +msgstr "" + +#. module: connector +#: model:ir.model,name:connector.model_connector_checkpoint_review +msgid "Checkpoints Review" +msgstr "" + +#. module: connector +#: model:ir.ui.view,arch_db:connector.view_connector_checkpoint_form +msgid "Click on the" +msgstr "" + +#. module: connector +#: model:ir.actions.act_window,name:connector.action_connector_config_settings +#: model:ir.ui.view,arch_db:connector.view_connector_config_settings +msgid "Configure Connector" +msgstr "" + +#. module: connector +#: model:ir.module.category,name:connector.module_category_connector +#: model:ir.ui.menu,name:connector.menu_connector_config_settings +msgid "Connector" +msgstr "" + +#. module: connector +#: model:ir.model,name:connector.model_connector_backend +msgid "Connector Backend" +msgstr "" + +#. module: connector +#: model:ir.actions.act_window,name:connector.action_connector_checkpoint +#: model:ir.model,name:connector.model_connector_checkpoint +#: model:ir.ui.view,arch_db:connector.view_connector_checkpoint_form +#: model:ir.ui.view,arch_db:connector.view_connector_checkpoint_search +#: model:ir.ui.view,arch_db:connector.view_connector_checkpoint_tree +msgid "Connector Checkpoint" +msgstr "" + +#. module: connector +#: model:ir.model,name:connector.model_connector_config_settings +msgid "Connector Configuration" +msgstr "" + +#. module: connector +#: model:res.groups,name:connector.group_connector_manager +msgid "Connector Manager" +msgstr "" + +#. module: connector +#: model:ir.ui.menu,name:connector.menu_connector +#: model:ir.ui.menu,name:connector.menu_connector_root +#: model:ir.ui.view,arch_db:connector.view_partner_connector_form +msgid "Connectors" +msgstr "" + +#. module: connector +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_create_uid +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_review_create_uid +#: model:ir.model.fields,field_description:connector.field_connector_config_settings_create_uid +msgid "Created by" +msgstr "Creado por" + +#. module: connector +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_create_date +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_review_create_date +#: model:ir.model.fields,field_description:connector.field_connector_config_settings_create_date +msgid "Created on" +msgstr "Creado en" + +#. module: connector +#: model:ir.model.fields,field_description:connector.field_connector_backend_display_name +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_display_name +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_review_display_name +#: model:ir.model.fields,field_description:connector.field_connector_config_settings_display_name +#: model:ir.model.fields,field_description:connector.field_external_binding_display_name +msgid "Display Name" +msgstr "" + +#. module: connector +#: model:ir.model,name:connector.model_external_binding +msgid "External Binding (abstract)" +msgstr "" + +#. module: connector +#: model:ir.ui.view,arch_db:connector.view_connector_checkpoint_search +msgid "Group By..." +msgstr "" + +#. module: connector +#: model:ir.model.fields,field_description:connector.field_connector_backend_id +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_id +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_review_id +#: model:ir.model.fields,field_description:connector.field_connector_config_settings_id +#: model:ir.model.fields,field_description:connector.field_external_binding_id +msgid "ID" +msgstr "ID" + +#. module: connector +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_backend_id +msgid "Imported from" +msgstr "" + +#. module: connector +#: model:ir.model.fields,field_description:connector.field_connector_backend___last_update +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint___last_update +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_review___last_update +#: model:ir.model.fields,field_description:connector.field_connector_config_settings___last_update +#: model:ir.model.fields,field_description:connector.field_external_binding___last_update +msgid "Last Modified on" +msgstr "" + +#. module: connector +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_review_write_uid +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_write_uid +#: model:ir.model.fields,field_description:connector.field_connector_config_settings_write_uid +msgid "Last Updated by" +msgstr "Última actualización por" + +#. module: connector +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_review_write_date +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_write_date +#: model:ir.model.fields,field_description:connector.field_connector_config_settings_write_date +msgid "Last Updated on" +msgstr "Última actualización en" + +#. module: connector +#: model:ir.model.fields,field_description:connector.field_connector_test_binding_sync_date +#: model:ir.model.fields,field_description:connector.field_external_binding_sync_date +#: model:ir.model.fields,field_description:connector.field_no_inherits_binding_sync_date +msgid "Last synchronization date" +msgstr "" + +#. module: connector +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_model_id +#: model:ir.ui.view,arch_db:connector.view_connector_checkpoint_search +msgid "Model" +msgstr "" + +#. module: connector +#: model:ir.model.fields,field_description:connector.field_connector_backend_name +#: model:ir.model.fields,field_description:connector.field_test_backend_name +msgid "Name" +msgstr "" + +#. module: connector +#: model:ir.model.fields,help:connector.field_connector_checkpoint_name +msgid "Name of the record to review" +msgstr "" + +#. module: connector +#: selection:connector.checkpoint,state:0 +#: model:ir.ui.view,arch_db:connector.view_connector_checkpoint_search +msgid "Need Review" +msgstr "" + +#. module: connector +#: model:ir.actions.act_window,help:connector.action_connector_checkpoint +msgid "No record to check." +msgstr "" + +#. module: connector +#: model:ir.actions.client,name:connector.action_client_connector_menu +msgid "Open Connector Menu" +msgstr "" + +#. module: connector +#: model:ir.model,name:connector.model_queue_job +msgid "Queue Job" +msgstr "" + +#. module: connector +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_record +msgid "Record" +msgstr "" + +#. module: connector +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_record_id +msgid "Record ID" +msgstr "" + +#. module: connector +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_name +msgid "Record Name" +msgstr "" + +#. module: connector +#: code:addons/connector/models/queue_job.py:32 +#, python-format +msgid "Related Record" +msgstr "" + +#. module: connector +#: model:ir.actions.act_window,name:connector.action_connector_checkpoint_review +#: model:ir.ui.view,arch_db:connector.view_connector_checkpoint_review +msgid "Review Checkpoints" +msgstr "" + +#. module: connector +#: selection:connector.checkpoint,state:0 +#: model:ir.ui.view,arch_db:connector.view_connector_checkpoint_form +#: model:ir.ui.view,arch_db:connector.view_connector_checkpoint_search +#: model:ir.ui.view,arch_db:connector.view_connector_checkpoint_tree +msgid "Reviewed" +msgstr "" + +#. module: connector +#: model:ir.ui.view,arch_db:connector.view_connector_checkpoint_review +msgid "Set as reviewed" +msgstr "" + +#. module: connector +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_state +msgid "Status" +msgstr "" + +#. module: connector +#: model:ir.actions.act_window,help:connector.action_connector_checkpoint +msgid "" +"The connectors list the new records to verify\n" +" based on their type. Only some need a manual\n" +" review." +msgstr "" + +#. module: connector +#: model:ir.model.fields,help:connector.field_connector_checkpoint_backend_id +msgid "The record has been imported from this backend" +msgstr "" + +#. module: connector +#: model:ir.model.fields,help:connector.field_connector_checkpoint_record +msgid "The record to review." +msgstr "" + +#. module: connector +#: model:ir.ui.view,arch_db:connector.view_connector_checkpoint_review +msgid "The selected checkpoints will be set as reviewed." +msgstr "" + +#. module: connector +#: model:ir.model.fields,field_description:connector.field_connector_backend_version +msgid "Version" +msgstr "" + +#. module: connector +#: model:ir.actions.act_window,help:connector.action_connector_checkpoint +msgid "" +"When a connector imports new records which have\n" +" configuration or reviews to do manually, they\n" +" will appear in this list. Once a record has been\n" +" checked, click on the 'Reviewed' button." +msgstr "" + +#. module: connector +#: model:ir.model,name:connector.model_base +msgid "base" +msgstr "" + +#. module: connector +#: model:ir.ui.view,arch_db:connector.view_connector_checkpoint_review +#: model:ir.ui.view,arch_db:connector.view_connector_config_settings +msgid "or" +msgstr "" + +#. module: connector +#: model:ir.ui.view,arch_db:connector.view_connector_checkpoint_form +msgid "to verify it:" +msgstr "" diff --git a/ext/3rd-party-addons/connector/i18n/es_MX.po b/ext/3rd-party-addons/connector/i18n/es_MX.po new file mode 100644 index 00000000..a6d79410 --- /dev/null +++ b/ext/3rd-party-addons/connector/i18n/es_MX.po @@ -0,0 +1,317 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * connector +# +# Translators: +# OCA Transbot , 2017 +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server 10.0\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2017-03-10 03:36+0000\n" +"PO-Revision-Date: 2017-03-10 03:36+0000\n" +"Last-Translator: OCA Transbot , 2017\n" +"Language-Team: Spanish (Mexico) (https://www.transifex.com/oca/teams/23907/es_MX/)\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: \n" +"Language: es_MX\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" + +#. module: connector +#: code:addons/connector/checkpoint/checkpoint.py:119 +#, python-format +msgid "A %s needs a review." +msgstr "El %s necesita revisión." + +#. module: connector +#: model:ir.ui.view,arch_db:connector.view_connector_config_settings +msgid "Apply" +msgstr "Aplicar" + +#. module: connector +#: model:ir.ui.view,arch_db:connector.view_connector_config_settings +msgid "Backends" +msgstr "" + +#. module: connector +#: model:ir.ui.view,arch_db:connector.view_connector_checkpoint_review +#: model:ir.ui.view,arch_db:connector.view_connector_config_settings +msgid "Cancel" +msgstr "Cancelar" + +#. module: connector +#: model:ir.ui.menu,name:connector.menu_checkpoint +msgid "Checkpoint" +msgstr "" + +#. module: connector +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_review_checkpoint_ids +msgid "Checkpoints" +msgstr "" + +#. module: connector +#: model:ir.model,name:connector.model_connector_checkpoint_review +msgid "Checkpoints Review" +msgstr "" + +#. module: connector +#: model:ir.ui.view,arch_db:connector.view_connector_checkpoint_form +msgid "Click on the" +msgstr "" + +#. module: connector +#: model:ir.actions.act_window,name:connector.action_connector_config_settings +#: model:ir.ui.view,arch_db:connector.view_connector_config_settings +msgid "Configure Connector" +msgstr "Configurar Conector" + +#. module: connector +#: model:ir.module.category,name:connector.module_category_connector +#: model:ir.ui.menu,name:connector.menu_connector_config_settings +msgid "Connector" +msgstr "Conector" + +#. module: connector +#: model:ir.model,name:connector.model_connector_backend +msgid "Connector Backend" +msgstr "" + +#. module: connector +#: model:ir.actions.act_window,name:connector.action_connector_checkpoint +#: model:ir.model,name:connector.model_connector_checkpoint +#: model:ir.ui.view,arch_db:connector.view_connector_checkpoint_form +#: model:ir.ui.view,arch_db:connector.view_connector_checkpoint_search +#: model:ir.ui.view,arch_db:connector.view_connector_checkpoint_tree +msgid "Connector Checkpoint" +msgstr "" + +#. module: connector +#: model:ir.model,name:connector.model_connector_config_settings +msgid "Connector Configuration" +msgstr "" + +#. module: connector +#: model:res.groups,name:connector.group_connector_manager +msgid "Connector Manager" +msgstr "" + +#. module: connector +#: model:ir.ui.menu,name:connector.menu_connector +#: model:ir.ui.menu,name:connector.menu_connector_root +#: model:ir.ui.view,arch_db:connector.view_partner_connector_form +msgid "Connectors" +msgstr "" + +#. module: connector +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_create_uid +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_review_create_uid +#: model:ir.model.fields,field_description:connector.field_connector_config_settings_create_uid +msgid "Created by" +msgstr "" + +#. module: connector +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_create_date +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_review_create_date +#: model:ir.model.fields,field_description:connector.field_connector_config_settings_create_date +msgid "Created on" +msgstr "" + +#. module: connector +#: model:ir.model.fields,field_description:connector.field_connector_backend_display_name +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_display_name +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_review_display_name +#: model:ir.model.fields,field_description:connector.field_connector_config_settings_display_name +#: model:ir.model.fields,field_description:connector.field_external_binding_display_name +msgid "Display Name" +msgstr "" + +#. module: connector +#: model:ir.model,name:connector.model_external_binding +msgid "External Binding (abstract)" +msgstr "" + +#. module: connector +#: model:ir.ui.view,arch_db:connector.view_connector_checkpoint_search +msgid "Group By..." +msgstr "" + +#. module: connector +#: model:ir.model.fields,field_description:connector.field_connector_backend_id +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_id +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_review_id +#: model:ir.model.fields,field_description:connector.field_connector_config_settings_id +#: model:ir.model.fields,field_description:connector.field_external_binding_id +msgid "ID" +msgstr "" + +#. module: connector +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_backend_id +msgid "Imported from" +msgstr "Importado de" + +#. module: connector +#: model:ir.model.fields,field_description:connector.field_connector_backend___last_update +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint___last_update +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_review___last_update +#: model:ir.model.fields,field_description:connector.field_connector_config_settings___last_update +#: model:ir.model.fields,field_description:connector.field_external_binding___last_update +msgid "Last Modified on" +msgstr "" + +#. module: connector +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_review_write_uid +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_write_uid +#: model:ir.model.fields,field_description:connector.field_connector_config_settings_write_uid +msgid "Last Updated by" +msgstr "" + +#. module: connector +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_review_write_date +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_write_date +#: model:ir.model.fields,field_description:connector.field_connector_config_settings_write_date +msgid "Last Updated on" +msgstr "" + +#. module: connector +#: model:ir.model.fields,field_description:connector.field_connector_test_binding_sync_date +#: model:ir.model.fields,field_description:connector.field_external_binding_sync_date +#: model:ir.model.fields,field_description:connector.field_no_inherits_binding_sync_date +msgid "Last synchronization date" +msgstr "" + +#. module: connector +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_model_id +#: model:ir.ui.view,arch_db:connector.view_connector_checkpoint_search +msgid "Model" +msgstr "Modelo" + +#. module: connector +#: model:ir.model.fields,field_description:connector.field_connector_backend_name +#: model:ir.model.fields,field_description:connector.field_test_backend_name +msgid "Name" +msgstr "Nombre" + +#. module: connector +#: model:ir.model.fields,help:connector.field_connector_checkpoint_name +msgid "Name of the record to review" +msgstr "" + +#. module: connector +#: selection:connector.checkpoint,state:0 +#: model:ir.ui.view,arch_db:connector.view_connector_checkpoint_search +msgid "Need Review" +msgstr "Necesita Revisión" + +#. module: connector +#: model:ir.actions.act_window,help:connector.action_connector_checkpoint +msgid "No record to check." +msgstr "" + +#. module: connector +#: model:ir.actions.client,name:connector.action_client_connector_menu +msgid "Open Connector Menu" +msgstr "" + +#. module: connector +#: model:ir.model,name:connector.model_queue_job +msgid "Queue Job" +msgstr "" + +#. module: connector +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_record +msgid "Record" +msgstr "" + +#. module: connector +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_record_id +msgid "Record ID" +msgstr "" + +#. module: connector +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_name +msgid "Record Name" +msgstr "" + +#. module: connector +#: code:addons/connector/models/queue_job.py:32 +#, python-format +msgid "Related Record" +msgstr "" + +#. module: connector +#: model:ir.actions.act_window,name:connector.action_connector_checkpoint_review +#: model:ir.ui.view,arch_db:connector.view_connector_checkpoint_review +msgid "Review Checkpoints" +msgstr "" + +#. module: connector +#: selection:connector.checkpoint,state:0 +#: model:ir.ui.view,arch_db:connector.view_connector_checkpoint_form +#: model:ir.ui.view,arch_db:connector.view_connector_checkpoint_search +#: model:ir.ui.view,arch_db:connector.view_connector_checkpoint_tree +msgid "Reviewed" +msgstr "Revisiado" + +#. module: connector +#: model:ir.ui.view,arch_db:connector.view_connector_checkpoint_review +msgid "Set as reviewed" +msgstr "" + +#. module: connector +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_state +msgid "Status" +msgstr "" + +#. module: connector +#: model:ir.actions.act_window,help:connector.action_connector_checkpoint +msgid "" +"The connectors list the new records to verify\n" +" based on their type. Only some need a manual\n" +" review." +msgstr "" + +#. module: connector +#: model:ir.model.fields,help:connector.field_connector_checkpoint_backend_id +msgid "The record has been imported from this backend" +msgstr "" + +#. module: connector +#: model:ir.model.fields,help:connector.field_connector_checkpoint_record +msgid "The record to review." +msgstr "" + +#. module: connector +#: model:ir.ui.view,arch_db:connector.view_connector_checkpoint_review +msgid "The selected checkpoints will be set as reviewed." +msgstr "" + +#. module: connector +#: model:ir.model.fields,field_description:connector.field_connector_backend_version +msgid "Version" +msgstr "" + +#. module: connector +#: model:ir.actions.act_window,help:connector.action_connector_checkpoint +msgid "" +"When a connector imports new records which have\n" +" configuration or reviews to do manually, they\n" +" will appear in this list. Once a record has been\n" +" checked, click on the 'Reviewed' button." +msgstr "" + +#. module: connector +#: model:ir.model,name:connector.model_base +msgid "base" +msgstr "" + +#. module: connector +#: model:ir.ui.view,arch_db:connector.view_connector_checkpoint_review +#: model:ir.ui.view,arch_db:connector.view_connector_config_settings +msgid "or" +msgstr "" + +#. module: connector +#: model:ir.ui.view,arch_db:connector.view_connector_checkpoint_form +msgid "to verify it:" +msgstr "" diff --git a/ext/3rd-party-addons/connector/i18n/es_VE.po b/ext/3rd-party-addons/connector/i18n/es_VE.po new file mode 100644 index 00000000..e419d970 --- /dev/null +++ b/ext/3rd-party-addons/connector/i18n/es_VE.po @@ -0,0 +1,317 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * connector +# +# Translators: +# OCA Transbot , 2017 +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server 10.0\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2017-03-10 03:36+0000\n" +"PO-Revision-Date: 2017-03-10 03:36+0000\n" +"Last-Translator: OCA Transbot , 2017\n" +"Language-Team: Spanish (Venezuela) (https://www.transifex.com/oca/teams/23907/es_VE/)\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: \n" +"Language: es_VE\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" + +#. module: connector +#: code:addons/connector/checkpoint/checkpoint.py:119 +#, python-format +msgid "A %s needs a review." +msgstr "" + +#. module: connector +#: model:ir.ui.view,arch_db:connector.view_connector_config_settings +msgid "Apply" +msgstr "" + +#. module: connector +#: model:ir.ui.view,arch_db:connector.view_connector_config_settings +msgid "Backends" +msgstr "" + +#. module: connector +#: model:ir.ui.view,arch_db:connector.view_connector_checkpoint_review +#: model:ir.ui.view,arch_db:connector.view_connector_config_settings +msgid "Cancel" +msgstr "Cancelar" + +#. module: connector +#: model:ir.ui.menu,name:connector.menu_checkpoint +msgid "Checkpoint" +msgstr "" + +#. module: connector +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_review_checkpoint_ids +msgid "Checkpoints" +msgstr "" + +#. module: connector +#: model:ir.model,name:connector.model_connector_checkpoint_review +msgid "Checkpoints Review" +msgstr "" + +#. module: connector +#: model:ir.ui.view,arch_db:connector.view_connector_checkpoint_form +msgid "Click on the" +msgstr "" + +#. module: connector +#: model:ir.actions.act_window,name:connector.action_connector_config_settings +#: model:ir.ui.view,arch_db:connector.view_connector_config_settings +msgid "Configure Connector" +msgstr "" + +#. module: connector +#: model:ir.module.category,name:connector.module_category_connector +#: model:ir.ui.menu,name:connector.menu_connector_config_settings +msgid "Connector" +msgstr "" + +#. module: connector +#: model:ir.model,name:connector.model_connector_backend +msgid "Connector Backend" +msgstr "" + +#. module: connector +#: model:ir.actions.act_window,name:connector.action_connector_checkpoint +#: model:ir.model,name:connector.model_connector_checkpoint +#: model:ir.ui.view,arch_db:connector.view_connector_checkpoint_form +#: model:ir.ui.view,arch_db:connector.view_connector_checkpoint_search +#: model:ir.ui.view,arch_db:connector.view_connector_checkpoint_tree +msgid "Connector Checkpoint" +msgstr "" + +#. module: connector +#: model:ir.model,name:connector.model_connector_config_settings +msgid "Connector Configuration" +msgstr "" + +#. module: connector +#: model:res.groups,name:connector.group_connector_manager +msgid "Connector Manager" +msgstr "" + +#. module: connector +#: model:ir.ui.menu,name:connector.menu_connector +#: model:ir.ui.menu,name:connector.menu_connector_root +#: model:ir.ui.view,arch_db:connector.view_partner_connector_form +msgid "Connectors" +msgstr "" + +#. module: connector +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_create_uid +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_review_create_uid +#: model:ir.model.fields,field_description:connector.field_connector_config_settings_create_uid +msgid "Created by" +msgstr "" + +#. module: connector +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_create_date +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_review_create_date +#: model:ir.model.fields,field_description:connector.field_connector_config_settings_create_date +msgid "Created on" +msgstr "" + +#. module: connector +#: model:ir.model.fields,field_description:connector.field_connector_backend_display_name +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_display_name +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_review_display_name +#: model:ir.model.fields,field_description:connector.field_connector_config_settings_display_name +#: model:ir.model.fields,field_description:connector.field_external_binding_display_name +msgid "Display Name" +msgstr "" + +#. module: connector +#: model:ir.model,name:connector.model_external_binding +msgid "External Binding (abstract)" +msgstr "" + +#. module: connector +#: model:ir.ui.view,arch_db:connector.view_connector_checkpoint_search +msgid "Group By..." +msgstr "" + +#. module: connector +#: model:ir.model.fields,field_description:connector.field_connector_backend_id +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_id +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_review_id +#: model:ir.model.fields,field_description:connector.field_connector_config_settings_id +#: model:ir.model.fields,field_description:connector.field_external_binding_id +msgid "ID" +msgstr "" + +#. module: connector +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_backend_id +msgid "Imported from" +msgstr "" + +#. module: connector +#: model:ir.model.fields,field_description:connector.field_connector_backend___last_update +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint___last_update +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_review___last_update +#: model:ir.model.fields,field_description:connector.field_connector_config_settings___last_update +#: model:ir.model.fields,field_description:connector.field_external_binding___last_update +msgid "Last Modified on" +msgstr "" + +#. module: connector +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_review_write_uid +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_write_uid +#: model:ir.model.fields,field_description:connector.field_connector_config_settings_write_uid +msgid "Last Updated by" +msgstr "" + +#. module: connector +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_review_write_date +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_write_date +#: model:ir.model.fields,field_description:connector.field_connector_config_settings_write_date +msgid "Last Updated on" +msgstr "" + +#. module: connector +#: model:ir.model.fields,field_description:connector.field_connector_test_binding_sync_date +#: model:ir.model.fields,field_description:connector.field_external_binding_sync_date +#: model:ir.model.fields,field_description:connector.field_no_inherits_binding_sync_date +msgid "Last synchronization date" +msgstr "" + +#. module: connector +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_model_id +#: model:ir.ui.view,arch_db:connector.view_connector_checkpoint_search +msgid "Model" +msgstr "" + +#. module: connector +#: model:ir.model.fields,field_description:connector.field_connector_backend_name +#: model:ir.model.fields,field_description:connector.field_test_backend_name +msgid "Name" +msgstr "" + +#. module: connector +#: model:ir.model.fields,help:connector.field_connector_checkpoint_name +msgid "Name of the record to review" +msgstr "" + +#. module: connector +#: selection:connector.checkpoint,state:0 +#: model:ir.ui.view,arch_db:connector.view_connector_checkpoint_search +msgid "Need Review" +msgstr "" + +#. module: connector +#: model:ir.actions.act_window,help:connector.action_connector_checkpoint +msgid "No record to check." +msgstr "" + +#. module: connector +#: model:ir.actions.client,name:connector.action_client_connector_menu +msgid "Open Connector Menu" +msgstr "" + +#. module: connector +#: model:ir.model,name:connector.model_queue_job +msgid "Queue Job" +msgstr "" + +#. module: connector +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_record +msgid "Record" +msgstr "" + +#. module: connector +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_record_id +msgid "Record ID" +msgstr "" + +#. module: connector +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_name +msgid "Record Name" +msgstr "" + +#. module: connector +#: code:addons/connector/models/queue_job.py:32 +#, python-format +msgid "Related Record" +msgstr "" + +#. module: connector +#: model:ir.actions.act_window,name:connector.action_connector_checkpoint_review +#: model:ir.ui.view,arch_db:connector.view_connector_checkpoint_review +msgid "Review Checkpoints" +msgstr "" + +#. module: connector +#: selection:connector.checkpoint,state:0 +#: model:ir.ui.view,arch_db:connector.view_connector_checkpoint_form +#: model:ir.ui.view,arch_db:connector.view_connector_checkpoint_search +#: model:ir.ui.view,arch_db:connector.view_connector_checkpoint_tree +msgid "Reviewed" +msgstr "" + +#. module: connector +#: model:ir.ui.view,arch_db:connector.view_connector_checkpoint_review +msgid "Set as reviewed" +msgstr "" + +#. module: connector +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_state +msgid "Status" +msgstr "" + +#. module: connector +#: model:ir.actions.act_window,help:connector.action_connector_checkpoint +msgid "" +"The connectors list the new records to verify\n" +" based on their type. Only some need a manual\n" +" review." +msgstr "" + +#. module: connector +#: model:ir.model.fields,help:connector.field_connector_checkpoint_backend_id +msgid "The record has been imported from this backend" +msgstr "" + +#. module: connector +#: model:ir.model.fields,help:connector.field_connector_checkpoint_record +msgid "The record to review." +msgstr "" + +#. module: connector +#: model:ir.ui.view,arch_db:connector.view_connector_checkpoint_review +msgid "The selected checkpoints will be set as reviewed." +msgstr "" + +#. module: connector +#: model:ir.model.fields,field_description:connector.field_connector_backend_version +msgid "Version" +msgstr "" + +#. module: connector +#: model:ir.actions.act_window,help:connector.action_connector_checkpoint +msgid "" +"When a connector imports new records which have\n" +" configuration or reviews to do manually, they\n" +" will appear in this list. Once a record has been\n" +" checked, click on the 'Reviewed' button." +msgstr "" + +#. module: connector +#: model:ir.model,name:connector.model_base +msgid "base" +msgstr "" + +#. module: connector +#: model:ir.ui.view,arch_db:connector.view_connector_checkpoint_review +#: model:ir.ui.view,arch_db:connector.view_connector_config_settings +msgid "or" +msgstr "" + +#. module: connector +#: model:ir.ui.view,arch_db:connector.view_connector_checkpoint_form +msgid "to verify it:" +msgstr "" diff --git a/ext/3rd-party-addons/connector/i18n/et.po b/ext/3rd-party-addons/connector/i18n/et.po new file mode 100644 index 00000000..3bcc0969 --- /dev/null +++ b/ext/3rd-party-addons/connector/i18n/et.po @@ -0,0 +1,317 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * connector +# +# Translators: +# OCA Transbot , 2017 +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server 10.0\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2017-03-10 03:36+0000\n" +"PO-Revision-Date: 2017-03-10 03:36+0000\n" +"Last-Translator: OCA Transbot , 2017\n" +"Language-Team: Estonian (https://www.transifex.com/oca/teams/23907/et/)\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: \n" +"Language: et\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" + +#. module: connector +#: code:addons/connector/checkpoint/checkpoint.py:119 +#, python-format +msgid "A %s needs a review." +msgstr "" + +#. module: connector +#: model:ir.ui.view,arch_db:connector.view_connector_config_settings +msgid "Apply" +msgstr "" + +#. module: connector +#: model:ir.ui.view,arch_db:connector.view_connector_config_settings +msgid "Backends" +msgstr "" + +#. module: connector +#: model:ir.ui.view,arch_db:connector.view_connector_checkpoint_review +#: model:ir.ui.view,arch_db:connector.view_connector_config_settings +msgid "Cancel" +msgstr "Loobu" + +#. module: connector +#: model:ir.ui.menu,name:connector.menu_checkpoint +msgid "Checkpoint" +msgstr "" + +#. module: connector +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_review_checkpoint_ids +msgid "Checkpoints" +msgstr "" + +#. module: connector +#: model:ir.model,name:connector.model_connector_checkpoint_review +msgid "Checkpoints Review" +msgstr "" + +#. module: connector +#: model:ir.ui.view,arch_db:connector.view_connector_checkpoint_form +msgid "Click on the" +msgstr "" + +#. module: connector +#: model:ir.actions.act_window,name:connector.action_connector_config_settings +#: model:ir.ui.view,arch_db:connector.view_connector_config_settings +msgid "Configure Connector" +msgstr "" + +#. module: connector +#: model:ir.module.category,name:connector.module_category_connector +#: model:ir.ui.menu,name:connector.menu_connector_config_settings +msgid "Connector" +msgstr "" + +#. module: connector +#: model:ir.model,name:connector.model_connector_backend +msgid "Connector Backend" +msgstr "" + +#. module: connector +#: model:ir.actions.act_window,name:connector.action_connector_checkpoint +#: model:ir.model,name:connector.model_connector_checkpoint +#: model:ir.ui.view,arch_db:connector.view_connector_checkpoint_form +#: model:ir.ui.view,arch_db:connector.view_connector_checkpoint_search +#: model:ir.ui.view,arch_db:connector.view_connector_checkpoint_tree +msgid "Connector Checkpoint" +msgstr "" + +#. module: connector +#: model:ir.model,name:connector.model_connector_config_settings +msgid "Connector Configuration" +msgstr "" + +#. module: connector +#: model:res.groups,name:connector.group_connector_manager +msgid "Connector Manager" +msgstr "" + +#. module: connector +#: model:ir.ui.menu,name:connector.menu_connector +#: model:ir.ui.menu,name:connector.menu_connector_root +#: model:ir.ui.view,arch_db:connector.view_partner_connector_form +msgid "Connectors" +msgstr "" + +#. module: connector +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_create_uid +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_review_create_uid +#: model:ir.model.fields,field_description:connector.field_connector_config_settings_create_uid +msgid "Created by" +msgstr "" + +#. module: connector +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_create_date +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_review_create_date +#: model:ir.model.fields,field_description:connector.field_connector_config_settings_create_date +msgid "Created on" +msgstr "" + +#. module: connector +#: model:ir.model.fields,field_description:connector.field_connector_backend_display_name +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_display_name +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_review_display_name +#: model:ir.model.fields,field_description:connector.field_connector_config_settings_display_name +#: model:ir.model.fields,field_description:connector.field_external_binding_display_name +msgid "Display Name" +msgstr "" + +#. module: connector +#: model:ir.model,name:connector.model_external_binding +msgid "External Binding (abstract)" +msgstr "" + +#. module: connector +#: model:ir.ui.view,arch_db:connector.view_connector_checkpoint_search +msgid "Group By..." +msgstr "" + +#. module: connector +#: model:ir.model.fields,field_description:connector.field_connector_backend_id +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_id +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_review_id +#: model:ir.model.fields,field_description:connector.field_connector_config_settings_id +#: model:ir.model.fields,field_description:connector.field_external_binding_id +msgid "ID" +msgstr "" + +#. module: connector +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_backend_id +msgid "Imported from" +msgstr "" + +#. module: connector +#: model:ir.model.fields,field_description:connector.field_connector_backend___last_update +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint___last_update +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_review___last_update +#: model:ir.model.fields,field_description:connector.field_connector_config_settings___last_update +#: model:ir.model.fields,field_description:connector.field_external_binding___last_update +msgid "Last Modified on" +msgstr "" + +#. module: connector +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_review_write_uid +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_write_uid +#: model:ir.model.fields,field_description:connector.field_connector_config_settings_write_uid +msgid "Last Updated by" +msgstr "" + +#. module: connector +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_review_write_date +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_write_date +#: model:ir.model.fields,field_description:connector.field_connector_config_settings_write_date +msgid "Last Updated on" +msgstr "" + +#. module: connector +#: model:ir.model.fields,field_description:connector.field_connector_test_binding_sync_date +#: model:ir.model.fields,field_description:connector.field_external_binding_sync_date +#: model:ir.model.fields,field_description:connector.field_no_inherits_binding_sync_date +msgid "Last synchronization date" +msgstr "" + +#. module: connector +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_model_id +#: model:ir.ui.view,arch_db:connector.view_connector_checkpoint_search +msgid "Model" +msgstr "" + +#. module: connector +#: model:ir.model.fields,field_description:connector.field_connector_backend_name +#: model:ir.model.fields,field_description:connector.field_test_backend_name +msgid "Name" +msgstr "" + +#. module: connector +#: model:ir.model.fields,help:connector.field_connector_checkpoint_name +msgid "Name of the record to review" +msgstr "" + +#. module: connector +#: selection:connector.checkpoint,state:0 +#: model:ir.ui.view,arch_db:connector.view_connector_checkpoint_search +msgid "Need Review" +msgstr "" + +#. module: connector +#: model:ir.actions.act_window,help:connector.action_connector_checkpoint +msgid "No record to check." +msgstr "" + +#. module: connector +#: model:ir.actions.client,name:connector.action_client_connector_menu +msgid "Open Connector Menu" +msgstr "" + +#. module: connector +#: model:ir.model,name:connector.model_queue_job +msgid "Queue Job" +msgstr "" + +#. module: connector +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_record +msgid "Record" +msgstr "" + +#. module: connector +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_record_id +msgid "Record ID" +msgstr "" + +#. module: connector +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_name +msgid "Record Name" +msgstr "" + +#. module: connector +#: code:addons/connector/models/queue_job.py:32 +#, python-format +msgid "Related Record" +msgstr "" + +#. module: connector +#: model:ir.actions.act_window,name:connector.action_connector_checkpoint_review +#: model:ir.ui.view,arch_db:connector.view_connector_checkpoint_review +msgid "Review Checkpoints" +msgstr "" + +#. module: connector +#: selection:connector.checkpoint,state:0 +#: model:ir.ui.view,arch_db:connector.view_connector_checkpoint_form +#: model:ir.ui.view,arch_db:connector.view_connector_checkpoint_search +#: model:ir.ui.view,arch_db:connector.view_connector_checkpoint_tree +msgid "Reviewed" +msgstr "" + +#. module: connector +#: model:ir.ui.view,arch_db:connector.view_connector_checkpoint_review +msgid "Set as reviewed" +msgstr "" + +#. module: connector +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_state +msgid "Status" +msgstr "" + +#. module: connector +#: model:ir.actions.act_window,help:connector.action_connector_checkpoint +msgid "" +"The connectors list the new records to verify\n" +" based on their type. Only some need a manual\n" +" review." +msgstr "" + +#. module: connector +#: model:ir.model.fields,help:connector.field_connector_checkpoint_backend_id +msgid "The record has been imported from this backend" +msgstr "" + +#. module: connector +#: model:ir.model.fields,help:connector.field_connector_checkpoint_record +msgid "The record to review." +msgstr "" + +#. module: connector +#: model:ir.ui.view,arch_db:connector.view_connector_checkpoint_review +msgid "The selected checkpoints will be set as reviewed." +msgstr "" + +#. module: connector +#: model:ir.model.fields,field_description:connector.field_connector_backend_version +msgid "Version" +msgstr "" + +#. module: connector +#: model:ir.actions.act_window,help:connector.action_connector_checkpoint +msgid "" +"When a connector imports new records which have\n" +" configuration or reviews to do manually, they\n" +" will appear in this list. Once a record has been\n" +" checked, click on the 'Reviewed' button." +msgstr "" + +#. module: connector +#: model:ir.model,name:connector.model_base +msgid "base" +msgstr "" + +#. module: connector +#: model:ir.ui.view,arch_db:connector.view_connector_checkpoint_review +#: model:ir.ui.view,arch_db:connector.view_connector_config_settings +msgid "or" +msgstr "" + +#. module: connector +#: model:ir.ui.view,arch_db:connector.view_connector_checkpoint_form +msgid "to verify it:" +msgstr "" diff --git a/ext/3rd-party-addons/connector/i18n/fi.po b/ext/3rd-party-addons/connector/i18n/fi.po new file mode 100644 index 00000000..67df00b5 --- /dev/null +++ b/ext/3rd-party-addons/connector/i18n/fi.po @@ -0,0 +1,317 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * connector +# +# Translators: +# OCA Transbot , 2017 +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server 10.0\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2017-03-10 03:36+0000\n" +"PO-Revision-Date: 2017-03-10 03:36+0000\n" +"Last-Translator: OCA Transbot , 2017\n" +"Language-Team: Finnish (https://www.transifex.com/oca/teams/23907/fi/)\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: \n" +"Language: fi\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" + +#. module: connector +#: code:addons/connector/checkpoint/checkpoint.py:119 +#, python-format +msgid "A %s needs a review." +msgstr "" + +#. module: connector +#: model:ir.ui.view,arch_db:connector.view_connector_config_settings +msgid "Apply" +msgstr "" + +#. module: connector +#: model:ir.ui.view,arch_db:connector.view_connector_config_settings +msgid "Backends" +msgstr "" + +#. module: connector +#: model:ir.ui.view,arch_db:connector.view_connector_checkpoint_review +#: model:ir.ui.view,arch_db:connector.view_connector_config_settings +msgid "Cancel" +msgstr "" + +#. module: connector +#: model:ir.ui.menu,name:connector.menu_checkpoint +msgid "Checkpoint" +msgstr "" + +#. module: connector +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_review_checkpoint_ids +msgid "Checkpoints" +msgstr "" + +#. module: connector +#: model:ir.model,name:connector.model_connector_checkpoint_review +msgid "Checkpoints Review" +msgstr "" + +#. module: connector +#: model:ir.ui.view,arch_db:connector.view_connector_checkpoint_form +msgid "Click on the" +msgstr "" + +#. module: connector +#: model:ir.actions.act_window,name:connector.action_connector_config_settings +#: model:ir.ui.view,arch_db:connector.view_connector_config_settings +msgid "Configure Connector" +msgstr "" + +#. module: connector +#: model:ir.module.category,name:connector.module_category_connector +#: model:ir.ui.menu,name:connector.menu_connector_config_settings +msgid "Connector" +msgstr "" + +#. module: connector +#: model:ir.model,name:connector.model_connector_backend +msgid "Connector Backend" +msgstr "" + +#. module: connector +#: model:ir.actions.act_window,name:connector.action_connector_checkpoint +#: model:ir.model,name:connector.model_connector_checkpoint +#: model:ir.ui.view,arch_db:connector.view_connector_checkpoint_form +#: model:ir.ui.view,arch_db:connector.view_connector_checkpoint_search +#: model:ir.ui.view,arch_db:connector.view_connector_checkpoint_tree +msgid "Connector Checkpoint" +msgstr "" + +#. module: connector +#: model:ir.model,name:connector.model_connector_config_settings +msgid "Connector Configuration" +msgstr "" + +#. module: connector +#: model:res.groups,name:connector.group_connector_manager +msgid "Connector Manager" +msgstr "" + +#. module: connector +#: model:ir.ui.menu,name:connector.menu_connector +#: model:ir.ui.menu,name:connector.menu_connector_root +#: model:ir.ui.view,arch_db:connector.view_partner_connector_form +msgid "Connectors" +msgstr "" + +#. module: connector +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_create_uid +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_review_create_uid +#: model:ir.model.fields,field_description:connector.field_connector_config_settings_create_uid +msgid "Created by" +msgstr "Luonut" + +#. module: connector +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_create_date +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_review_create_date +#: model:ir.model.fields,field_description:connector.field_connector_config_settings_create_date +msgid "Created on" +msgstr "Luotu" + +#. module: connector +#: model:ir.model.fields,field_description:connector.field_connector_backend_display_name +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_display_name +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_review_display_name +#: model:ir.model.fields,field_description:connector.field_connector_config_settings_display_name +#: model:ir.model.fields,field_description:connector.field_external_binding_display_name +msgid "Display Name" +msgstr "Nimi" + +#. module: connector +#: model:ir.model,name:connector.model_external_binding +msgid "External Binding (abstract)" +msgstr "" + +#. module: connector +#: model:ir.ui.view,arch_db:connector.view_connector_checkpoint_search +msgid "Group By..." +msgstr "" + +#. module: connector +#: model:ir.model.fields,field_description:connector.field_connector_backend_id +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_id +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_review_id +#: model:ir.model.fields,field_description:connector.field_connector_config_settings_id +#: model:ir.model.fields,field_description:connector.field_external_binding_id +msgid "ID" +msgstr "ID" + +#. module: connector +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_backend_id +msgid "Imported from" +msgstr "" + +#. module: connector +#: model:ir.model.fields,field_description:connector.field_connector_backend___last_update +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint___last_update +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_review___last_update +#: model:ir.model.fields,field_description:connector.field_connector_config_settings___last_update +#: model:ir.model.fields,field_description:connector.field_external_binding___last_update +msgid "Last Modified on" +msgstr "Viimeksi muokattu" + +#. module: connector +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_review_write_uid +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_write_uid +#: model:ir.model.fields,field_description:connector.field_connector_config_settings_write_uid +msgid "Last Updated by" +msgstr "Viimeksi päivittänyt" + +#. module: connector +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_review_write_date +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_write_date +#: model:ir.model.fields,field_description:connector.field_connector_config_settings_write_date +msgid "Last Updated on" +msgstr "Viimeksi päivitetty" + +#. module: connector +#: model:ir.model.fields,field_description:connector.field_connector_test_binding_sync_date +#: model:ir.model.fields,field_description:connector.field_external_binding_sync_date +#: model:ir.model.fields,field_description:connector.field_no_inherits_binding_sync_date +msgid "Last synchronization date" +msgstr "" + +#. module: connector +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_model_id +#: model:ir.ui.view,arch_db:connector.view_connector_checkpoint_search +msgid "Model" +msgstr "" + +#. module: connector +#: model:ir.model.fields,field_description:connector.field_connector_backend_name +#: model:ir.model.fields,field_description:connector.field_test_backend_name +msgid "Name" +msgstr "" + +#. module: connector +#: model:ir.model.fields,help:connector.field_connector_checkpoint_name +msgid "Name of the record to review" +msgstr "" + +#. module: connector +#: selection:connector.checkpoint,state:0 +#: model:ir.ui.view,arch_db:connector.view_connector_checkpoint_search +msgid "Need Review" +msgstr "" + +#. module: connector +#: model:ir.actions.act_window,help:connector.action_connector_checkpoint +msgid "No record to check." +msgstr "" + +#. module: connector +#: model:ir.actions.client,name:connector.action_client_connector_menu +msgid "Open Connector Menu" +msgstr "" + +#. module: connector +#: model:ir.model,name:connector.model_queue_job +msgid "Queue Job" +msgstr "" + +#. module: connector +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_record +msgid "Record" +msgstr "" + +#. module: connector +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_record_id +msgid "Record ID" +msgstr "" + +#. module: connector +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_name +msgid "Record Name" +msgstr "" + +#. module: connector +#: code:addons/connector/models/queue_job.py:32 +#, python-format +msgid "Related Record" +msgstr "" + +#. module: connector +#: model:ir.actions.act_window,name:connector.action_connector_checkpoint_review +#: model:ir.ui.view,arch_db:connector.view_connector_checkpoint_review +msgid "Review Checkpoints" +msgstr "" + +#. module: connector +#: selection:connector.checkpoint,state:0 +#: model:ir.ui.view,arch_db:connector.view_connector_checkpoint_form +#: model:ir.ui.view,arch_db:connector.view_connector_checkpoint_search +#: model:ir.ui.view,arch_db:connector.view_connector_checkpoint_tree +msgid "Reviewed" +msgstr "" + +#. module: connector +#: model:ir.ui.view,arch_db:connector.view_connector_checkpoint_review +msgid "Set as reviewed" +msgstr "" + +#. module: connector +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_state +msgid "Status" +msgstr "" + +#. module: connector +#: model:ir.actions.act_window,help:connector.action_connector_checkpoint +msgid "" +"The connectors list the new records to verify\n" +" based on their type. Only some need a manual\n" +" review." +msgstr "" + +#. module: connector +#: model:ir.model.fields,help:connector.field_connector_checkpoint_backend_id +msgid "The record has been imported from this backend" +msgstr "" + +#. module: connector +#: model:ir.model.fields,help:connector.field_connector_checkpoint_record +msgid "The record to review." +msgstr "" + +#. module: connector +#: model:ir.ui.view,arch_db:connector.view_connector_checkpoint_review +msgid "The selected checkpoints will be set as reviewed." +msgstr "" + +#. module: connector +#: model:ir.model.fields,field_description:connector.field_connector_backend_version +msgid "Version" +msgstr "" + +#. module: connector +#: model:ir.actions.act_window,help:connector.action_connector_checkpoint +msgid "" +"When a connector imports new records which have\n" +" configuration or reviews to do manually, they\n" +" will appear in this list. Once a record has been\n" +" checked, click on the 'Reviewed' button." +msgstr "" + +#. module: connector +#: model:ir.model,name:connector.model_base +msgid "base" +msgstr "" + +#. module: connector +#: model:ir.ui.view,arch_db:connector.view_connector_checkpoint_review +#: model:ir.ui.view,arch_db:connector.view_connector_config_settings +msgid "or" +msgstr "" + +#. module: connector +#: model:ir.ui.view,arch_db:connector.view_connector_checkpoint_form +msgid "to verify it:" +msgstr "" diff --git a/ext/3rd-party-addons/connector/i18n/fr.po b/ext/3rd-party-addons/connector/i18n/fr.po new file mode 100644 index 00000000..3383cf0d --- /dev/null +++ b/ext/3rd-party-addons/connector/i18n/fr.po @@ -0,0 +1,322 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * connector +# +# Translators: +# OCA Transbot , 2017 +# leemannd , 2017 +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server 10.0\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2017-06-14 20:10+0000\n" +"PO-Revision-Date: 2017-06-14 20:10+0000\n" +"Last-Translator: leemannd , 2017\n" +"Language-Team: French (https://www.transifex.com/oca/teams/23907/fr/)\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: \n" +"Language: fr\n" +"Plural-Forms: nplurals=2; plural=(n > 1);\n" + +#. module: connector +#: code:addons/connector/checkpoint/checkpoint.py:119 +#, python-format +msgid "A %s needs a review." +msgstr "Un %s a besoin d'un contrôle." + +#. module: connector +#: model:ir.ui.view,arch_db:connector.view_connector_config_settings +msgid "Apply" +msgstr "Appliquer" + +#. module: connector +#: model:ir.ui.view,arch_db:connector.view_connector_config_settings +msgid "Backends" +msgstr "Backends" + +#. module: connector +#: model:ir.ui.view,arch_db:connector.view_connector_checkpoint_review +#: model:ir.ui.view,arch_db:connector.view_connector_config_settings +msgid "Cancel" +msgstr "Annuler" + +#. module: connector +#: model:ir.ui.menu,name:connector.menu_checkpoint +msgid "Checkpoint" +msgstr "Points de contrôle" + +#. module: connector +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_review_checkpoint_ids +msgid "Checkpoints" +msgstr "Points de contrôle" + +#. module: connector +#: model:ir.model,name:connector.model_connector_checkpoint_review +msgid "Checkpoints Review" +msgstr "Points de contrôle" + +#. module: connector +#: model:ir.ui.view,arch_db:connector.view_connector_checkpoint_form +msgid "Click on the" +msgstr "Cliquer sur le" + +#. module: connector +#: model:ir.actions.act_window,name:connector.action_connector_config_settings +#: model:ir.ui.view,arch_db:connector.view_connector_config_settings +msgid "Configure Connector" +msgstr "Configurer les connecteurs" + +#. module: connector +#: model:ir.module.category,name:connector.module_category_connector +#: model:ir.ui.menu,name:connector.menu_connector_config_settings +msgid "Connector" +msgstr "Connecteur" + +#. module: connector +#: model:ir.model,name:connector.model_connector_backend +msgid "Connector Backend" +msgstr "Backend de connecteur" + +#. module: connector +#: model:ir.actions.act_window,name:connector.action_connector_checkpoint +#: model:ir.model,name:connector.model_connector_checkpoint +#: model:ir.ui.view,arch_db:connector.view_connector_checkpoint_form +#: model:ir.ui.view,arch_db:connector.view_connector_checkpoint_search +#: model:ir.ui.view,arch_db:connector.view_connector_checkpoint_tree +msgid "Connector Checkpoint" +msgstr "Point de contrôle" + +#. module: connector +#: model:ir.model,name:connector.model_connector_config_settings +msgid "Connector Configuration" +msgstr "Configuration du connecteur" + +#. module: connector +#: model:res.groups,name:connector.group_connector_manager +msgid "Connector Manager" +msgstr "Responsable connecteurs" + +#. module: connector +#: model:ir.ui.menu,name:connector.menu_connector +#: model:ir.ui.menu,name:connector.menu_connector_root +#: model:ir.ui.view,arch_db:connector.view_partner_connector_form +msgid "Connectors" +msgstr "Connecteurs" + +#. module: connector +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_create_uid +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_review_create_uid +#: model:ir.model.fields,field_description:connector.field_connector_config_settings_create_uid +msgid "Created by" +msgstr "Créé par" + +#. module: connector +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_create_date +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_review_create_date +#: model:ir.model.fields,field_description:connector.field_connector_config_settings_create_date +msgid "Created on" +msgstr "Créé le" + +#. module: connector +#: model:ir.model.fields,field_description:connector.field_connector_backend_display_name +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_display_name +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_review_display_name +#: model:ir.model.fields,field_description:connector.field_connector_config_settings_display_name +#: model:ir.model.fields,field_description:connector.field_external_binding_display_name +msgid "Display Name" +msgstr "Nom affiché" + +#. module: connector +#: model:ir.model,name:connector.model_external_binding +msgid "External Binding (abstract)" +msgstr "Lien Externe (abstrait)" + +#. module: connector +#: model:ir.ui.view,arch_db:connector.view_connector_checkpoint_search +msgid "Group By..." +msgstr "Grouper par..." + +#. module: connector +#: model:ir.model.fields,field_description:connector.field_connector_backend_id +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_id +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_review_id +#: model:ir.model.fields,field_description:connector.field_connector_config_settings_id +#: model:ir.model.fields,field_description:connector.field_external_binding_id +msgid "ID" +msgstr "ID" + +#. module: connector +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_backend_id +msgid "Imported from" +msgstr "Importé depuis" + +#. module: connector +#: model:ir.model.fields,field_description:connector.field_connector_backend___last_update +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint___last_update +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_review___last_update +#: model:ir.model.fields,field_description:connector.field_connector_config_settings___last_update +#: model:ir.model.fields,field_description:connector.field_external_binding___last_update +msgid "Last Modified on" +msgstr "Dernière modification le" + +#. module: connector +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_review_write_uid +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_write_uid +#: model:ir.model.fields,field_description:connector.field_connector_config_settings_write_uid +msgid "Last Updated by" +msgstr "Dernière mise à jour par" + +#. module: connector +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_review_write_date +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_write_date +#: model:ir.model.fields,field_description:connector.field_connector_config_settings_write_date +msgid "Last Updated on" +msgstr "Dernière mise à jour le" + +#. module: connector +#: model:ir.model.fields,field_description:connector.field_connector_test_binding_sync_date +#: model:ir.model.fields,field_description:connector.field_external_binding_sync_date +#: model:ir.model.fields,field_description:connector.field_no_inherits_binding_sync_date +msgid "Last synchronization date" +msgstr "Dernière date de synchronisation" + +#. module: connector +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_model_id +#: model:ir.ui.view,arch_db:connector.view_connector_checkpoint_search +msgid "Model" +msgstr "Modèle" + +#. module: connector +#: model:ir.model.fields,field_description:connector.field_connector_backend_name +#: model:ir.model.fields,field_description:connector.field_test_backend_name +msgid "Name" +msgstr "Nom" + +#. module: connector +#: model:ir.model.fields,help:connector.field_connector_checkpoint_name +msgid "Name of the record to review" +msgstr "Nom de l'enregistrement à contrôler" + +#. module: connector +#: selection:connector.checkpoint,state:0 +#: model:ir.ui.view,arch_db:connector.view_connector_checkpoint_search +msgid "Need Review" +msgstr "Nécessite un contrôle" + +#. module: connector +#: model:ir.actions.act_window,help:connector.action_connector_checkpoint +msgid "No record to check." +msgstr "Pas d'enregistrement à contrôler." + +#. module: connector +#: model:ir.actions.client,name:connector.action_client_connector_menu +msgid "Open Connector Menu" +msgstr "Ouvrir le menu du connecteur" + +#. module: connector +#: model:ir.model,name:connector.model_queue_job +msgid "Queue Job" +msgstr "Queue de jobs" + +#. module: connector +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_record +msgid "Record" +msgstr "Enregistrement" + +#. module: connector +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_record_id +msgid "Record ID" +msgstr "ID de ressource" + +#. module: connector +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_name +msgid "Record Name" +msgstr "Nom d'enregistrement" + +#. module: connector +#: code:addons/connector/models/queue_job.py:32 +#, python-format +msgid "Related Record" +msgstr "Enregistrement lié" + +#. module: connector +#: model:ir.actions.act_window,name:connector.action_connector_checkpoint_review +#: model:ir.ui.view,arch_db:connector.view_connector_checkpoint_review +msgid "Review Checkpoints" +msgstr "Contrôler" + +#. module: connector +#: selection:connector.checkpoint,state:0 +#: model:ir.ui.view,arch_db:connector.view_connector_checkpoint_form +#: model:ir.ui.view,arch_db:connector.view_connector_checkpoint_search +#: model:ir.ui.view,arch_db:connector.view_connector_checkpoint_tree +msgid "Reviewed" +msgstr "Contrôlé" + +#. module: connector +#: model:ir.ui.view,arch_db:connector.view_connector_checkpoint_review +msgid "Set as reviewed" +msgstr "Passer en contrôlé" + +#. module: connector +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_state +msgid "Status" +msgstr "État" + +#. module: connector +#: model:ir.actions.act_window,help:connector.action_connector_checkpoint +msgid "" +"The connectors list the new records to verify\n" +" based on their type. Only some need a manual\n" +" review." +msgstr "" +"Les connecteurs listent les nouveaux enregistrements pour vérifier\n" +" leur type. Seulement certaines nécessitent un contrôle\n" +" manuel." + +#. module: connector +#: model:ir.model.fields,help:connector.field_connector_checkpoint_backend_id +msgid "The record has been imported from this backend" +msgstr "La ressource a été importée depuis ce backend." + +#. module: connector +#: model:ir.model.fields,help:connector.field_connector_checkpoint_record +msgid "The record to review." +msgstr "L'enregistrement à contrôler." + +#. module: connector +#: model:ir.ui.view,arch_db:connector.view_connector_checkpoint_review +msgid "The selected checkpoints will be set as reviewed." +msgstr "" +"Les points de contrôle sélectionnés vont être considérés comme contrôlés." + +#. module: connector +#: model:ir.model.fields,field_description:connector.field_connector_backend_version +msgid "Version" +msgstr "Version" + +#. module: connector +#: model:ir.actions.act_window,help:connector.action_connector_checkpoint +msgid "" +"When a connector imports new records which have\n" +" configuration or reviews to do manually, they\n" +" will appear in this list. Once a record has been\n" +" checked, click on the 'Reviewed' button." +msgstr "" + +#. module: connector +#: model:ir.model,name:connector.model_base +msgid "base" +msgstr "base" + +#. module: connector +#: model:ir.ui.view,arch_db:connector.view_connector_checkpoint_review +#: model:ir.ui.view,arch_db:connector.view_connector_config_settings +msgid "or" +msgstr "ou" + +#. module: connector +#: model:ir.ui.view,arch_db:connector.view_connector_checkpoint_form +msgid "to verify it:" +msgstr "pour le vérifier:" diff --git a/ext/3rd-party-addons/connector/i18n/gl.po b/ext/3rd-party-addons/connector/i18n/gl.po new file mode 100644 index 00000000..dbfb7fb3 --- /dev/null +++ b/ext/3rd-party-addons/connector/i18n/gl.po @@ -0,0 +1,317 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * connector +# +# Translators: +# OCA Transbot , 2017 +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server 10.0\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2017-03-10 03:36+0000\n" +"PO-Revision-Date: 2017-03-10 03:36+0000\n" +"Last-Translator: OCA Transbot , 2017\n" +"Language-Team: Galician (https://www.transifex.com/oca/teams/23907/gl/)\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: \n" +"Language: gl\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" + +#. module: connector +#: code:addons/connector/checkpoint/checkpoint.py:119 +#, python-format +msgid "A %s needs a review." +msgstr "" + +#. module: connector +#: model:ir.ui.view,arch_db:connector.view_connector_config_settings +msgid "Apply" +msgstr "" + +#. module: connector +#: model:ir.ui.view,arch_db:connector.view_connector_config_settings +msgid "Backends" +msgstr "" + +#. module: connector +#: model:ir.ui.view,arch_db:connector.view_connector_checkpoint_review +#: model:ir.ui.view,arch_db:connector.view_connector_config_settings +msgid "Cancel" +msgstr "Cancelar" + +#. module: connector +#: model:ir.ui.menu,name:connector.menu_checkpoint +msgid "Checkpoint" +msgstr "" + +#. module: connector +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_review_checkpoint_ids +msgid "Checkpoints" +msgstr "" + +#. module: connector +#: model:ir.model,name:connector.model_connector_checkpoint_review +msgid "Checkpoints Review" +msgstr "" + +#. module: connector +#: model:ir.ui.view,arch_db:connector.view_connector_checkpoint_form +msgid "Click on the" +msgstr "" + +#. module: connector +#: model:ir.actions.act_window,name:connector.action_connector_config_settings +#: model:ir.ui.view,arch_db:connector.view_connector_config_settings +msgid "Configure Connector" +msgstr "" + +#. module: connector +#: model:ir.module.category,name:connector.module_category_connector +#: model:ir.ui.menu,name:connector.menu_connector_config_settings +msgid "Connector" +msgstr "" + +#. module: connector +#: model:ir.model,name:connector.model_connector_backend +msgid "Connector Backend" +msgstr "" + +#. module: connector +#: model:ir.actions.act_window,name:connector.action_connector_checkpoint +#: model:ir.model,name:connector.model_connector_checkpoint +#: model:ir.ui.view,arch_db:connector.view_connector_checkpoint_form +#: model:ir.ui.view,arch_db:connector.view_connector_checkpoint_search +#: model:ir.ui.view,arch_db:connector.view_connector_checkpoint_tree +msgid "Connector Checkpoint" +msgstr "" + +#. module: connector +#: model:ir.model,name:connector.model_connector_config_settings +msgid "Connector Configuration" +msgstr "" + +#. module: connector +#: model:res.groups,name:connector.group_connector_manager +msgid "Connector Manager" +msgstr "" + +#. module: connector +#: model:ir.ui.menu,name:connector.menu_connector +#: model:ir.ui.menu,name:connector.menu_connector_root +#: model:ir.ui.view,arch_db:connector.view_partner_connector_form +msgid "Connectors" +msgstr "" + +#. module: connector +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_create_uid +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_review_create_uid +#: model:ir.model.fields,field_description:connector.field_connector_config_settings_create_uid +msgid "Created by" +msgstr "Creado por" + +#. module: connector +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_create_date +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_review_create_date +#: model:ir.model.fields,field_description:connector.field_connector_config_settings_create_date +msgid "Created on" +msgstr "Creado en" + +#. module: connector +#: model:ir.model.fields,field_description:connector.field_connector_backend_display_name +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_display_name +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_review_display_name +#: model:ir.model.fields,field_description:connector.field_connector_config_settings_display_name +#: model:ir.model.fields,field_description:connector.field_external_binding_display_name +msgid "Display Name" +msgstr "" + +#. module: connector +#: model:ir.model,name:connector.model_external_binding +msgid "External Binding (abstract)" +msgstr "" + +#. module: connector +#: model:ir.ui.view,arch_db:connector.view_connector_checkpoint_search +msgid "Group By..." +msgstr "" + +#. module: connector +#: model:ir.model.fields,field_description:connector.field_connector_backend_id +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_id +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_review_id +#: model:ir.model.fields,field_description:connector.field_connector_config_settings_id +#: model:ir.model.fields,field_description:connector.field_external_binding_id +msgid "ID" +msgstr "ID" + +#. module: connector +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_backend_id +msgid "Imported from" +msgstr "" + +#. module: connector +#: model:ir.model.fields,field_description:connector.field_connector_backend___last_update +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint___last_update +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_review___last_update +#: model:ir.model.fields,field_description:connector.field_connector_config_settings___last_update +#: model:ir.model.fields,field_description:connector.field_external_binding___last_update +msgid "Last Modified on" +msgstr "" + +#. module: connector +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_review_write_uid +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_write_uid +#: model:ir.model.fields,field_description:connector.field_connector_config_settings_write_uid +msgid "Last Updated by" +msgstr "ültima actualización por" + +#. module: connector +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_review_write_date +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_write_date +#: model:ir.model.fields,field_description:connector.field_connector_config_settings_write_date +msgid "Last Updated on" +msgstr "Última actualización en" + +#. module: connector +#: model:ir.model.fields,field_description:connector.field_connector_test_binding_sync_date +#: model:ir.model.fields,field_description:connector.field_external_binding_sync_date +#: model:ir.model.fields,field_description:connector.field_no_inherits_binding_sync_date +msgid "Last synchronization date" +msgstr "" + +#. module: connector +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_model_id +#: model:ir.ui.view,arch_db:connector.view_connector_checkpoint_search +msgid "Model" +msgstr "" + +#. module: connector +#: model:ir.model.fields,field_description:connector.field_connector_backend_name +#: model:ir.model.fields,field_description:connector.field_test_backend_name +msgid "Name" +msgstr "" + +#. module: connector +#: model:ir.model.fields,help:connector.field_connector_checkpoint_name +msgid "Name of the record to review" +msgstr "" + +#. module: connector +#: selection:connector.checkpoint,state:0 +#: model:ir.ui.view,arch_db:connector.view_connector_checkpoint_search +msgid "Need Review" +msgstr "" + +#. module: connector +#: model:ir.actions.act_window,help:connector.action_connector_checkpoint +msgid "No record to check." +msgstr "" + +#. module: connector +#: model:ir.actions.client,name:connector.action_client_connector_menu +msgid "Open Connector Menu" +msgstr "" + +#. module: connector +#: model:ir.model,name:connector.model_queue_job +msgid "Queue Job" +msgstr "" + +#. module: connector +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_record +msgid "Record" +msgstr "" + +#. module: connector +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_record_id +msgid "Record ID" +msgstr "" + +#. module: connector +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_name +msgid "Record Name" +msgstr "" + +#. module: connector +#: code:addons/connector/models/queue_job.py:32 +#, python-format +msgid "Related Record" +msgstr "" + +#. module: connector +#: model:ir.actions.act_window,name:connector.action_connector_checkpoint_review +#: model:ir.ui.view,arch_db:connector.view_connector_checkpoint_review +msgid "Review Checkpoints" +msgstr "" + +#. module: connector +#: selection:connector.checkpoint,state:0 +#: model:ir.ui.view,arch_db:connector.view_connector_checkpoint_form +#: model:ir.ui.view,arch_db:connector.view_connector_checkpoint_search +#: model:ir.ui.view,arch_db:connector.view_connector_checkpoint_tree +msgid "Reviewed" +msgstr "" + +#. module: connector +#: model:ir.ui.view,arch_db:connector.view_connector_checkpoint_review +msgid "Set as reviewed" +msgstr "" + +#. module: connector +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_state +msgid "Status" +msgstr "" + +#. module: connector +#: model:ir.actions.act_window,help:connector.action_connector_checkpoint +msgid "" +"The connectors list the new records to verify\n" +" based on their type. Only some need a manual\n" +" review." +msgstr "" + +#. module: connector +#: model:ir.model.fields,help:connector.field_connector_checkpoint_backend_id +msgid "The record has been imported from this backend" +msgstr "" + +#. module: connector +#: model:ir.model.fields,help:connector.field_connector_checkpoint_record +msgid "The record to review." +msgstr "" + +#. module: connector +#: model:ir.ui.view,arch_db:connector.view_connector_checkpoint_review +msgid "The selected checkpoints will be set as reviewed." +msgstr "" + +#. module: connector +#: model:ir.model.fields,field_description:connector.field_connector_backend_version +msgid "Version" +msgstr "" + +#. module: connector +#: model:ir.actions.act_window,help:connector.action_connector_checkpoint +msgid "" +"When a connector imports new records which have\n" +" configuration or reviews to do manually, they\n" +" will appear in this list. Once a record has been\n" +" checked, click on the 'Reviewed' button." +msgstr "" + +#. module: connector +#: model:ir.model,name:connector.model_base +msgid "base" +msgstr "" + +#. module: connector +#: model:ir.ui.view,arch_db:connector.view_connector_checkpoint_review +#: model:ir.ui.view,arch_db:connector.view_connector_config_settings +msgid "or" +msgstr "" + +#. module: connector +#: model:ir.ui.view,arch_db:connector.view_connector_checkpoint_form +msgid "to verify it:" +msgstr "" diff --git a/ext/3rd-party-addons/connector/i18n/hr.po b/ext/3rd-party-addons/connector/i18n/hr.po new file mode 100644 index 00000000..a052622f --- /dev/null +++ b/ext/3rd-party-addons/connector/i18n/hr.po @@ -0,0 +1,317 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * connector +# +# Translators: +# OCA Transbot , 2017 +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server 10.0\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2017-03-10 03:36+0000\n" +"PO-Revision-Date: 2017-03-10 03:36+0000\n" +"Last-Translator: OCA Transbot , 2017\n" +"Language-Team: Croatian (https://www.transifex.com/oca/teams/23907/hr/)\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: \n" +"Language: hr\n" +"Plural-Forms: nplurals=3; plural=n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2;\n" + +#. module: connector +#: code:addons/connector/checkpoint/checkpoint.py:119 +#, python-format +msgid "A %s needs a review." +msgstr "" + +#. module: connector +#: model:ir.ui.view,arch_db:connector.view_connector_config_settings +msgid "Apply" +msgstr "Primjeni" + +#. module: connector +#: model:ir.ui.view,arch_db:connector.view_connector_config_settings +msgid "Backends" +msgstr "" + +#. module: connector +#: model:ir.ui.view,arch_db:connector.view_connector_checkpoint_review +#: model:ir.ui.view,arch_db:connector.view_connector_config_settings +msgid "Cancel" +msgstr "" + +#. module: connector +#: model:ir.ui.menu,name:connector.menu_checkpoint +msgid "Checkpoint" +msgstr "" + +#. module: connector +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_review_checkpoint_ids +msgid "Checkpoints" +msgstr "" + +#. module: connector +#: model:ir.model,name:connector.model_connector_checkpoint_review +msgid "Checkpoints Review" +msgstr "" + +#. module: connector +#: model:ir.ui.view,arch_db:connector.view_connector_checkpoint_form +msgid "Click on the" +msgstr "" + +#. module: connector +#: model:ir.actions.act_window,name:connector.action_connector_config_settings +#: model:ir.ui.view,arch_db:connector.view_connector_config_settings +msgid "Configure Connector" +msgstr "" + +#. module: connector +#: model:ir.module.category,name:connector.module_category_connector +#: model:ir.ui.menu,name:connector.menu_connector_config_settings +msgid "Connector" +msgstr "" + +#. module: connector +#: model:ir.model,name:connector.model_connector_backend +msgid "Connector Backend" +msgstr "" + +#. module: connector +#: model:ir.actions.act_window,name:connector.action_connector_checkpoint +#: model:ir.model,name:connector.model_connector_checkpoint +#: model:ir.ui.view,arch_db:connector.view_connector_checkpoint_form +#: model:ir.ui.view,arch_db:connector.view_connector_checkpoint_search +#: model:ir.ui.view,arch_db:connector.view_connector_checkpoint_tree +msgid "Connector Checkpoint" +msgstr "" + +#. module: connector +#: model:ir.model,name:connector.model_connector_config_settings +msgid "Connector Configuration" +msgstr "" + +#. module: connector +#: model:res.groups,name:connector.group_connector_manager +msgid "Connector Manager" +msgstr "" + +#. module: connector +#: model:ir.ui.menu,name:connector.menu_connector +#: model:ir.ui.menu,name:connector.menu_connector_root +#: model:ir.ui.view,arch_db:connector.view_partner_connector_form +msgid "Connectors" +msgstr "" + +#. module: connector +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_create_uid +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_review_create_uid +#: model:ir.model.fields,field_description:connector.field_connector_config_settings_create_uid +msgid "Created by" +msgstr "" + +#. module: connector +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_create_date +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_review_create_date +#: model:ir.model.fields,field_description:connector.field_connector_config_settings_create_date +msgid "Created on" +msgstr "" + +#. module: connector +#: model:ir.model.fields,field_description:connector.field_connector_backend_display_name +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_display_name +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_review_display_name +#: model:ir.model.fields,field_description:connector.field_connector_config_settings_display_name +#: model:ir.model.fields,field_description:connector.field_external_binding_display_name +msgid "Display Name" +msgstr "" + +#. module: connector +#: model:ir.model,name:connector.model_external_binding +msgid "External Binding (abstract)" +msgstr "" + +#. module: connector +#: model:ir.ui.view,arch_db:connector.view_connector_checkpoint_search +msgid "Group By..." +msgstr "Grupiraj po..." + +#. module: connector +#: model:ir.model.fields,field_description:connector.field_connector_backend_id +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_id +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_review_id +#: model:ir.model.fields,field_description:connector.field_connector_config_settings_id +#: model:ir.model.fields,field_description:connector.field_external_binding_id +msgid "ID" +msgstr "" + +#. module: connector +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_backend_id +msgid "Imported from" +msgstr "" + +#. module: connector +#: model:ir.model.fields,field_description:connector.field_connector_backend___last_update +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint___last_update +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_review___last_update +#: model:ir.model.fields,field_description:connector.field_connector_config_settings___last_update +#: model:ir.model.fields,field_description:connector.field_external_binding___last_update +msgid "Last Modified on" +msgstr "" + +#. module: connector +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_review_write_uid +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_write_uid +#: model:ir.model.fields,field_description:connector.field_connector_config_settings_write_uid +msgid "Last Updated by" +msgstr "" + +#. module: connector +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_review_write_date +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_write_date +#: model:ir.model.fields,field_description:connector.field_connector_config_settings_write_date +msgid "Last Updated on" +msgstr "" + +#. module: connector +#: model:ir.model.fields,field_description:connector.field_connector_test_binding_sync_date +#: model:ir.model.fields,field_description:connector.field_external_binding_sync_date +#: model:ir.model.fields,field_description:connector.field_no_inherits_binding_sync_date +msgid "Last synchronization date" +msgstr "" + +#. module: connector +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_model_id +#: model:ir.ui.view,arch_db:connector.view_connector_checkpoint_search +msgid "Model" +msgstr "" + +#. module: connector +#: model:ir.model.fields,field_description:connector.field_connector_backend_name +#: model:ir.model.fields,field_description:connector.field_test_backend_name +msgid "Name" +msgstr "" + +#. module: connector +#: model:ir.model.fields,help:connector.field_connector_checkpoint_name +msgid "Name of the record to review" +msgstr "" + +#. module: connector +#: selection:connector.checkpoint,state:0 +#: model:ir.ui.view,arch_db:connector.view_connector_checkpoint_search +msgid "Need Review" +msgstr "" + +#. module: connector +#: model:ir.actions.act_window,help:connector.action_connector_checkpoint +msgid "No record to check." +msgstr "" + +#. module: connector +#: model:ir.actions.client,name:connector.action_client_connector_menu +msgid "Open Connector Menu" +msgstr "" + +#. module: connector +#: model:ir.model,name:connector.model_queue_job +msgid "Queue Job" +msgstr "" + +#. module: connector +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_record +msgid "Record" +msgstr "" + +#. module: connector +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_record_id +msgid "Record ID" +msgstr "" + +#. module: connector +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_name +msgid "Record Name" +msgstr "" + +#. module: connector +#: code:addons/connector/models/queue_job.py:32 +#, python-format +msgid "Related Record" +msgstr "" + +#. module: connector +#: model:ir.actions.act_window,name:connector.action_connector_checkpoint_review +#: model:ir.ui.view,arch_db:connector.view_connector_checkpoint_review +msgid "Review Checkpoints" +msgstr "" + +#. module: connector +#: selection:connector.checkpoint,state:0 +#: model:ir.ui.view,arch_db:connector.view_connector_checkpoint_form +#: model:ir.ui.view,arch_db:connector.view_connector_checkpoint_search +#: model:ir.ui.view,arch_db:connector.view_connector_checkpoint_tree +msgid "Reviewed" +msgstr "" + +#. module: connector +#: model:ir.ui.view,arch_db:connector.view_connector_checkpoint_review +msgid "Set as reviewed" +msgstr "" + +#. module: connector +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_state +msgid "Status" +msgstr "" + +#. module: connector +#: model:ir.actions.act_window,help:connector.action_connector_checkpoint +msgid "" +"The connectors list the new records to verify\n" +" based on their type. Only some need a manual\n" +" review." +msgstr "" + +#. module: connector +#: model:ir.model.fields,help:connector.field_connector_checkpoint_backend_id +msgid "The record has been imported from this backend" +msgstr "" + +#. module: connector +#: model:ir.model.fields,help:connector.field_connector_checkpoint_record +msgid "The record to review." +msgstr "" + +#. module: connector +#: model:ir.ui.view,arch_db:connector.view_connector_checkpoint_review +msgid "The selected checkpoints will be set as reviewed." +msgstr "" + +#. module: connector +#: model:ir.model.fields,field_description:connector.field_connector_backend_version +msgid "Version" +msgstr "" + +#. module: connector +#: model:ir.actions.act_window,help:connector.action_connector_checkpoint +msgid "" +"When a connector imports new records which have\n" +" configuration or reviews to do manually, they\n" +" will appear in this list. Once a record has been\n" +" checked, click on the 'Reviewed' button." +msgstr "" + +#. module: connector +#: model:ir.model,name:connector.model_base +msgid "base" +msgstr "" + +#. module: connector +#: model:ir.ui.view,arch_db:connector.view_connector_checkpoint_review +#: model:ir.ui.view,arch_db:connector.view_connector_config_settings +msgid "or" +msgstr "" + +#. module: connector +#: model:ir.ui.view,arch_db:connector.view_connector_checkpoint_form +msgid "to verify it:" +msgstr "" diff --git a/ext/3rd-party-addons/connector/i18n/hr_HR.po b/ext/3rd-party-addons/connector/i18n/hr_HR.po new file mode 100644 index 00000000..36f2d2ca --- /dev/null +++ b/ext/3rd-party-addons/connector/i18n/hr_HR.po @@ -0,0 +1,317 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * connector +# +# Translators: +# OCA Transbot , 2017 +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server 10.0\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2017-03-10 03:36+0000\n" +"PO-Revision-Date: 2017-03-10 03:36+0000\n" +"Last-Translator: OCA Transbot , 2017\n" +"Language-Team: Croatian (Croatia) (https://www.transifex.com/oca/teams/23907/hr_HR/)\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: \n" +"Language: hr_HR\n" +"Plural-Forms: nplurals=3; plural=n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2;\n" + +#. module: connector +#: code:addons/connector/checkpoint/checkpoint.py:119 +#, python-format +msgid "A %s needs a review." +msgstr "%s potrebno je pregledati." + +#. module: connector +#: model:ir.ui.view,arch_db:connector.view_connector_config_settings +msgid "Apply" +msgstr "Primjeni" + +#. module: connector +#: model:ir.ui.view,arch_db:connector.view_connector_config_settings +msgid "Backends" +msgstr "" + +#. module: connector +#: model:ir.ui.view,arch_db:connector.view_connector_checkpoint_review +#: model:ir.ui.view,arch_db:connector.view_connector_config_settings +msgid "Cancel" +msgstr "" + +#. module: connector +#: model:ir.ui.menu,name:connector.menu_checkpoint +msgid "Checkpoint" +msgstr "" + +#. module: connector +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_review_checkpoint_ids +msgid "Checkpoints" +msgstr "" + +#. module: connector +#: model:ir.model,name:connector.model_connector_checkpoint_review +msgid "Checkpoints Review" +msgstr "" + +#. module: connector +#: model:ir.ui.view,arch_db:connector.view_connector_checkpoint_form +msgid "Click on the" +msgstr "" + +#. module: connector +#: model:ir.actions.act_window,name:connector.action_connector_config_settings +#: model:ir.ui.view,arch_db:connector.view_connector_config_settings +msgid "Configure Connector" +msgstr "" + +#. module: connector +#: model:ir.module.category,name:connector.module_category_connector +#: model:ir.ui.menu,name:connector.menu_connector_config_settings +msgid "Connector" +msgstr "" + +#. module: connector +#: model:ir.model,name:connector.model_connector_backend +msgid "Connector Backend" +msgstr "" + +#. module: connector +#: model:ir.actions.act_window,name:connector.action_connector_checkpoint +#: model:ir.model,name:connector.model_connector_checkpoint +#: model:ir.ui.view,arch_db:connector.view_connector_checkpoint_form +#: model:ir.ui.view,arch_db:connector.view_connector_checkpoint_search +#: model:ir.ui.view,arch_db:connector.view_connector_checkpoint_tree +msgid "Connector Checkpoint" +msgstr "" + +#. module: connector +#: model:ir.model,name:connector.model_connector_config_settings +msgid "Connector Configuration" +msgstr "" + +#. module: connector +#: model:res.groups,name:connector.group_connector_manager +msgid "Connector Manager" +msgstr "" + +#. module: connector +#: model:ir.ui.menu,name:connector.menu_connector +#: model:ir.ui.menu,name:connector.menu_connector_root +#: model:ir.ui.view,arch_db:connector.view_partner_connector_form +msgid "Connectors" +msgstr "" + +#. module: connector +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_create_uid +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_review_create_uid +#: model:ir.model.fields,field_description:connector.field_connector_config_settings_create_uid +msgid "Created by" +msgstr "" + +#. module: connector +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_create_date +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_review_create_date +#: model:ir.model.fields,field_description:connector.field_connector_config_settings_create_date +msgid "Created on" +msgstr "" + +#. module: connector +#: model:ir.model.fields,field_description:connector.field_connector_backend_display_name +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_display_name +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_review_display_name +#: model:ir.model.fields,field_description:connector.field_connector_config_settings_display_name +#: model:ir.model.fields,field_description:connector.field_external_binding_display_name +msgid "Display Name" +msgstr "" + +#. module: connector +#: model:ir.model,name:connector.model_external_binding +msgid "External Binding (abstract)" +msgstr "" + +#. module: connector +#: model:ir.ui.view,arch_db:connector.view_connector_checkpoint_search +msgid "Group By..." +msgstr "" + +#. module: connector +#: model:ir.model.fields,field_description:connector.field_connector_backend_id +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_id +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_review_id +#: model:ir.model.fields,field_description:connector.field_connector_config_settings_id +#: model:ir.model.fields,field_description:connector.field_external_binding_id +msgid "ID" +msgstr "" + +#. module: connector +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_backend_id +msgid "Imported from" +msgstr "" + +#. module: connector +#: model:ir.model.fields,field_description:connector.field_connector_backend___last_update +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint___last_update +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_review___last_update +#: model:ir.model.fields,field_description:connector.field_connector_config_settings___last_update +#: model:ir.model.fields,field_description:connector.field_external_binding___last_update +msgid "Last Modified on" +msgstr "" + +#. module: connector +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_review_write_uid +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_write_uid +#: model:ir.model.fields,field_description:connector.field_connector_config_settings_write_uid +msgid "Last Updated by" +msgstr "" + +#. module: connector +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_review_write_date +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_write_date +#: model:ir.model.fields,field_description:connector.field_connector_config_settings_write_date +msgid "Last Updated on" +msgstr "" + +#. module: connector +#: model:ir.model.fields,field_description:connector.field_connector_test_binding_sync_date +#: model:ir.model.fields,field_description:connector.field_external_binding_sync_date +#: model:ir.model.fields,field_description:connector.field_no_inherits_binding_sync_date +msgid "Last synchronization date" +msgstr "" + +#. module: connector +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_model_id +#: model:ir.ui.view,arch_db:connector.view_connector_checkpoint_search +msgid "Model" +msgstr "" + +#. module: connector +#: model:ir.model.fields,field_description:connector.field_connector_backend_name +#: model:ir.model.fields,field_description:connector.field_test_backend_name +msgid "Name" +msgstr "" + +#. module: connector +#: model:ir.model.fields,help:connector.field_connector_checkpoint_name +msgid "Name of the record to review" +msgstr "" + +#. module: connector +#: selection:connector.checkpoint,state:0 +#: model:ir.ui.view,arch_db:connector.view_connector_checkpoint_search +msgid "Need Review" +msgstr "" + +#. module: connector +#: model:ir.actions.act_window,help:connector.action_connector_checkpoint +msgid "No record to check." +msgstr "" + +#. module: connector +#: model:ir.actions.client,name:connector.action_client_connector_menu +msgid "Open Connector Menu" +msgstr "" + +#. module: connector +#: model:ir.model,name:connector.model_queue_job +msgid "Queue Job" +msgstr "" + +#. module: connector +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_record +msgid "Record" +msgstr "" + +#. module: connector +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_record_id +msgid "Record ID" +msgstr "" + +#. module: connector +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_name +msgid "Record Name" +msgstr "" + +#. module: connector +#: code:addons/connector/models/queue_job.py:32 +#, python-format +msgid "Related Record" +msgstr "" + +#. module: connector +#: model:ir.actions.act_window,name:connector.action_connector_checkpoint_review +#: model:ir.ui.view,arch_db:connector.view_connector_checkpoint_review +msgid "Review Checkpoints" +msgstr "" + +#. module: connector +#: selection:connector.checkpoint,state:0 +#: model:ir.ui.view,arch_db:connector.view_connector_checkpoint_form +#: model:ir.ui.view,arch_db:connector.view_connector_checkpoint_search +#: model:ir.ui.view,arch_db:connector.view_connector_checkpoint_tree +msgid "Reviewed" +msgstr "" + +#. module: connector +#: model:ir.ui.view,arch_db:connector.view_connector_checkpoint_review +msgid "Set as reviewed" +msgstr "" + +#. module: connector +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_state +msgid "Status" +msgstr "" + +#. module: connector +#: model:ir.actions.act_window,help:connector.action_connector_checkpoint +msgid "" +"The connectors list the new records to verify\n" +" based on their type. Only some need a manual\n" +" review." +msgstr "" + +#. module: connector +#: model:ir.model.fields,help:connector.field_connector_checkpoint_backend_id +msgid "The record has been imported from this backend" +msgstr "" + +#. module: connector +#: model:ir.model.fields,help:connector.field_connector_checkpoint_record +msgid "The record to review." +msgstr "" + +#. module: connector +#: model:ir.ui.view,arch_db:connector.view_connector_checkpoint_review +msgid "The selected checkpoints will be set as reviewed." +msgstr "" + +#. module: connector +#: model:ir.model.fields,field_description:connector.field_connector_backend_version +msgid "Version" +msgstr "" + +#. module: connector +#: model:ir.actions.act_window,help:connector.action_connector_checkpoint +msgid "" +"When a connector imports new records which have\n" +" configuration or reviews to do manually, they\n" +" will appear in this list. Once a record has been\n" +" checked, click on the 'Reviewed' button." +msgstr "" + +#. module: connector +#: model:ir.model,name:connector.model_base +msgid "base" +msgstr "" + +#. module: connector +#: model:ir.ui.view,arch_db:connector.view_connector_checkpoint_review +#: model:ir.ui.view,arch_db:connector.view_connector_config_settings +msgid "or" +msgstr "" + +#. module: connector +#: model:ir.ui.view,arch_db:connector.view_connector_checkpoint_form +msgid "to verify it:" +msgstr "" diff --git a/ext/3rd-party-addons/connector/i18n/hu.po b/ext/3rd-party-addons/connector/i18n/hu.po new file mode 100644 index 00000000..a05e7bd8 --- /dev/null +++ b/ext/3rd-party-addons/connector/i18n/hu.po @@ -0,0 +1,317 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * connector +# +# Translators: +# OCA Transbot , 2017 +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server 10.0\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2017-03-10 03:36+0000\n" +"PO-Revision-Date: 2017-03-10 03:36+0000\n" +"Last-Translator: OCA Transbot , 2017\n" +"Language-Team: Hungarian (https://www.transifex.com/oca/teams/23907/hu/)\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: \n" +"Language: hu\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" + +#. module: connector +#: code:addons/connector/checkpoint/checkpoint.py:119 +#, python-format +msgid "A %s needs a review." +msgstr "" + +#. module: connector +#: model:ir.ui.view,arch_db:connector.view_connector_config_settings +msgid "Apply" +msgstr "Alkalmaz" + +#. module: connector +#: model:ir.ui.view,arch_db:connector.view_connector_config_settings +msgid "Backends" +msgstr "Háttérprogramok" + +#. module: connector +#: model:ir.ui.view,arch_db:connector.view_connector_checkpoint_review +#: model:ir.ui.view,arch_db:connector.view_connector_config_settings +msgid "Cancel" +msgstr "Mégsem" + +#. module: connector +#: model:ir.ui.menu,name:connector.menu_checkpoint +msgid "Checkpoint" +msgstr "Ellenőrzőpont" + +#. module: connector +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_review_checkpoint_ids +msgid "Checkpoints" +msgstr "Ellenörző pontok" + +#. module: connector +#: model:ir.model,name:connector.model_connector_checkpoint_review +msgid "Checkpoints Review" +msgstr "Ellenörzőpontok felülvizsgálata" + +#. module: connector +#: model:ir.ui.view,arch_db:connector.view_connector_checkpoint_form +msgid "Click on the" +msgstr "Kattintson erre" + +#. module: connector +#: model:ir.actions.act_window,name:connector.action_connector_config_settings +#: model:ir.ui.view,arch_db:connector.view_connector_config_settings +msgid "Configure Connector" +msgstr "Csatlakozó beállítása" + +#. module: connector +#: model:ir.module.category,name:connector.module_category_connector +#: model:ir.ui.menu,name:connector.menu_connector_config_settings +msgid "Connector" +msgstr "Csatoló" + +#. module: connector +#: model:ir.model,name:connector.model_connector_backend +msgid "Connector Backend" +msgstr "" + +#. module: connector +#: model:ir.actions.act_window,name:connector.action_connector_checkpoint +#: model:ir.model,name:connector.model_connector_checkpoint +#: model:ir.ui.view,arch_db:connector.view_connector_checkpoint_form +#: model:ir.ui.view,arch_db:connector.view_connector_checkpoint_search +#: model:ir.ui.view,arch_db:connector.view_connector_checkpoint_tree +msgid "Connector Checkpoint" +msgstr "Csatoló ellenörzőpont" + +#. module: connector +#: model:ir.model,name:connector.model_connector_config_settings +msgid "Connector Configuration" +msgstr "" + +#. module: connector +#: model:res.groups,name:connector.group_connector_manager +msgid "Connector Manager" +msgstr "Csatoló beállítás" + +#. module: connector +#: model:ir.ui.menu,name:connector.menu_connector +#: model:ir.ui.menu,name:connector.menu_connector_root +#: model:ir.ui.view,arch_db:connector.view_partner_connector_form +msgid "Connectors" +msgstr "Csatolók" + +#. module: connector +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_create_uid +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_review_create_uid +#: model:ir.model.fields,field_description:connector.field_connector_config_settings_create_uid +msgid "Created by" +msgstr "" + +#. module: connector +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_create_date +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_review_create_date +#: model:ir.model.fields,field_description:connector.field_connector_config_settings_create_date +msgid "Created on" +msgstr "" + +#. module: connector +#: model:ir.model.fields,field_description:connector.field_connector_backend_display_name +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_display_name +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_review_display_name +#: model:ir.model.fields,field_description:connector.field_connector_config_settings_display_name +#: model:ir.model.fields,field_description:connector.field_external_binding_display_name +msgid "Display Name" +msgstr "" + +#. module: connector +#: model:ir.model,name:connector.model_external_binding +msgid "External Binding (abstract)" +msgstr "Külső csatolás (absztract)" + +#. module: connector +#: model:ir.ui.view,arch_db:connector.view_connector_checkpoint_search +msgid "Group By..." +msgstr "Csoportosítás ezzel..." + +#. module: connector +#: model:ir.model.fields,field_description:connector.field_connector_backend_id +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_id +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_review_id +#: model:ir.model.fields,field_description:connector.field_connector_config_settings_id +#: model:ir.model.fields,field_description:connector.field_external_binding_id +msgid "ID" +msgstr "" + +#. module: connector +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_backend_id +msgid "Imported from" +msgstr "Innen importált" + +#. module: connector +#: model:ir.model.fields,field_description:connector.field_connector_backend___last_update +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint___last_update +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_review___last_update +#: model:ir.model.fields,field_description:connector.field_connector_config_settings___last_update +#: model:ir.model.fields,field_description:connector.field_external_binding___last_update +msgid "Last Modified on" +msgstr "" + +#. module: connector +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_review_write_uid +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_write_uid +#: model:ir.model.fields,field_description:connector.field_connector_config_settings_write_uid +msgid "Last Updated by" +msgstr "" + +#. module: connector +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_review_write_date +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_write_date +#: model:ir.model.fields,field_description:connector.field_connector_config_settings_write_date +msgid "Last Updated on" +msgstr "" + +#. module: connector +#: model:ir.model.fields,field_description:connector.field_connector_test_binding_sync_date +#: model:ir.model.fields,field_description:connector.field_external_binding_sync_date +#: model:ir.model.fields,field_description:connector.field_no_inherits_binding_sync_date +msgid "Last synchronization date" +msgstr "Utolsó szinkronizáció dátuma" + +#. module: connector +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_model_id +#: model:ir.ui.view,arch_db:connector.view_connector_checkpoint_search +msgid "Model" +msgstr "Modell, minta" + +#. module: connector +#: model:ir.model.fields,field_description:connector.field_connector_backend_name +#: model:ir.model.fields,field_description:connector.field_test_backend_name +msgid "Name" +msgstr "Név" + +#. module: connector +#: model:ir.model.fields,help:connector.field_connector_checkpoint_name +msgid "Name of the record to review" +msgstr "" + +#. module: connector +#: selection:connector.checkpoint,state:0 +#: model:ir.ui.view,arch_db:connector.view_connector_checkpoint_search +msgid "Need Review" +msgstr "Felülvizsgálat szükséges" + +#. module: connector +#: model:ir.actions.act_window,help:connector.action_connector_checkpoint +msgid "No record to check." +msgstr "" + +#. module: connector +#: model:ir.actions.client,name:connector.action_client_connector_menu +msgid "Open Connector Menu" +msgstr "Csatoló menü megnyitása" + +#. module: connector +#: model:ir.model,name:connector.model_queue_job +msgid "Queue Job" +msgstr "Sorbanálló feladatok" + +#. module: connector +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_record +msgid "Record" +msgstr "" + +#. module: connector +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_record_id +msgid "Record ID" +msgstr "Rekordazonosító ID" + +#. module: connector +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_name +msgid "Record Name" +msgstr "" + +#. module: connector +#: code:addons/connector/models/queue_job.py:32 +#, python-format +msgid "Related Record" +msgstr "" + +#. module: connector +#: model:ir.actions.act_window,name:connector.action_connector_checkpoint_review +#: model:ir.ui.view,arch_db:connector.view_connector_checkpoint_review +msgid "Review Checkpoints" +msgstr "Ellenörzőpontok felülvizsgálata" + +#. module: connector +#: selection:connector.checkpoint,state:0 +#: model:ir.ui.view,arch_db:connector.view_connector_checkpoint_form +#: model:ir.ui.view,arch_db:connector.view_connector_checkpoint_search +#: model:ir.ui.view,arch_db:connector.view_connector_checkpoint_tree +msgid "Reviewed" +msgstr "Leellenörzött" + +#. module: connector +#: model:ir.ui.view,arch_db:connector.view_connector_checkpoint_review +msgid "Set as reviewed" +msgstr "Leellenörzöttnek jelölt" + +#. module: connector +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_state +msgid "Status" +msgstr "Állapot" + +#. module: connector +#: model:ir.actions.act_window,help:connector.action_connector_checkpoint +msgid "" +"The connectors list the new records to verify\n" +" based on their type. Only some need a manual\n" +" review." +msgstr "" + +#. module: connector +#: model:ir.model.fields,help:connector.field_connector_checkpoint_backend_id +msgid "The record has been imported from this backend" +msgstr "Erről a végpontról importált rekord" + +#. module: connector +#: model:ir.model.fields,help:connector.field_connector_checkpoint_record +msgid "The record to review." +msgstr "" + +#. module: connector +#: model:ir.ui.view,arch_db:connector.view_connector_checkpoint_review +msgid "The selected checkpoints will be set as reviewed." +msgstr "A kiválasztott ellenörzőpont leellenörzőttként nyilvántartva." + +#. module: connector +#: model:ir.model.fields,field_description:connector.field_connector_backend_version +msgid "Version" +msgstr "Verzió" + +#. module: connector +#: model:ir.actions.act_window,help:connector.action_connector_checkpoint +msgid "" +"When a connector imports new records which have\n" +" configuration or reviews to do manually, they\n" +" will appear in this list. Once a record has been\n" +" checked, click on the 'Reviewed' button." +msgstr "" + +#. module: connector +#: model:ir.model,name:connector.model_base +msgid "base" +msgstr "" + +#. module: connector +#: model:ir.ui.view,arch_db:connector.view_connector_checkpoint_review +#: model:ir.ui.view,arch_db:connector.view_connector_config_settings +msgid "or" +msgstr "vagy" + +#. module: connector +#: model:ir.ui.view,arch_db:connector.view_connector_checkpoint_form +msgid "to verify it:" +msgstr "ezt ellenőrizni:" diff --git a/ext/3rd-party-addons/connector/i18n/it.po b/ext/3rd-party-addons/connector/i18n/it.po new file mode 100644 index 00000000..7f289793 --- /dev/null +++ b/ext/3rd-party-addons/connector/i18n/it.po @@ -0,0 +1,317 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * connector +# +# Translators: +# OCA Transbot , 2017 +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server 10.0\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2017-03-10 03:36+0000\n" +"PO-Revision-Date: 2017-03-10 03:36+0000\n" +"Last-Translator: OCA Transbot , 2017\n" +"Language-Team: Italian (https://www.transifex.com/oca/teams/23907/it/)\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: \n" +"Language: it\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" + +#. module: connector +#: code:addons/connector/checkpoint/checkpoint.py:119 +#, python-format +msgid "A %s needs a review." +msgstr "" + +#. module: connector +#: model:ir.ui.view,arch_db:connector.view_connector_config_settings +msgid "Apply" +msgstr "Applica" + +#. module: connector +#: model:ir.ui.view,arch_db:connector.view_connector_config_settings +msgid "Backends" +msgstr "Backends" + +#. module: connector +#: model:ir.ui.view,arch_db:connector.view_connector_checkpoint_review +#: model:ir.ui.view,arch_db:connector.view_connector_config_settings +msgid "Cancel" +msgstr "Annulla" + +#. module: connector +#: model:ir.ui.menu,name:connector.menu_checkpoint +msgid "Checkpoint" +msgstr "" + +#. module: connector +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_review_checkpoint_ids +msgid "Checkpoints" +msgstr "Checkpoints" + +#. module: connector +#: model:ir.model,name:connector.model_connector_checkpoint_review +msgid "Checkpoints Review" +msgstr "Revisione Checkpoints" + +#. module: connector +#: model:ir.ui.view,arch_db:connector.view_connector_checkpoint_form +msgid "Click on the" +msgstr "" + +#. module: connector +#: model:ir.actions.act_window,name:connector.action_connector_config_settings +#: model:ir.ui.view,arch_db:connector.view_connector_config_settings +msgid "Configure Connector" +msgstr "Configura Connettore" + +#. module: connector +#: model:ir.module.category,name:connector.module_category_connector +#: model:ir.ui.menu,name:connector.menu_connector_config_settings +msgid "Connector" +msgstr "Connettore" + +#. module: connector +#: model:ir.model,name:connector.model_connector_backend +msgid "Connector Backend" +msgstr "" + +#. module: connector +#: model:ir.actions.act_window,name:connector.action_connector_checkpoint +#: model:ir.model,name:connector.model_connector_checkpoint +#: model:ir.ui.view,arch_db:connector.view_connector_checkpoint_form +#: model:ir.ui.view,arch_db:connector.view_connector_checkpoint_search +#: model:ir.ui.view,arch_db:connector.view_connector_checkpoint_tree +msgid "Connector Checkpoint" +msgstr "Checkpoint Connettore" + +#. module: connector +#: model:ir.model,name:connector.model_connector_config_settings +msgid "Connector Configuration" +msgstr "" + +#. module: connector +#: model:res.groups,name:connector.group_connector_manager +msgid "Connector Manager" +msgstr "" + +#. module: connector +#: model:ir.ui.menu,name:connector.menu_connector +#: model:ir.ui.menu,name:connector.menu_connector_root +#: model:ir.ui.view,arch_db:connector.view_partner_connector_form +msgid "Connectors" +msgstr "Connettori" + +#. module: connector +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_create_uid +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_review_create_uid +#: model:ir.model.fields,field_description:connector.field_connector_config_settings_create_uid +msgid "Created by" +msgstr "Creato da" + +#. module: connector +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_create_date +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_review_create_date +#: model:ir.model.fields,field_description:connector.field_connector_config_settings_create_date +msgid "Created on" +msgstr "Creato il" + +#. module: connector +#: model:ir.model.fields,field_description:connector.field_connector_backend_display_name +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_display_name +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_review_display_name +#: model:ir.model.fields,field_description:connector.field_connector_config_settings_display_name +#: model:ir.model.fields,field_description:connector.field_external_binding_display_name +msgid "Display Name" +msgstr "Nome da visualizzare" + +#. module: connector +#: model:ir.model,name:connector.model_external_binding +msgid "External Binding (abstract)" +msgstr "" + +#. module: connector +#: model:ir.ui.view,arch_db:connector.view_connector_checkpoint_search +msgid "Group By..." +msgstr "Raggruppa per..." + +#. module: connector +#: model:ir.model.fields,field_description:connector.field_connector_backend_id +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_id +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_review_id +#: model:ir.model.fields,field_description:connector.field_connector_config_settings_id +#: model:ir.model.fields,field_description:connector.field_external_binding_id +msgid "ID" +msgstr "ID" + +#. module: connector +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_backend_id +msgid "Imported from" +msgstr "Importato da" + +#. module: connector +#: model:ir.model.fields,field_description:connector.field_connector_backend___last_update +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint___last_update +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_review___last_update +#: model:ir.model.fields,field_description:connector.field_connector_config_settings___last_update +#: model:ir.model.fields,field_description:connector.field_external_binding___last_update +msgid "Last Modified on" +msgstr "Ultima modifica il" + +#. module: connector +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_review_write_uid +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_write_uid +#: model:ir.model.fields,field_description:connector.field_connector_config_settings_write_uid +msgid "Last Updated by" +msgstr "Ultimo aggiornamento di" + +#. module: connector +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_review_write_date +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_write_date +#: model:ir.model.fields,field_description:connector.field_connector_config_settings_write_date +msgid "Last Updated on" +msgstr "Ultimo aggiornamento il" + +#. module: connector +#: model:ir.model.fields,field_description:connector.field_connector_test_binding_sync_date +#: model:ir.model.fields,field_description:connector.field_external_binding_sync_date +#: model:ir.model.fields,field_description:connector.field_no_inherits_binding_sync_date +msgid "Last synchronization date" +msgstr "Data ultima sincronizzazione" + +#. module: connector +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_model_id +#: model:ir.ui.view,arch_db:connector.view_connector_checkpoint_search +msgid "Model" +msgstr "" + +#. module: connector +#: model:ir.model.fields,field_description:connector.field_connector_backend_name +#: model:ir.model.fields,field_description:connector.field_test_backend_name +msgid "Name" +msgstr "" + +#. module: connector +#: model:ir.model.fields,help:connector.field_connector_checkpoint_name +msgid "Name of the record to review" +msgstr "" + +#. module: connector +#: selection:connector.checkpoint,state:0 +#: model:ir.ui.view,arch_db:connector.view_connector_checkpoint_search +msgid "Need Review" +msgstr "" + +#. module: connector +#: model:ir.actions.act_window,help:connector.action_connector_checkpoint +msgid "No record to check." +msgstr "" + +#. module: connector +#: model:ir.actions.client,name:connector.action_client_connector_menu +msgid "Open Connector Menu" +msgstr "Apre il menù del Connettore" + +#. module: connector +#: model:ir.model,name:connector.model_queue_job +msgid "Queue Job" +msgstr "Coda Job" + +#. module: connector +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_record +msgid "Record" +msgstr "" + +#. module: connector +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_record_id +msgid "Record ID" +msgstr "" + +#. module: connector +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_name +msgid "Record Name" +msgstr "" + +#. module: connector +#: code:addons/connector/models/queue_job.py:32 +#, python-format +msgid "Related Record" +msgstr "" + +#. module: connector +#: model:ir.actions.act_window,name:connector.action_connector_checkpoint_review +#: model:ir.ui.view,arch_db:connector.view_connector_checkpoint_review +msgid "Review Checkpoints" +msgstr "" + +#. module: connector +#: selection:connector.checkpoint,state:0 +#: model:ir.ui.view,arch_db:connector.view_connector_checkpoint_form +#: model:ir.ui.view,arch_db:connector.view_connector_checkpoint_search +#: model:ir.ui.view,arch_db:connector.view_connector_checkpoint_tree +msgid "Reviewed" +msgstr "" + +#. module: connector +#: model:ir.ui.view,arch_db:connector.view_connector_checkpoint_review +msgid "Set as reviewed" +msgstr "Imposta come revisionato" + +#. module: connector +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_state +msgid "Status" +msgstr "" + +#. module: connector +#: model:ir.actions.act_window,help:connector.action_connector_checkpoint +msgid "" +"The connectors list the new records to verify\n" +" based on their type. Only some need a manual\n" +" review." +msgstr "" + +#. module: connector +#: model:ir.model.fields,help:connector.field_connector_checkpoint_backend_id +msgid "The record has been imported from this backend" +msgstr "Il record è stato importato da questo backend" + +#. module: connector +#: model:ir.model.fields,help:connector.field_connector_checkpoint_record +msgid "The record to review." +msgstr "" + +#. module: connector +#: model:ir.ui.view,arch_db:connector.view_connector_checkpoint_review +msgid "The selected checkpoints will be set as reviewed." +msgstr "" + +#. module: connector +#: model:ir.model.fields,field_description:connector.field_connector_backend_version +msgid "Version" +msgstr "" + +#. module: connector +#: model:ir.actions.act_window,help:connector.action_connector_checkpoint +msgid "" +"When a connector imports new records which have\n" +" configuration or reviews to do manually, they\n" +" will appear in this list. Once a record has been\n" +" checked, click on the 'Reviewed' button." +msgstr "" + +#. module: connector +#: model:ir.model,name:connector.model_base +msgid "base" +msgstr "" + +#. module: connector +#: model:ir.ui.view,arch_db:connector.view_connector_checkpoint_review +#: model:ir.ui.view,arch_db:connector.view_connector_config_settings +msgid "or" +msgstr "o" + +#. module: connector +#: model:ir.ui.view,arch_db:connector.view_connector_checkpoint_form +msgid "to verify it:" +msgstr "" diff --git a/ext/3rd-party-addons/connector/i18n/lt.po b/ext/3rd-party-addons/connector/i18n/lt.po new file mode 100644 index 00000000..8d2f2dd8 --- /dev/null +++ b/ext/3rd-party-addons/connector/i18n/lt.po @@ -0,0 +1,317 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * connector +# +# Translators: +# OCA Transbot , 2017 +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server 10.0\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2017-03-10 03:36+0000\n" +"PO-Revision-Date: 2017-03-10 03:36+0000\n" +"Last-Translator: OCA Transbot , 2017\n" +"Language-Team: Lithuanian (https://www.transifex.com/oca/teams/23907/lt/)\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: \n" +"Language: lt\n" +"Plural-Forms: nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && (n%100<10 || n%100>=20) ? 1 : 2);\n" + +#. module: connector +#: code:addons/connector/checkpoint/checkpoint.py:119 +#, python-format +msgid "A %s needs a review." +msgstr "" + +#. module: connector +#: model:ir.ui.view,arch_db:connector.view_connector_config_settings +msgid "Apply" +msgstr "" + +#. module: connector +#: model:ir.ui.view,arch_db:connector.view_connector_config_settings +msgid "Backends" +msgstr "" + +#. module: connector +#: model:ir.ui.view,arch_db:connector.view_connector_checkpoint_review +#: model:ir.ui.view,arch_db:connector.view_connector_config_settings +msgid "Cancel" +msgstr "Atšaukti" + +#. module: connector +#: model:ir.ui.menu,name:connector.menu_checkpoint +msgid "Checkpoint" +msgstr "" + +#. module: connector +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_review_checkpoint_ids +msgid "Checkpoints" +msgstr "" + +#. module: connector +#: model:ir.model,name:connector.model_connector_checkpoint_review +msgid "Checkpoints Review" +msgstr "" + +#. module: connector +#: model:ir.ui.view,arch_db:connector.view_connector_checkpoint_form +msgid "Click on the" +msgstr "" + +#. module: connector +#: model:ir.actions.act_window,name:connector.action_connector_config_settings +#: model:ir.ui.view,arch_db:connector.view_connector_config_settings +msgid "Configure Connector" +msgstr "" + +#. module: connector +#: model:ir.module.category,name:connector.module_category_connector +#: model:ir.ui.menu,name:connector.menu_connector_config_settings +msgid "Connector" +msgstr "" + +#. module: connector +#: model:ir.model,name:connector.model_connector_backend +msgid "Connector Backend" +msgstr "" + +#. module: connector +#: model:ir.actions.act_window,name:connector.action_connector_checkpoint +#: model:ir.model,name:connector.model_connector_checkpoint +#: model:ir.ui.view,arch_db:connector.view_connector_checkpoint_form +#: model:ir.ui.view,arch_db:connector.view_connector_checkpoint_search +#: model:ir.ui.view,arch_db:connector.view_connector_checkpoint_tree +msgid "Connector Checkpoint" +msgstr "" + +#. module: connector +#: model:ir.model,name:connector.model_connector_config_settings +msgid "Connector Configuration" +msgstr "" + +#. module: connector +#: model:res.groups,name:connector.group_connector_manager +msgid "Connector Manager" +msgstr "" + +#. module: connector +#: model:ir.ui.menu,name:connector.menu_connector +#: model:ir.ui.menu,name:connector.menu_connector_root +#: model:ir.ui.view,arch_db:connector.view_partner_connector_form +msgid "Connectors" +msgstr "" + +#. module: connector +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_create_uid +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_review_create_uid +#: model:ir.model.fields,field_description:connector.field_connector_config_settings_create_uid +msgid "Created by" +msgstr "" + +#. module: connector +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_create_date +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_review_create_date +#: model:ir.model.fields,field_description:connector.field_connector_config_settings_create_date +msgid "Created on" +msgstr "" + +#. module: connector +#: model:ir.model.fields,field_description:connector.field_connector_backend_display_name +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_display_name +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_review_display_name +#: model:ir.model.fields,field_description:connector.field_connector_config_settings_display_name +#: model:ir.model.fields,field_description:connector.field_external_binding_display_name +msgid "Display Name" +msgstr "" + +#. module: connector +#: model:ir.model,name:connector.model_external_binding +msgid "External Binding (abstract)" +msgstr "" + +#. module: connector +#: model:ir.ui.view,arch_db:connector.view_connector_checkpoint_search +msgid "Group By..." +msgstr "" + +#. module: connector +#: model:ir.model.fields,field_description:connector.field_connector_backend_id +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_id +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_review_id +#: model:ir.model.fields,field_description:connector.field_connector_config_settings_id +#: model:ir.model.fields,field_description:connector.field_external_binding_id +msgid "ID" +msgstr "" + +#. module: connector +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_backend_id +msgid "Imported from" +msgstr "" + +#. module: connector +#: model:ir.model.fields,field_description:connector.field_connector_backend___last_update +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint___last_update +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_review___last_update +#: model:ir.model.fields,field_description:connector.field_connector_config_settings___last_update +#: model:ir.model.fields,field_description:connector.field_external_binding___last_update +msgid "Last Modified on" +msgstr "" + +#. module: connector +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_review_write_uid +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_write_uid +#: model:ir.model.fields,field_description:connector.field_connector_config_settings_write_uid +msgid "Last Updated by" +msgstr "" + +#. module: connector +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_review_write_date +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_write_date +#: model:ir.model.fields,field_description:connector.field_connector_config_settings_write_date +msgid "Last Updated on" +msgstr "" + +#. module: connector +#: model:ir.model.fields,field_description:connector.field_connector_test_binding_sync_date +#: model:ir.model.fields,field_description:connector.field_external_binding_sync_date +#: model:ir.model.fields,field_description:connector.field_no_inherits_binding_sync_date +msgid "Last synchronization date" +msgstr "" + +#. module: connector +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_model_id +#: model:ir.ui.view,arch_db:connector.view_connector_checkpoint_search +msgid "Model" +msgstr "" + +#. module: connector +#: model:ir.model.fields,field_description:connector.field_connector_backend_name +#: model:ir.model.fields,field_description:connector.field_test_backend_name +msgid "Name" +msgstr "" + +#. module: connector +#: model:ir.model.fields,help:connector.field_connector_checkpoint_name +msgid "Name of the record to review" +msgstr "" + +#. module: connector +#: selection:connector.checkpoint,state:0 +#: model:ir.ui.view,arch_db:connector.view_connector_checkpoint_search +msgid "Need Review" +msgstr "" + +#. module: connector +#: model:ir.actions.act_window,help:connector.action_connector_checkpoint +msgid "No record to check." +msgstr "" + +#. module: connector +#: model:ir.actions.client,name:connector.action_client_connector_menu +msgid "Open Connector Menu" +msgstr "" + +#. module: connector +#: model:ir.model,name:connector.model_queue_job +msgid "Queue Job" +msgstr "" + +#. module: connector +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_record +msgid "Record" +msgstr "" + +#. module: connector +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_record_id +msgid "Record ID" +msgstr "" + +#. module: connector +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_name +msgid "Record Name" +msgstr "" + +#. module: connector +#: code:addons/connector/models/queue_job.py:32 +#, python-format +msgid "Related Record" +msgstr "" + +#. module: connector +#: model:ir.actions.act_window,name:connector.action_connector_checkpoint_review +#: model:ir.ui.view,arch_db:connector.view_connector_checkpoint_review +msgid "Review Checkpoints" +msgstr "" + +#. module: connector +#: selection:connector.checkpoint,state:0 +#: model:ir.ui.view,arch_db:connector.view_connector_checkpoint_form +#: model:ir.ui.view,arch_db:connector.view_connector_checkpoint_search +#: model:ir.ui.view,arch_db:connector.view_connector_checkpoint_tree +msgid "Reviewed" +msgstr "" + +#. module: connector +#: model:ir.ui.view,arch_db:connector.view_connector_checkpoint_review +msgid "Set as reviewed" +msgstr "" + +#. module: connector +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_state +msgid "Status" +msgstr "" + +#. module: connector +#: model:ir.actions.act_window,help:connector.action_connector_checkpoint +msgid "" +"The connectors list the new records to verify\n" +" based on their type. Only some need a manual\n" +" review." +msgstr "" + +#. module: connector +#: model:ir.model.fields,help:connector.field_connector_checkpoint_backend_id +msgid "The record has been imported from this backend" +msgstr "" + +#. module: connector +#: model:ir.model.fields,help:connector.field_connector_checkpoint_record +msgid "The record to review." +msgstr "" + +#. module: connector +#: model:ir.ui.view,arch_db:connector.view_connector_checkpoint_review +msgid "The selected checkpoints will be set as reviewed." +msgstr "" + +#. module: connector +#: model:ir.model.fields,field_description:connector.field_connector_backend_version +msgid "Version" +msgstr "" + +#. module: connector +#: model:ir.actions.act_window,help:connector.action_connector_checkpoint +msgid "" +"When a connector imports new records which have\n" +" configuration or reviews to do manually, they\n" +" will appear in this list. Once a record has been\n" +" checked, click on the 'Reviewed' button." +msgstr "" + +#. module: connector +#: model:ir.model,name:connector.model_base +msgid "base" +msgstr "" + +#. module: connector +#: model:ir.ui.view,arch_db:connector.view_connector_checkpoint_review +#: model:ir.ui.view,arch_db:connector.view_connector_config_settings +msgid "or" +msgstr "" + +#. module: connector +#: model:ir.ui.view,arch_db:connector.view_connector_checkpoint_form +msgid "to verify it:" +msgstr "" diff --git a/ext/3rd-party-addons/connector/i18n/nl.po b/ext/3rd-party-addons/connector/i18n/nl.po new file mode 100644 index 00000000..18c6d07c --- /dev/null +++ b/ext/3rd-party-addons/connector/i18n/nl.po @@ -0,0 +1,317 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * connector +# +# Translators: +# OCA Transbot , 2017 +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server 10.0\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2017-03-10 03:36+0000\n" +"PO-Revision-Date: 2017-03-10 03:36+0000\n" +"Last-Translator: OCA Transbot , 2017\n" +"Language-Team: Dutch (https://www.transifex.com/oca/teams/23907/nl/)\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: \n" +"Language: nl\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" + +#. module: connector +#: code:addons/connector/checkpoint/checkpoint.py:119 +#, python-format +msgid "A %s needs a review." +msgstr "" + +#. module: connector +#: model:ir.ui.view,arch_db:connector.view_connector_config_settings +msgid "Apply" +msgstr "Toepassen" + +#. module: connector +#: model:ir.ui.view,arch_db:connector.view_connector_config_settings +msgid "Backends" +msgstr "Backends" + +#. module: connector +#: model:ir.ui.view,arch_db:connector.view_connector_checkpoint_review +#: model:ir.ui.view,arch_db:connector.view_connector_config_settings +msgid "Cancel" +msgstr "Annuleer" + +#. module: connector +#: model:ir.ui.menu,name:connector.menu_checkpoint +msgid "Checkpoint" +msgstr "Controlepunt" + +#. module: connector +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_review_checkpoint_ids +msgid "Checkpoints" +msgstr "Controlepunten" + +#. module: connector +#: model:ir.model,name:connector.model_connector_checkpoint_review +msgid "Checkpoints Review" +msgstr "Controlepunten controle" + +#. module: connector +#: model:ir.ui.view,arch_db:connector.view_connector_checkpoint_form +msgid "Click on the" +msgstr "Klik op de" + +#. module: connector +#: model:ir.actions.act_window,name:connector.action_connector_config_settings +#: model:ir.ui.view,arch_db:connector.view_connector_config_settings +msgid "Configure Connector" +msgstr "Connector instellen" + +#. module: connector +#: model:ir.module.category,name:connector.module_category_connector +#: model:ir.ui.menu,name:connector.menu_connector_config_settings +msgid "Connector" +msgstr "Connector" + +#. module: connector +#: model:ir.model,name:connector.model_connector_backend +msgid "Connector Backend" +msgstr "" + +#. module: connector +#: model:ir.actions.act_window,name:connector.action_connector_checkpoint +#: model:ir.model,name:connector.model_connector_checkpoint +#: model:ir.ui.view,arch_db:connector.view_connector_checkpoint_form +#: model:ir.ui.view,arch_db:connector.view_connector_checkpoint_search +#: model:ir.ui.view,arch_db:connector.view_connector_checkpoint_tree +msgid "Connector Checkpoint" +msgstr "Connector controlepunt" + +#. module: connector +#: model:ir.model,name:connector.model_connector_config_settings +msgid "Connector Configuration" +msgstr "" + +#. module: connector +#: model:res.groups,name:connector.group_connector_manager +msgid "Connector Manager" +msgstr "Connector manager" + +#. module: connector +#: model:ir.ui.menu,name:connector.menu_connector +#: model:ir.ui.menu,name:connector.menu_connector_root +#: model:ir.ui.view,arch_db:connector.view_partner_connector_form +msgid "Connectors" +msgstr "Connectors" + +#. module: connector +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_create_uid +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_review_create_uid +#: model:ir.model.fields,field_description:connector.field_connector_config_settings_create_uid +msgid "Created by" +msgstr "" + +#. module: connector +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_create_date +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_review_create_date +#: model:ir.model.fields,field_description:connector.field_connector_config_settings_create_date +msgid "Created on" +msgstr "" + +#. module: connector +#: model:ir.model.fields,field_description:connector.field_connector_backend_display_name +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_display_name +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_review_display_name +#: model:ir.model.fields,field_description:connector.field_connector_config_settings_display_name +#: model:ir.model.fields,field_description:connector.field_external_binding_display_name +msgid "Display Name" +msgstr "" + +#. module: connector +#: model:ir.model,name:connector.model_external_binding +msgid "External Binding (abstract)" +msgstr "External Binding (abstract)" + +#. module: connector +#: model:ir.ui.view,arch_db:connector.view_connector_checkpoint_search +msgid "Group By..." +msgstr "Groepeer op..." + +#. module: connector +#: model:ir.model.fields,field_description:connector.field_connector_backend_id +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_id +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_review_id +#: model:ir.model.fields,field_description:connector.field_connector_config_settings_id +#: model:ir.model.fields,field_description:connector.field_external_binding_id +msgid "ID" +msgstr "" + +#. module: connector +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_backend_id +msgid "Imported from" +msgstr "Geïmporteerd van" + +#. module: connector +#: model:ir.model.fields,field_description:connector.field_connector_backend___last_update +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint___last_update +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_review___last_update +#: model:ir.model.fields,field_description:connector.field_connector_config_settings___last_update +#: model:ir.model.fields,field_description:connector.field_external_binding___last_update +msgid "Last Modified on" +msgstr "" + +#. module: connector +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_review_write_uid +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_write_uid +#: model:ir.model.fields,field_description:connector.field_connector_config_settings_write_uid +msgid "Last Updated by" +msgstr "" + +#. module: connector +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_review_write_date +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_write_date +#: model:ir.model.fields,field_description:connector.field_connector_config_settings_write_date +msgid "Last Updated on" +msgstr "" + +#. module: connector +#: model:ir.model.fields,field_description:connector.field_connector_test_binding_sync_date +#: model:ir.model.fields,field_description:connector.field_external_binding_sync_date +#: model:ir.model.fields,field_description:connector.field_no_inherits_binding_sync_date +msgid "Last synchronization date" +msgstr "Laatste synchronisatie datum" + +#. module: connector +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_model_id +#: model:ir.ui.view,arch_db:connector.view_connector_checkpoint_search +msgid "Model" +msgstr "Model" + +#. module: connector +#: model:ir.model.fields,field_description:connector.field_connector_backend_name +#: model:ir.model.fields,field_description:connector.field_test_backend_name +msgid "Name" +msgstr "Naam" + +#. module: connector +#: model:ir.model.fields,help:connector.field_connector_checkpoint_name +msgid "Name of the record to review" +msgstr "" + +#. module: connector +#: selection:connector.checkpoint,state:0 +#: model:ir.ui.view,arch_db:connector.view_connector_checkpoint_search +msgid "Need Review" +msgstr "Controle nodig" + +#. module: connector +#: model:ir.actions.act_window,help:connector.action_connector_checkpoint +msgid "No record to check." +msgstr "" + +#. module: connector +#: model:ir.actions.client,name:connector.action_client_connector_menu +msgid "Open Connector Menu" +msgstr "Open connector menu" + +#. module: connector +#: model:ir.model,name:connector.model_queue_job +msgid "Queue Job" +msgstr "Geplande taken" + +#. module: connector +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_record +msgid "Record" +msgstr "" + +#. module: connector +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_record_id +msgid "Record ID" +msgstr "Record-id" + +#. module: connector +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_name +msgid "Record Name" +msgstr "" + +#. module: connector +#: code:addons/connector/models/queue_job.py:32 +#, python-format +msgid "Related Record" +msgstr "" + +#. module: connector +#: model:ir.actions.act_window,name:connector.action_connector_checkpoint_review +#: model:ir.ui.view,arch_db:connector.view_connector_checkpoint_review +msgid "Review Checkpoints" +msgstr "Controleer controlepunten" + +#. module: connector +#: selection:connector.checkpoint,state:0 +#: model:ir.ui.view,arch_db:connector.view_connector_checkpoint_form +#: model:ir.ui.view,arch_db:connector.view_connector_checkpoint_search +#: model:ir.ui.view,arch_db:connector.view_connector_checkpoint_tree +msgid "Reviewed" +msgstr "Gecontroleerd" + +#. module: connector +#: model:ir.ui.view,arch_db:connector.view_connector_checkpoint_review +msgid "Set as reviewed" +msgstr "Stel in als gecontroleerd" + +#. module: connector +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_state +msgid "Status" +msgstr "Status" + +#. module: connector +#: model:ir.actions.act_window,help:connector.action_connector_checkpoint +msgid "" +"The connectors list the new records to verify\n" +" based on their type. Only some need a manual\n" +" review." +msgstr "" + +#. module: connector +#: model:ir.model.fields,help:connector.field_connector_checkpoint_backend_id +msgid "The record has been imported from this backend" +msgstr "De regel is geïmporteerd vanuit deze backend" + +#. module: connector +#: model:ir.model.fields,help:connector.field_connector_checkpoint_record +msgid "The record to review." +msgstr "" + +#. module: connector +#: model:ir.ui.view,arch_db:connector.view_connector_checkpoint_review +msgid "The selected checkpoints will be set as reviewed." +msgstr "De geselecteerde controlepunten worden ingesteld als gecontroleerd" + +#. module: connector +#: model:ir.model.fields,field_description:connector.field_connector_backend_version +msgid "Version" +msgstr "Versie" + +#. module: connector +#: model:ir.actions.act_window,help:connector.action_connector_checkpoint +msgid "" +"When a connector imports new records which have\n" +" configuration or reviews to do manually, they\n" +" will appear in this list. Once a record has been\n" +" checked, click on the 'Reviewed' button." +msgstr "" + +#. module: connector +#: model:ir.model,name:connector.model_base +msgid "base" +msgstr "" + +#. module: connector +#: model:ir.ui.view,arch_db:connector.view_connector_checkpoint_review +#: model:ir.ui.view,arch_db:connector.view_connector_config_settings +msgid "or" +msgstr "of" + +#. module: connector +#: model:ir.ui.view,arch_db:connector.view_connector_checkpoint_form +msgid "to verify it:" +msgstr "om te controleren:" diff --git a/ext/3rd-party-addons/connector/i18n/nl_BE.po b/ext/3rd-party-addons/connector/i18n/nl_BE.po new file mode 100644 index 00000000..9bc77480 --- /dev/null +++ b/ext/3rd-party-addons/connector/i18n/nl_BE.po @@ -0,0 +1,317 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * connector +# +# Translators: +# OCA Transbot , 2017 +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server 10.0\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2017-03-10 03:36+0000\n" +"PO-Revision-Date: 2017-03-10 03:36+0000\n" +"Last-Translator: OCA Transbot , 2017\n" +"Language-Team: Dutch (Belgium) (https://www.transifex.com/oca/teams/23907/nl_BE/)\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: \n" +"Language: nl_BE\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" + +#. module: connector +#: code:addons/connector/checkpoint/checkpoint.py:119 +#, python-format +msgid "A %s needs a review." +msgstr "" + +#. module: connector +#: model:ir.ui.view,arch_db:connector.view_connector_config_settings +msgid "Apply" +msgstr "" + +#. module: connector +#: model:ir.ui.view,arch_db:connector.view_connector_config_settings +msgid "Backends" +msgstr "" + +#. module: connector +#: model:ir.ui.view,arch_db:connector.view_connector_checkpoint_review +#: model:ir.ui.view,arch_db:connector.view_connector_config_settings +msgid "Cancel" +msgstr "Annuleren" + +#. module: connector +#: model:ir.ui.menu,name:connector.menu_checkpoint +msgid "Checkpoint" +msgstr "" + +#. module: connector +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_review_checkpoint_ids +msgid "Checkpoints" +msgstr "" + +#. module: connector +#: model:ir.model,name:connector.model_connector_checkpoint_review +msgid "Checkpoints Review" +msgstr "" + +#. module: connector +#: model:ir.ui.view,arch_db:connector.view_connector_checkpoint_form +msgid "Click on the" +msgstr "" + +#. module: connector +#: model:ir.actions.act_window,name:connector.action_connector_config_settings +#: model:ir.ui.view,arch_db:connector.view_connector_config_settings +msgid "Configure Connector" +msgstr "" + +#. module: connector +#: model:ir.module.category,name:connector.module_category_connector +#: model:ir.ui.menu,name:connector.menu_connector_config_settings +msgid "Connector" +msgstr "" + +#. module: connector +#: model:ir.model,name:connector.model_connector_backend +msgid "Connector Backend" +msgstr "" + +#. module: connector +#: model:ir.actions.act_window,name:connector.action_connector_checkpoint +#: model:ir.model,name:connector.model_connector_checkpoint +#: model:ir.ui.view,arch_db:connector.view_connector_checkpoint_form +#: model:ir.ui.view,arch_db:connector.view_connector_checkpoint_search +#: model:ir.ui.view,arch_db:connector.view_connector_checkpoint_tree +msgid "Connector Checkpoint" +msgstr "" + +#. module: connector +#: model:ir.model,name:connector.model_connector_config_settings +msgid "Connector Configuration" +msgstr "" + +#. module: connector +#: model:res.groups,name:connector.group_connector_manager +msgid "Connector Manager" +msgstr "" + +#. module: connector +#: model:ir.ui.menu,name:connector.menu_connector +#: model:ir.ui.menu,name:connector.menu_connector_root +#: model:ir.ui.view,arch_db:connector.view_partner_connector_form +msgid "Connectors" +msgstr "" + +#. module: connector +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_create_uid +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_review_create_uid +#: model:ir.model.fields,field_description:connector.field_connector_config_settings_create_uid +msgid "Created by" +msgstr "" + +#. module: connector +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_create_date +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_review_create_date +#: model:ir.model.fields,field_description:connector.field_connector_config_settings_create_date +msgid "Created on" +msgstr "" + +#. module: connector +#: model:ir.model.fields,field_description:connector.field_connector_backend_display_name +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_display_name +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_review_display_name +#: model:ir.model.fields,field_description:connector.field_connector_config_settings_display_name +#: model:ir.model.fields,field_description:connector.field_external_binding_display_name +msgid "Display Name" +msgstr "" + +#. module: connector +#: model:ir.model,name:connector.model_external_binding +msgid "External Binding (abstract)" +msgstr "" + +#. module: connector +#: model:ir.ui.view,arch_db:connector.view_connector_checkpoint_search +msgid "Group By..." +msgstr "" + +#. module: connector +#: model:ir.model.fields,field_description:connector.field_connector_backend_id +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_id +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_review_id +#: model:ir.model.fields,field_description:connector.field_connector_config_settings_id +#: model:ir.model.fields,field_description:connector.field_external_binding_id +msgid "ID" +msgstr "" + +#. module: connector +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_backend_id +msgid "Imported from" +msgstr "" + +#. module: connector +#: model:ir.model.fields,field_description:connector.field_connector_backend___last_update +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint___last_update +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_review___last_update +#: model:ir.model.fields,field_description:connector.field_connector_config_settings___last_update +#: model:ir.model.fields,field_description:connector.field_external_binding___last_update +msgid "Last Modified on" +msgstr "" + +#. module: connector +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_review_write_uid +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_write_uid +#: model:ir.model.fields,field_description:connector.field_connector_config_settings_write_uid +msgid "Last Updated by" +msgstr "" + +#. module: connector +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_review_write_date +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_write_date +#: model:ir.model.fields,field_description:connector.field_connector_config_settings_write_date +msgid "Last Updated on" +msgstr "" + +#. module: connector +#: model:ir.model.fields,field_description:connector.field_connector_test_binding_sync_date +#: model:ir.model.fields,field_description:connector.field_external_binding_sync_date +#: model:ir.model.fields,field_description:connector.field_no_inherits_binding_sync_date +msgid "Last synchronization date" +msgstr "" + +#. module: connector +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_model_id +#: model:ir.ui.view,arch_db:connector.view_connector_checkpoint_search +msgid "Model" +msgstr "" + +#. module: connector +#: model:ir.model.fields,field_description:connector.field_connector_backend_name +#: model:ir.model.fields,field_description:connector.field_test_backend_name +msgid "Name" +msgstr "" + +#. module: connector +#: model:ir.model.fields,help:connector.field_connector_checkpoint_name +msgid "Name of the record to review" +msgstr "" + +#. module: connector +#: selection:connector.checkpoint,state:0 +#: model:ir.ui.view,arch_db:connector.view_connector_checkpoint_search +msgid "Need Review" +msgstr "" + +#. module: connector +#: model:ir.actions.act_window,help:connector.action_connector_checkpoint +msgid "No record to check." +msgstr "" + +#. module: connector +#: model:ir.actions.client,name:connector.action_client_connector_menu +msgid "Open Connector Menu" +msgstr "" + +#. module: connector +#: model:ir.model,name:connector.model_queue_job +msgid "Queue Job" +msgstr "" + +#. module: connector +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_record +msgid "Record" +msgstr "" + +#. module: connector +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_record_id +msgid "Record ID" +msgstr "" + +#. module: connector +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_name +msgid "Record Name" +msgstr "" + +#. module: connector +#: code:addons/connector/models/queue_job.py:32 +#, python-format +msgid "Related Record" +msgstr "" + +#. module: connector +#: model:ir.actions.act_window,name:connector.action_connector_checkpoint_review +#: model:ir.ui.view,arch_db:connector.view_connector_checkpoint_review +msgid "Review Checkpoints" +msgstr "" + +#. module: connector +#: selection:connector.checkpoint,state:0 +#: model:ir.ui.view,arch_db:connector.view_connector_checkpoint_form +#: model:ir.ui.view,arch_db:connector.view_connector_checkpoint_search +#: model:ir.ui.view,arch_db:connector.view_connector_checkpoint_tree +msgid "Reviewed" +msgstr "" + +#. module: connector +#: model:ir.ui.view,arch_db:connector.view_connector_checkpoint_review +msgid "Set as reviewed" +msgstr "" + +#. module: connector +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_state +msgid "Status" +msgstr "" + +#. module: connector +#: model:ir.actions.act_window,help:connector.action_connector_checkpoint +msgid "" +"The connectors list the new records to verify\n" +" based on their type. Only some need a manual\n" +" review." +msgstr "" + +#. module: connector +#: model:ir.model.fields,help:connector.field_connector_checkpoint_backend_id +msgid "The record has been imported from this backend" +msgstr "" + +#. module: connector +#: model:ir.model.fields,help:connector.field_connector_checkpoint_record +msgid "The record to review." +msgstr "" + +#. module: connector +#: model:ir.ui.view,arch_db:connector.view_connector_checkpoint_review +msgid "The selected checkpoints will be set as reviewed." +msgstr "" + +#. module: connector +#: model:ir.model.fields,field_description:connector.field_connector_backend_version +msgid "Version" +msgstr "" + +#. module: connector +#: model:ir.actions.act_window,help:connector.action_connector_checkpoint +msgid "" +"When a connector imports new records which have\n" +" configuration or reviews to do manually, they\n" +" will appear in this list. Once a record has been\n" +" checked, click on the 'Reviewed' button." +msgstr "" + +#. module: connector +#: model:ir.model,name:connector.model_base +msgid "base" +msgstr "" + +#. module: connector +#: model:ir.ui.view,arch_db:connector.view_connector_checkpoint_review +#: model:ir.ui.view,arch_db:connector.view_connector_config_settings +msgid "or" +msgstr "" + +#. module: connector +#: model:ir.ui.view,arch_db:connector.view_connector_checkpoint_form +msgid "to verify it:" +msgstr "" diff --git a/ext/3rd-party-addons/connector/i18n/pl.po b/ext/3rd-party-addons/connector/i18n/pl.po new file mode 100644 index 00000000..e7513575 --- /dev/null +++ b/ext/3rd-party-addons/connector/i18n/pl.po @@ -0,0 +1,317 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * connector +# +# Translators: +# OCA Transbot , 2017 +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server 10.0\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2017-03-10 03:36+0000\n" +"PO-Revision-Date: 2017-03-10 03:36+0000\n" +"Last-Translator: OCA Transbot , 2017\n" +"Language-Team: Polish (https://www.transifex.com/oca/teams/23907/pl/)\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: \n" +"Language: pl\n" +"Plural-Forms: nplurals=4; plural=(n==1 ? 0 : (n%10>=2 && n%10<=4) && (n%100<12 || n%100>=14) ? 1 : n!=1 && (n%10>=0 && n%10<=1) || (n%10>=5 && n%10<=9) || (n%100>=12 && n%100<=14) ? 2 : 3);\n" + +#. module: connector +#: code:addons/connector/checkpoint/checkpoint.py:119 +#, python-format +msgid "A %s needs a review." +msgstr "" + +#. module: connector +#: model:ir.ui.view,arch_db:connector.view_connector_config_settings +msgid "Apply" +msgstr "" + +#. module: connector +#: model:ir.ui.view,arch_db:connector.view_connector_config_settings +msgid "Backends" +msgstr "" + +#. module: connector +#: model:ir.ui.view,arch_db:connector.view_connector_checkpoint_review +#: model:ir.ui.view,arch_db:connector.view_connector_config_settings +msgid "Cancel" +msgstr "Anuluj" + +#. module: connector +#: model:ir.ui.menu,name:connector.menu_checkpoint +msgid "Checkpoint" +msgstr "" + +#. module: connector +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_review_checkpoint_ids +msgid "Checkpoints" +msgstr "" + +#. module: connector +#: model:ir.model,name:connector.model_connector_checkpoint_review +msgid "Checkpoints Review" +msgstr "" + +#. module: connector +#: model:ir.ui.view,arch_db:connector.view_connector_checkpoint_form +msgid "Click on the" +msgstr "" + +#. module: connector +#: model:ir.actions.act_window,name:connector.action_connector_config_settings +#: model:ir.ui.view,arch_db:connector.view_connector_config_settings +msgid "Configure Connector" +msgstr "" + +#. module: connector +#: model:ir.module.category,name:connector.module_category_connector +#: model:ir.ui.menu,name:connector.menu_connector_config_settings +msgid "Connector" +msgstr "" + +#. module: connector +#: model:ir.model,name:connector.model_connector_backend +msgid "Connector Backend" +msgstr "" + +#. module: connector +#: model:ir.actions.act_window,name:connector.action_connector_checkpoint +#: model:ir.model,name:connector.model_connector_checkpoint +#: model:ir.ui.view,arch_db:connector.view_connector_checkpoint_form +#: model:ir.ui.view,arch_db:connector.view_connector_checkpoint_search +#: model:ir.ui.view,arch_db:connector.view_connector_checkpoint_tree +msgid "Connector Checkpoint" +msgstr "" + +#. module: connector +#: model:ir.model,name:connector.model_connector_config_settings +msgid "Connector Configuration" +msgstr "" + +#. module: connector +#: model:res.groups,name:connector.group_connector_manager +msgid "Connector Manager" +msgstr "" + +#. module: connector +#: model:ir.ui.menu,name:connector.menu_connector +#: model:ir.ui.menu,name:connector.menu_connector_root +#: model:ir.ui.view,arch_db:connector.view_partner_connector_form +msgid "Connectors" +msgstr "" + +#. module: connector +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_create_uid +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_review_create_uid +#: model:ir.model.fields,field_description:connector.field_connector_config_settings_create_uid +msgid "Created by" +msgstr "" + +#. module: connector +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_create_date +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_review_create_date +#: model:ir.model.fields,field_description:connector.field_connector_config_settings_create_date +msgid "Created on" +msgstr "" + +#. module: connector +#: model:ir.model.fields,field_description:connector.field_connector_backend_display_name +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_display_name +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_review_display_name +#: model:ir.model.fields,field_description:connector.field_connector_config_settings_display_name +#: model:ir.model.fields,field_description:connector.field_external_binding_display_name +msgid "Display Name" +msgstr "" + +#. module: connector +#: model:ir.model,name:connector.model_external_binding +msgid "External Binding (abstract)" +msgstr "" + +#. module: connector +#: model:ir.ui.view,arch_db:connector.view_connector_checkpoint_search +msgid "Group By..." +msgstr "" + +#. module: connector +#: model:ir.model.fields,field_description:connector.field_connector_backend_id +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_id +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_review_id +#: model:ir.model.fields,field_description:connector.field_connector_config_settings_id +#: model:ir.model.fields,field_description:connector.field_external_binding_id +msgid "ID" +msgstr "" + +#. module: connector +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_backend_id +msgid "Imported from" +msgstr "" + +#. module: connector +#: model:ir.model.fields,field_description:connector.field_connector_backend___last_update +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint___last_update +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_review___last_update +#: model:ir.model.fields,field_description:connector.field_connector_config_settings___last_update +#: model:ir.model.fields,field_description:connector.field_external_binding___last_update +msgid "Last Modified on" +msgstr "" + +#. module: connector +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_review_write_uid +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_write_uid +#: model:ir.model.fields,field_description:connector.field_connector_config_settings_write_uid +msgid "Last Updated by" +msgstr "" + +#. module: connector +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_review_write_date +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_write_date +#: model:ir.model.fields,field_description:connector.field_connector_config_settings_write_date +msgid "Last Updated on" +msgstr "" + +#. module: connector +#: model:ir.model.fields,field_description:connector.field_connector_test_binding_sync_date +#: model:ir.model.fields,field_description:connector.field_external_binding_sync_date +#: model:ir.model.fields,field_description:connector.field_no_inherits_binding_sync_date +msgid "Last synchronization date" +msgstr "" + +#. module: connector +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_model_id +#: model:ir.ui.view,arch_db:connector.view_connector_checkpoint_search +msgid "Model" +msgstr "" + +#. module: connector +#: model:ir.model.fields,field_description:connector.field_connector_backend_name +#: model:ir.model.fields,field_description:connector.field_test_backend_name +msgid "Name" +msgstr "" + +#. module: connector +#: model:ir.model.fields,help:connector.field_connector_checkpoint_name +msgid "Name of the record to review" +msgstr "" + +#. module: connector +#: selection:connector.checkpoint,state:0 +#: model:ir.ui.view,arch_db:connector.view_connector_checkpoint_search +msgid "Need Review" +msgstr "" + +#. module: connector +#: model:ir.actions.act_window,help:connector.action_connector_checkpoint +msgid "No record to check." +msgstr "" + +#. module: connector +#: model:ir.actions.client,name:connector.action_client_connector_menu +msgid "Open Connector Menu" +msgstr "" + +#. module: connector +#: model:ir.model,name:connector.model_queue_job +msgid "Queue Job" +msgstr "" + +#. module: connector +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_record +msgid "Record" +msgstr "" + +#. module: connector +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_record_id +msgid "Record ID" +msgstr "" + +#. module: connector +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_name +msgid "Record Name" +msgstr "" + +#. module: connector +#: code:addons/connector/models/queue_job.py:32 +#, python-format +msgid "Related Record" +msgstr "" + +#. module: connector +#: model:ir.actions.act_window,name:connector.action_connector_checkpoint_review +#: model:ir.ui.view,arch_db:connector.view_connector_checkpoint_review +msgid "Review Checkpoints" +msgstr "" + +#. module: connector +#: selection:connector.checkpoint,state:0 +#: model:ir.ui.view,arch_db:connector.view_connector_checkpoint_form +#: model:ir.ui.view,arch_db:connector.view_connector_checkpoint_search +#: model:ir.ui.view,arch_db:connector.view_connector_checkpoint_tree +msgid "Reviewed" +msgstr "" + +#. module: connector +#: model:ir.ui.view,arch_db:connector.view_connector_checkpoint_review +msgid "Set as reviewed" +msgstr "" + +#. module: connector +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_state +msgid "Status" +msgstr "" + +#. module: connector +#: model:ir.actions.act_window,help:connector.action_connector_checkpoint +msgid "" +"The connectors list the new records to verify\n" +" based on their type. Only some need a manual\n" +" review." +msgstr "" + +#. module: connector +#: model:ir.model.fields,help:connector.field_connector_checkpoint_backend_id +msgid "The record has been imported from this backend" +msgstr "" + +#. module: connector +#: model:ir.model.fields,help:connector.field_connector_checkpoint_record +msgid "The record to review." +msgstr "" + +#. module: connector +#: model:ir.ui.view,arch_db:connector.view_connector_checkpoint_review +msgid "The selected checkpoints will be set as reviewed." +msgstr "" + +#. module: connector +#: model:ir.model.fields,field_description:connector.field_connector_backend_version +msgid "Version" +msgstr "" + +#. module: connector +#: model:ir.actions.act_window,help:connector.action_connector_checkpoint +msgid "" +"When a connector imports new records which have\n" +" configuration or reviews to do manually, they\n" +" will appear in this list. Once a record has been\n" +" checked, click on the 'Reviewed' button." +msgstr "" + +#. module: connector +#: model:ir.model,name:connector.model_base +msgid "base" +msgstr "" + +#. module: connector +#: model:ir.ui.view,arch_db:connector.view_connector_checkpoint_review +#: model:ir.ui.view,arch_db:connector.view_connector_config_settings +msgid "or" +msgstr "" + +#. module: connector +#: model:ir.ui.view,arch_db:connector.view_connector_checkpoint_form +msgid "to verify it:" +msgstr "" diff --git a/ext/3rd-party-addons/connector/i18n/pt.po b/ext/3rd-party-addons/connector/i18n/pt.po new file mode 100644 index 00000000..baf3ba8f --- /dev/null +++ b/ext/3rd-party-addons/connector/i18n/pt.po @@ -0,0 +1,317 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * connector +# +# Translators: +# OCA Transbot , 2017 +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server 10.0\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2017-03-10 03:36+0000\n" +"PO-Revision-Date: 2017-03-10 03:36+0000\n" +"Last-Translator: OCA Transbot , 2017\n" +"Language-Team: Portuguese (https://www.transifex.com/oca/teams/23907/pt/)\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: \n" +"Language: pt\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" + +#. module: connector +#: code:addons/connector/checkpoint/checkpoint.py:119 +#, python-format +msgid "A %s needs a review." +msgstr "" + +#. module: connector +#: model:ir.ui.view,arch_db:connector.view_connector_config_settings +msgid "Apply" +msgstr "" + +#. module: connector +#: model:ir.ui.view,arch_db:connector.view_connector_config_settings +msgid "Backends" +msgstr "" + +#. module: connector +#: model:ir.ui.view,arch_db:connector.view_connector_checkpoint_review +#: model:ir.ui.view,arch_db:connector.view_connector_config_settings +msgid "Cancel" +msgstr "Cancelar" + +#. module: connector +#: model:ir.ui.menu,name:connector.menu_checkpoint +msgid "Checkpoint" +msgstr "" + +#. module: connector +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_review_checkpoint_ids +msgid "Checkpoints" +msgstr "" + +#. module: connector +#: model:ir.model,name:connector.model_connector_checkpoint_review +msgid "Checkpoints Review" +msgstr "" + +#. module: connector +#: model:ir.ui.view,arch_db:connector.view_connector_checkpoint_form +msgid "Click on the" +msgstr "" + +#. module: connector +#: model:ir.actions.act_window,name:connector.action_connector_config_settings +#: model:ir.ui.view,arch_db:connector.view_connector_config_settings +msgid "Configure Connector" +msgstr "" + +#. module: connector +#: model:ir.module.category,name:connector.module_category_connector +#: model:ir.ui.menu,name:connector.menu_connector_config_settings +msgid "Connector" +msgstr "" + +#. module: connector +#: model:ir.model,name:connector.model_connector_backend +msgid "Connector Backend" +msgstr "" + +#. module: connector +#: model:ir.actions.act_window,name:connector.action_connector_checkpoint +#: model:ir.model,name:connector.model_connector_checkpoint +#: model:ir.ui.view,arch_db:connector.view_connector_checkpoint_form +#: model:ir.ui.view,arch_db:connector.view_connector_checkpoint_search +#: model:ir.ui.view,arch_db:connector.view_connector_checkpoint_tree +msgid "Connector Checkpoint" +msgstr "" + +#. module: connector +#: model:ir.model,name:connector.model_connector_config_settings +msgid "Connector Configuration" +msgstr "" + +#. module: connector +#: model:res.groups,name:connector.group_connector_manager +msgid "Connector Manager" +msgstr "" + +#. module: connector +#: model:ir.ui.menu,name:connector.menu_connector +#: model:ir.ui.menu,name:connector.menu_connector_root +#: model:ir.ui.view,arch_db:connector.view_partner_connector_form +msgid "Connectors" +msgstr "" + +#. module: connector +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_create_uid +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_review_create_uid +#: model:ir.model.fields,field_description:connector.field_connector_config_settings_create_uid +msgid "Created by" +msgstr "Criado por" + +#. module: connector +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_create_date +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_review_create_date +#: model:ir.model.fields,field_description:connector.field_connector_config_settings_create_date +msgid "Created on" +msgstr "Criado em" + +#. module: connector +#: model:ir.model.fields,field_description:connector.field_connector_backend_display_name +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_display_name +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_review_display_name +#: model:ir.model.fields,field_description:connector.field_connector_config_settings_display_name +#: model:ir.model.fields,field_description:connector.field_external_binding_display_name +msgid "Display Name" +msgstr "" + +#. module: connector +#: model:ir.model,name:connector.model_external_binding +msgid "External Binding (abstract)" +msgstr "" + +#. module: connector +#: model:ir.ui.view,arch_db:connector.view_connector_checkpoint_search +msgid "Group By..." +msgstr "" + +#. module: connector +#: model:ir.model.fields,field_description:connector.field_connector_backend_id +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_id +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_review_id +#: model:ir.model.fields,field_description:connector.field_connector_config_settings_id +#: model:ir.model.fields,field_description:connector.field_external_binding_id +msgid "ID" +msgstr "ID" + +#. module: connector +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_backend_id +msgid "Imported from" +msgstr "" + +#. module: connector +#: model:ir.model.fields,field_description:connector.field_connector_backend___last_update +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint___last_update +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_review___last_update +#: model:ir.model.fields,field_description:connector.field_connector_config_settings___last_update +#: model:ir.model.fields,field_description:connector.field_external_binding___last_update +msgid "Last Modified on" +msgstr "" + +#. module: connector +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_review_write_uid +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_write_uid +#: model:ir.model.fields,field_description:connector.field_connector_config_settings_write_uid +msgid "Last Updated by" +msgstr "Atualizado pela última vez por" + +#. module: connector +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_review_write_date +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_write_date +#: model:ir.model.fields,field_description:connector.field_connector_config_settings_write_date +msgid "Last Updated on" +msgstr "Atualizado pela última vez em" + +#. module: connector +#: model:ir.model.fields,field_description:connector.field_connector_test_binding_sync_date +#: model:ir.model.fields,field_description:connector.field_external_binding_sync_date +#: model:ir.model.fields,field_description:connector.field_no_inherits_binding_sync_date +msgid "Last synchronization date" +msgstr "" + +#. module: connector +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_model_id +#: model:ir.ui.view,arch_db:connector.view_connector_checkpoint_search +msgid "Model" +msgstr "" + +#. module: connector +#: model:ir.model.fields,field_description:connector.field_connector_backend_name +#: model:ir.model.fields,field_description:connector.field_test_backend_name +msgid "Name" +msgstr "" + +#. module: connector +#: model:ir.model.fields,help:connector.field_connector_checkpoint_name +msgid "Name of the record to review" +msgstr "" + +#. module: connector +#: selection:connector.checkpoint,state:0 +#: model:ir.ui.view,arch_db:connector.view_connector_checkpoint_search +msgid "Need Review" +msgstr "" + +#. module: connector +#: model:ir.actions.act_window,help:connector.action_connector_checkpoint +msgid "No record to check." +msgstr "" + +#. module: connector +#: model:ir.actions.client,name:connector.action_client_connector_menu +msgid "Open Connector Menu" +msgstr "" + +#. module: connector +#: model:ir.model,name:connector.model_queue_job +msgid "Queue Job" +msgstr "" + +#. module: connector +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_record +msgid "Record" +msgstr "" + +#. module: connector +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_record_id +msgid "Record ID" +msgstr "" + +#. module: connector +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_name +msgid "Record Name" +msgstr "" + +#. module: connector +#: code:addons/connector/models/queue_job.py:32 +#, python-format +msgid "Related Record" +msgstr "" + +#. module: connector +#: model:ir.actions.act_window,name:connector.action_connector_checkpoint_review +#: model:ir.ui.view,arch_db:connector.view_connector_checkpoint_review +msgid "Review Checkpoints" +msgstr "" + +#. module: connector +#: selection:connector.checkpoint,state:0 +#: model:ir.ui.view,arch_db:connector.view_connector_checkpoint_form +#: model:ir.ui.view,arch_db:connector.view_connector_checkpoint_search +#: model:ir.ui.view,arch_db:connector.view_connector_checkpoint_tree +msgid "Reviewed" +msgstr "" + +#. module: connector +#: model:ir.ui.view,arch_db:connector.view_connector_checkpoint_review +msgid "Set as reviewed" +msgstr "" + +#. module: connector +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_state +msgid "Status" +msgstr "" + +#. module: connector +#: model:ir.actions.act_window,help:connector.action_connector_checkpoint +msgid "" +"The connectors list the new records to verify\n" +" based on their type. Only some need a manual\n" +" review." +msgstr "" + +#. module: connector +#: model:ir.model.fields,help:connector.field_connector_checkpoint_backend_id +msgid "The record has been imported from this backend" +msgstr "" + +#. module: connector +#: model:ir.model.fields,help:connector.field_connector_checkpoint_record +msgid "The record to review." +msgstr "" + +#. module: connector +#: model:ir.ui.view,arch_db:connector.view_connector_checkpoint_review +msgid "The selected checkpoints will be set as reviewed." +msgstr "" + +#. module: connector +#: model:ir.model.fields,field_description:connector.field_connector_backend_version +msgid "Version" +msgstr "" + +#. module: connector +#: model:ir.actions.act_window,help:connector.action_connector_checkpoint +msgid "" +"When a connector imports new records which have\n" +" configuration or reviews to do manually, they\n" +" will appear in this list. Once a record has been\n" +" checked, click on the 'Reviewed' button." +msgstr "" + +#. module: connector +#: model:ir.model,name:connector.model_base +msgid "base" +msgstr "" + +#. module: connector +#: model:ir.ui.view,arch_db:connector.view_connector_checkpoint_review +#: model:ir.ui.view,arch_db:connector.view_connector_config_settings +msgid "or" +msgstr "" + +#. module: connector +#: model:ir.ui.view,arch_db:connector.view_connector_checkpoint_form +msgid "to verify it:" +msgstr "" diff --git a/ext/3rd-party-addons/connector/i18n/pt_BR.po b/ext/3rd-party-addons/connector/i18n/pt_BR.po new file mode 100644 index 00000000..a17b0506 --- /dev/null +++ b/ext/3rd-party-addons/connector/i18n/pt_BR.po @@ -0,0 +1,317 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * connector +# +# Translators: +# OCA Transbot , 2017 +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server 10.0\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2017-03-10 03:36+0000\n" +"PO-Revision-Date: 2017-03-10 03:36+0000\n" +"Last-Translator: OCA Transbot , 2017\n" +"Language-Team: Portuguese (Brazil) (https://www.transifex.com/oca/teams/23907/pt_BR/)\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: \n" +"Language: pt_BR\n" +"Plural-Forms: nplurals=2; plural=(n > 1);\n" + +#. module: connector +#: code:addons/connector/checkpoint/checkpoint.py:119 +#, python-format +msgid "A %s needs a review." +msgstr "Um %s necessita revisão" + +#. module: connector +#: model:ir.ui.view,arch_db:connector.view_connector_config_settings +msgid "Apply" +msgstr "Aplicar" + +#. module: connector +#: model:ir.ui.view,arch_db:connector.view_connector_config_settings +msgid "Backends" +msgstr "Backends" + +#. module: connector +#: model:ir.ui.view,arch_db:connector.view_connector_checkpoint_review +#: model:ir.ui.view,arch_db:connector.view_connector_config_settings +msgid "Cancel" +msgstr "Cancelar" + +#. module: connector +#: model:ir.ui.menu,name:connector.menu_checkpoint +msgid "Checkpoint" +msgstr "Ponto de checagem" + +#. module: connector +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_review_checkpoint_ids +msgid "Checkpoints" +msgstr "Pontos de checagem" + +#. module: connector +#: model:ir.model,name:connector.model_connector_checkpoint_review +msgid "Checkpoints Review" +msgstr "Revisão de pontos de checagem" + +#. module: connector +#: model:ir.ui.view,arch_db:connector.view_connector_checkpoint_form +msgid "Click on the" +msgstr "Clique na" + +#. module: connector +#: model:ir.actions.act_window,name:connector.action_connector_config_settings +#: model:ir.ui.view,arch_db:connector.view_connector_config_settings +msgid "Configure Connector" +msgstr "Configurar conector" + +#. module: connector +#: model:ir.module.category,name:connector.module_category_connector +#: model:ir.ui.menu,name:connector.menu_connector_config_settings +msgid "Connector" +msgstr "Conector" + +#. module: connector +#: model:ir.model,name:connector.model_connector_backend +msgid "Connector Backend" +msgstr "Backend do conector" + +#. module: connector +#: model:ir.actions.act_window,name:connector.action_connector_checkpoint +#: model:ir.model,name:connector.model_connector_checkpoint +#: model:ir.ui.view,arch_db:connector.view_connector_checkpoint_form +#: model:ir.ui.view,arch_db:connector.view_connector_checkpoint_search +#: model:ir.ui.view,arch_db:connector.view_connector_checkpoint_tree +msgid "Connector Checkpoint" +msgstr "Ponto de checagem conector" + +#. module: connector +#: model:ir.model,name:connector.model_connector_config_settings +msgid "Connector Configuration" +msgstr "Configuração do conector" + +#. module: connector +#: model:res.groups,name:connector.group_connector_manager +msgid "Connector Manager" +msgstr "Gerenciador do conector" + +#. module: connector +#: model:ir.ui.menu,name:connector.menu_connector +#: model:ir.ui.menu,name:connector.menu_connector_root +#: model:ir.ui.view,arch_db:connector.view_partner_connector_form +msgid "Connectors" +msgstr "Conectores" + +#. module: connector +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_create_uid +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_review_create_uid +#: model:ir.model.fields,field_description:connector.field_connector_config_settings_create_uid +msgid "Created by" +msgstr "Criado por" + +#. module: connector +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_create_date +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_review_create_date +#: model:ir.model.fields,field_description:connector.field_connector_config_settings_create_date +msgid "Created on" +msgstr "Criado em " + +#. module: connector +#: model:ir.model.fields,field_description:connector.field_connector_backend_display_name +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_display_name +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_review_display_name +#: model:ir.model.fields,field_description:connector.field_connector_config_settings_display_name +#: model:ir.model.fields,field_description:connector.field_external_binding_display_name +msgid "Display Name" +msgstr "" + +#. module: connector +#: model:ir.model,name:connector.model_external_binding +msgid "External Binding (abstract)" +msgstr "Ligações externas (resumo)" + +#. module: connector +#: model:ir.ui.view,arch_db:connector.view_connector_checkpoint_search +msgid "Group By..." +msgstr "Agrupar por .." + +#. module: connector +#: model:ir.model.fields,field_description:connector.field_connector_backend_id +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_id +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_review_id +#: model:ir.model.fields,field_description:connector.field_connector_config_settings_id +#: model:ir.model.fields,field_description:connector.field_external_binding_id +msgid "ID" +msgstr "ID" + +#. module: connector +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_backend_id +msgid "Imported from" +msgstr "Importado de" + +#. module: connector +#: model:ir.model.fields,field_description:connector.field_connector_backend___last_update +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint___last_update +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_review___last_update +#: model:ir.model.fields,field_description:connector.field_connector_config_settings___last_update +#: model:ir.model.fields,field_description:connector.field_external_binding___last_update +msgid "Last Modified on" +msgstr "" + +#. module: connector +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_review_write_uid +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_write_uid +#: model:ir.model.fields,field_description:connector.field_connector_config_settings_write_uid +msgid "Last Updated by" +msgstr "Última atualização por" + +#. module: connector +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_review_write_date +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_write_date +#: model:ir.model.fields,field_description:connector.field_connector_config_settings_write_date +msgid "Last Updated on" +msgstr "Última atualização em " + +#. module: connector +#: model:ir.model.fields,field_description:connector.field_connector_test_binding_sync_date +#: model:ir.model.fields,field_description:connector.field_external_binding_sync_date +#: model:ir.model.fields,field_description:connector.field_no_inherits_binding_sync_date +msgid "Last synchronization date" +msgstr "Última sincronização" + +#. module: connector +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_model_id +#: model:ir.ui.view,arch_db:connector.view_connector_checkpoint_search +msgid "Model" +msgstr "Modelo" + +#. module: connector +#: model:ir.model.fields,field_description:connector.field_connector_backend_name +#: model:ir.model.fields,field_description:connector.field_test_backend_name +msgid "Name" +msgstr "Nome" + +#. module: connector +#: model:ir.model.fields,help:connector.field_connector_checkpoint_name +msgid "Name of the record to review" +msgstr "" + +#. module: connector +#: selection:connector.checkpoint,state:0 +#: model:ir.ui.view,arch_db:connector.view_connector_checkpoint_search +msgid "Need Review" +msgstr "Necessita revisão" + +#. module: connector +#: model:ir.actions.act_window,help:connector.action_connector_checkpoint +msgid "No record to check." +msgstr "" + +#. module: connector +#: model:ir.actions.client,name:connector.action_client_connector_menu +msgid "Open Connector Menu" +msgstr "Abrir menu do conector" + +#. module: connector +#: model:ir.model,name:connector.model_queue_job +msgid "Queue Job" +msgstr "Fila de tarefas" + +#. module: connector +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_record +msgid "Record" +msgstr "" + +#. module: connector +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_record_id +msgid "Record ID" +msgstr "ID do registro" + +#. module: connector +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_name +msgid "Record Name" +msgstr "" + +#. module: connector +#: code:addons/connector/models/queue_job.py:32 +#, python-format +msgid "Related Record" +msgstr "Registro relacionado" + +#. module: connector +#: model:ir.actions.act_window,name:connector.action_connector_checkpoint_review +#: model:ir.ui.view,arch_db:connector.view_connector_checkpoint_review +msgid "Review Checkpoints" +msgstr "Revisão dos pontos de checagem" + +#. module: connector +#: selection:connector.checkpoint,state:0 +#: model:ir.ui.view,arch_db:connector.view_connector_checkpoint_form +#: model:ir.ui.view,arch_db:connector.view_connector_checkpoint_search +#: model:ir.ui.view,arch_db:connector.view_connector_checkpoint_tree +msgid "Reviewed" +msgstr "Revisado" + +#. module: connector +#: model:ir.ui.view,arch_db:connector.view_connector_checkpoint_review +msgid "Set as reviewed" +msgstr "Marcar como revisado" + +#. module: connector +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_state +msgid "Status" +msgstr "Situação" + +#. module: connector +#: model:ir.actions.act_window,help:connector.action_connector_checkpoint +msgid "" +"The connectors list the new records to verify\n" +" based on their type. Only some need a manual\n" +" review." +msgstr "" + +#. module: connector +#: model:ir.model.fields,help:connector.field_connector_checkpoint_backend_id +msgid "The record has been imported from this backend" +msgstr "O registro foi importado deste backend" + +#. module: connector +#: model:ir.model.fields,help:connector.field_connector_checkpoint_record +msgid "The record to review." +msgstr "" + +#. module: connector +#: model:ir.ui.view,arch_db:connector.view_connector_checkpoint_review +msgid "The selected checkpoints will be set as reviewed." +msgstr "O pontos de checagem selecionados vão ser marcados como revisados." + +#. module: connector +#: model:ir.model.fields,field_description:connector.field_connector_backend_version +msgid "Version" +msgstr "Versão" + +#. module: connector +#: model:ir.actions.act_window,help:connector.action_connector_checkpoint +msgid "" +"When a connector imports new records which have\n" +" configuration or reviews to do manually, they\n" +" will appear in this list. Once a record has been\n" +" checked, click on the 'Reviewed' button." +msgstr "" + +#. module: connector +#: model:ir.model,name:connector.model_base +msgid "base" +msgstr "" + +#. module: connector +#: model:ir.ui.view,arch_db:connector.view_connector_checkpoint_review +#: model:ir.ui.view,arch_db:connector.view_connector_config_settings +msgid "or" +msgstr "ou" + +#. module: connector +#: model:ir.ui.view,arch_db:connector.view_connector_checkpoint_form +msgid "to verify it:" +msgstr "para verificar." diff --git a/ext/3rd-party-addons/connector/i18n/pt_PT.po b/ext/3rd-party-addons/connector/i18n/pt_PT.po new file mode 100644 index 00000000..84585967 --- /dev/null +++ b/ext/3rd-party-addons/connector/i18n/pt_PT.po @@ -0,0 +1,317 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * connector +# +# Translators: +# OCA Transbot , 2017 +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server 10.0\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2017-03-10 03:36+0000\n" +"PO-Revision-Date: 2017-03-10 03:36+0000\n" +"Last-Translator: OCA Transbot , 2017\n" +"Language-Team: Portuguese (Portugal) (https://www.transifex.com/oca/teams/23907/pt_PT/)\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: \n" +"Language: pt_PT\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" + +#. module: connector +#: code:addons/connector/checkpoint/checkpoint.py:119 +#, python-format +msgid "A %s needs a review." +msgstr "" + +#. module: connector +#: model:ir.ui.view,arch_db:connector.view_connector_config_settings +msgid "Apply" +msgstr "" + +#. module: connector +#: model:ir.ui.view,arch_db:connector.view_connector_config_settings +msgid "Backends" +msgstr "" + +#. module: connector +#: model:ir.ui.view,arch_db:connector.view_connector_checkpoint_review +#: model:ir.ui.view,arch_db:connector.view_connector_config_settings +msgid "Cancel" +msgstr "Cancelar" + +#. module: connector +#: model:ir.ui.menu,name:connector.menu_checkpoint +msgid "Checkpoint" +msgstr "" + +#. module: connector +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_review_checkpoint_ids +msgid "Checkpoints" +msgstr "" + +#. module: connector +#: model:ir.model,name:connector.model_connector_checkpoint_review +msgid "Checkpoints Review" +msgstr "" + +#. module: connector +#: model:ir.ui.view,arch_db:connector.view_connector_checkpoint_form +msgid "Click on the" +msgstr "" + +#. module: connector +#: model:ir.actions.act_window,name:connector.action_connector_config_settings +#: model:ir.ui.view,arch_db:connector.view_connector_config_settings +msgid "Configure Connector" +msgstr "" + +#. module: connector +#: model:ir.module.category,name:connector.module_category_connector +#: model:ir.ui.menu,name:connector.menu_connector_config_settings +msgid "Connector" +msgstr "" + +#. module: connector +#: model:ir.model,name:connector.model_connector_backend +msgid "Connector Backend" +msgstr "" + +#. module: connector +#: model:ir.actions.act_window,name:connector.action_connector_checkpoint +#: model:ir.model,name:connector.model_connector_checkpoint +#: model:ir.ui.view,arch_db:connector.view_connector_checkpoint_form +#: model:ir.ui.view,arch_db:connector.view_connector_checkpoint_search +#: model:ir.ui.view,arch_db:connector.view_connector_checkpoint_tree +msgid "Connector Checkpoint" +msgstr "" + +#. module: connector +#: model:ir.model,name:connector.model_connector_config_settings +msgid "Connector Configuration" +msgstr "" + +#. module: connector +#: model:res.groups,name:connector.group_connector_manager +msgid "Connector Manager" +msgstr "" + +#. module: connector +#: model:ir.ui.menu,name:connector.menu_connector +#: model:ir.ui.menu,name:connector.menu_connector_root +#: model:ir.ui.view,arch_db:connector.view_partner_connector_form +msgid "Connectors" +msgstr "" + +#. module: connector +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_create_uid +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_review_create_uid +#: model:ir.model.fields,field_description:connector.field_connector_config_settings_create_uid +msgid "Created by" +msgstr "Criado por" + +#. module: connector +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_create_date +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_review_create_date +#: model:ir.model.fields,field_description:connector.field_connector_config_settings_create_date +msgid "Created on" +msgstr "Criado em" + +#. module: connector +#: model:ir.model.fields,field_description:connector.field_connector_backend_display_name +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_display_name +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_review_display_name +#: model:ir.model.fields,field_description:connector.field_connector_config_settings_display_name +#: model:ir.model.fields,field_description:connector.field_external_binding_display_name +msgid "Display Name" +msgstr "" + +#. module: connector +#: model:ir.model,name:connector.model_external_binding +msgid "External Binding (abstract)" +msgstr "" + +#. module: connector +#: model:ir.ui.view,arch_db:connector.view_connector_checkpoint_search +msgid "Group By..." +msgstr "" + +#. module: connector +#: model:ir.model.fields,field_description:connector.field_connector_backend_id +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_id +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_review_id +#: model:ir.model.fields,field_description:connector.field_connector_config_settings_id +#: model:ir.model.fields,field_description:connector.field_external_binding_id +msgid "ID" +msgstr "ID" + +#. module: connector +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_backend_id +msgid "Imported from" +msgstr "" + +#. module: connector +#: model:ir.model.fields,field_description:connector.field_connector_backend___last_update +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint___last_update +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_review___last_update +#: model:ir.model.fields,field_description:connector.field_connector_config_settings___last_update +#: model:ir.model.fields,field_description:connector.field_external_binding___last_update +msgid "Last Modified on" +msgstr "" + +#. module: connector +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_review_write_uid +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_write_uid +#: model:ir.model.fields,field_description:connector.field_connector_config_settings_write_uid +msgid "Last Updated by" +msgstr "Atualizado pela última vez por" + +#. module: connector +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_review_write_date +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_write_date +#: model:ir.model.fields,field_description:connector.field_connector_config_settings_write_date +msgid "Last Updated on" +msgstr "Atualizado pela última vez em" + +#. module: connector +#: model:ir.model.fields,field_description:connector.field_connector_test_binding_sync_date +#: model:ir.model.fields,field_description:connector.field_external_binding_sync_date +#: model:ir.model.fields,field_description:connector.field_no_inherits_binding_sync_date +msgid "Last synchronization date" +msgstr "" + +#. module: connector +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_model_id +#: model:ir.ui.view,arch_db:connector.view_connector_checkpoint_search +msgid "Model" +msgstr "" + +#. module: connector +#: model:ir.model.fields,field_description:connector.field_connector_backend_name +#: model:ir.model.fields,field_description:connector.field_test_backend_name +msgid "Name" +msgstr "" + +#. module: connector +#: model:ir.model.fields,help:connector.field_connector_checkpoint_name +msgid "Name of the record to review" +msgstr "" + +#. module: connector +#: selection:connector.checkpoint,state:0 +#: model:ir.ui.view,arch_db:connector.view_connector_checkpoint_search +msgid "Need Review" +msgstr "" + +#. module: connector +#: model:ir.actions.act_window,help:connector.action_connector_checkpoint +msgid "No record to check." +msgstr "" + +#. module: connector +#: model:ir.actions.client,name:connector.action_client_connector_menu +msgid "Open Connector Menu" +msgstr "" + +#. module: connector +#: model:ir.model,name:connector.model_queue_job +msgid "Queue Job" +msgstr "" + +#. module: connector +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_record +msgid "Record" +msgstr "" + +#. module: connector +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_record_id +msgid "Record ID" +msgstr "" + +#. module: connector +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_name +msgid "Record Name" +msgstr "" + +#. module: connector +#: code:addons/connector/models/queue_job.py:32 +#, python-format +msgid "Related Record" +msgstr "" + +#. module: connector +#: model:ir.actions.act_window,name:connector.action_connector_checkpoint_review +#: model:ir.ui.view,arch_db:connector.view_connector_checkpoint_review +msgid "Review Checkpoints" +msgstr "" + +#. module: connector +#: selection:connector.checkpoint,state:0 +#: model:ir.ui.view,arch_db:connector.view_connector_checkpoint_form +#: model:ir.ui.view,arch_db:connector.view_connector_checkpoint_search +#: model:ir.ui.view,arch_db:connector.view_connector_checkpoint_tree +msgid "Reviewed" +msgstr "" + +#. module: connector +#: model:ir.ui.view,arch_db:connector.view_connector_checkpoint_review +msgid "Set as reviewed" +msgstr "" + +#. module: connector +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_state +msgid "Status" +msgstr "Estado" + +#. module: connector +#: model:ir.actions.act_window,help:connector.action_connector_checkpoint +msgid "" +"The connectors list the new records to verify\n" +" based on their type. Only some need a manual\n" +" review." +msgstr "" + +#. module: connector +#: model:ir.model.fields,help:connector.field_connector_checkpoint_backend_id +msgid "The record has been imported from this backend" +msgstr "" + +#. module: connector +#: model:ir.model.fields,help:connector.field_connector_checkpoint_record +msgid "The record to review." +msgstr "" + +#. module: connector +#: model:ir.ui.view,arch_db:connector.view_connector_checkpoint_review +msgid "The selected checkpoints will be set as reviewed." +msgstr "" + +#. module: connector +#: model:ir.model.fields,field_description:connector.field_connector_backend_version +msgid "Version" +msgstr "" + +#. module: connector +#: model:ir.actions.act_window,help:connector.action_connector_checkpoint +msgid "" +"When a connector imports new records which have\n" +" configuration or reviews to do manually, they\n" +" will appear in this list. Once a record has been\n" +" checked, click on the 'Reviewed' button." +msgstr "" + +#. module: connector +#: model:ir.model,name:connector.model_base +msgid "base" +msgstr "" + +#. module: connector +#: model:ir.ui.view,arch_db:connector.view_connector_checkpoint_review +#: model:ir.ui.view,arch_db:connector.view_connector_config_settings +msgid "or" +msgstr "" + +#. module: connector +#: model:ir.ui.view,arch_db:connector.view_connector_checkpoint_form +msgid "to verify it:" +msgstr "" diff --git a/ext/3rd-party-addons/connector/i18n/ro.po b/ext/3rd-party-addons/connector/i18n/ro.po new file mode 100644 index 00000000..2c1cdfc1 --- /dev/null +++ b/ext/3rd-party-addons/connector/i18n/ro.po @@ -0,0 +1,317 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * connector +# +# Translators: +# OCA Transbot , 2017 +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server 10.0\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2017-03-10 03:36+0000\n" +"PO-Revision-Date: 2017-03-10 03:36+0000\n" +"Last-Translator: OCA Transbot , 2017\n" +"Language-Team: Romanian (https://www.transifex.com/oca/teams/23907/ro/)\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: \n" +"Language: ro\n" +"Plural-Forms: nplurals=3; plural=(n==1?0:(((n%100>19)||((n%100==0)&&(n!=0)))?2:1));\n" + +#. module: connector +#: code:addons/connector/checkpoint/checkpoint.py:119 +#, python-format +msgid "A %s needs a review." +msgstr "" + +#. module: connector +#: model:ir.ui.view,arch_db:connector.view_connector_config_settings +msgid "Apply" +msgstr "Aplică" + +#. module: connector +#: model:ir.ui.view,arch_db:connector.view_connector_config_settings +msgid "Backends" +msgstr "" + +#. module: connector +#: model:ir.ui.view,arch_db:connector.view_connector_checkpoint_review +#: model:ir.ui.view,arch_db:connector.view_connector_config_settings +msgid "Cancel" +msgstr "Anuleaza" + +#. module: connector +#: model:ir.ui.menu,name:connector.menu_checkpoint +msgid "Checkpoint" +msgstr "" + +#. module: connector +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_review_checkpoint_ids +msgid "Checkpoints" +msgstr "" + +#. module: connector +#: model:ir.model,name:connector.model_connector_checkpoint_review +msgid "Checkpoints Review" +msgstr "" + +#. module: connector +#: model:ir.ui.view,arch_db:connector.view_connector_checkpoint_form +msgid "Click on the" +msgstr "" + +#. module: connector +#: model:ir.actions.act_window,name:connector.action_connector_config_settings +#: model:ir.ui.view,arch_db:connector.view_connector_config_settings +msgid "Configure Connector" +msgstr "" + +#. module: connector +#: model:ir.module.category,name:connector.module_category_connector +#: model:ir.ui.menu,name:connector.menu_connector_config_settings +msgid "Connector" +msgstr "" + +#. module: connector +#: model:ir.model,name:connector.model_connector_backend +msgid "Connector Backend" +msgstr "" + +#. module: connector +#: model:ir.actions.act_window,name:connector.action_connector_checkpoint +#: model:ir.model,name:connector.model_connector_checkpoint +#: model:ir.ui.view,arch_db:connector.view_connector_checkpoint_form +#: model:ir.ui.view,arch_db:connector.view_connector_checkpoint_search +#: model:ir.ui.view,arch_db:connector.view_connector_checkpoint_tree +msgid "Connector Checkpoint" +msgstr "" + +#. module: connector +#: model:ir.model,name:connector.model_connector_config_settings +msgid "Connector Configuration" +msgstr "" + +#. module: connector +#: model:res.groups,name:connector.group_connector_manager +msgid "Connector Manager" +msgstr "" + +#. module: connector +#: model:ir.ui.menu,name:connector.menu_connector +#: model:ir.ui.menu,name:connector.menu_connector_root +#: model:ir.ui.view,arch_db:connector.view_partner_connector_form +msgid "Connectors" +msgstr "" + +#. module: connector +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_create_uid +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_review_create_uid +#: model:ir.model.fields,field_description:connector.field_connector_config_settings_create_uid +msgid "Created by" +msgstr "" + +#. module: connector +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_create_date +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_review_create_date +#: model:ir.model.fields,field_description:connector.field_connector_config_settings_create_date +msgid "Created on" +msgstr "" + +#. module: connector +#: model:ir.model.fields,field_description:connector.field_connector_backend_display_name +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_display_name +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_review_display_name +#: model:ir.model.fields,field_description:connector.field_connector_config_settings_display_name +#: model:ir.model.fields,field_description:connector.field_external_binding_display_name +msgid "Display Name" +msgstr "" + +#. module: connector +#: model:ir.model,name:connector.model_external_binding +msgid "External Binding (abstract)" +msgstr "" + +#. module: connector +#: model:ir.ui.view,arch_db:connector.view_connector_checkpoint_search +msgid "Group By..." +msgstr "" + +#. module: connector +#: model:ir.model.fields,field_description:connector.field_connector_backend_id +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_id +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_review_id +#: model:ir.model.fields,field_description:connector.field_connector_config_settings_id +#: model:ir.model.fields,field_description:connector.field_external_binding_id +msgid "ID" +msgstr "" + +#. module: connector +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_backend_id +msgid "Imported from" +msgstr "" + +#. module: connector +#: model:ir.model.fields,field_description:connector.field_connector_backend___last_update +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint___last_update +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_review___last_update +#: model:ir.model.fields,field_description:connector.field_connector_config_settings___last_update +#: model:ir.model.fields,field_description:connector.field_external_binding___last_update +msgid "Last Modified on" +msgstr "" + +#. module: connector +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_review_write_uid +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_write_uid +#: model:ir.model.fields,field_description:connector.field_connector_config_settings_write_uid +msgid "Last Updated by" +msgstr "" + +#. module: connector +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_review_write_date +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_write_date +#: model:ir.model.fields,field_description:connector.field_connector_config_settings_write_date +msgid "Last Updated on" +msgstr "" + +#. module: connector +#: model:ir.model.fields,field_description:connector.field_connector_test_binding_sync_date +#: model:ir.model.fields,field_description:connector.field_external_binding_sync_date +#: model:ir.model.fields,field_description:connector.field_no_inherits_binding_sync_date +msgid "Last synchronization date" +msgstr "" + +#. module: connector +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_model_id +#: model:ir.ui.view,arch_db:connector.view_connector_checkpoint_search +msgid "Model" +msgstr "" + +#. module: connector +#: model:ir.model.fields,field_description:connector.field_connector_backend_name +#: model:ir.model.fields,field_description:connector.field_test_backend_name +msgid "Name" +msgstr "" + +#. module: connector +#: model:ir.model.fields,help:connector.field_connector_checkpoint_name +msgid "Name of the record to review" +msgstr "" + +#. module: connector +#: selection:connector.checkpoint,state:0 +#: model:ir.ui.view,arch_db:connector.view_connector_checkpoint_search +msgid "Need Review" +msgstr "" + +#. module: connector +#: model:ir.actions.act_window,help:connector.action_connector_checkpoint +msgid "No record to check." +msgstr "" + +#. module: connector +#: model:ir.actions.client,name:connector.action_client_connector_menu +msgid "Open Connector Menu" +msgstr "" + +#. module: connector +#: model:ir.model,name:connector.model_queue_job +msgid "Queue Job" +msgstr "" + +#. module: connector +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_record +msgid "Record" +msgstr "" + +#. module: connector +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_record_id +msgid "Record ID" +msgstr "" + +#. module: connector +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_name +msgid "Record Name" +msgstr "" + +#. module: connector +#: code:addons/connector/models/queue_job.py:32 +#, python-format +msgid "Related Record" +msgstr "" + +#. module: connector +#: model:ir.actions.act_window,name:connector.action_connector_checkpoint_review +#: model:ir.ui.view,arch_db:connector.view_connector_checkpoint_review +msgid "Review Checkpoints" +msgstr "" + +#. module: connector +#: selection:connector.checkpoint,state:0 +#: model:ir.ui.view,arch_db:connector.view_connector_checkpoint_form +#: model:ir.ui.view,arch_db:connector.view_connector_checkpoint_search +#: model:ir.ui.view,arch_db:connector.view_connector_checkpoint_tree +msgid "Reviewed" +msgstr "" + +#. module: connector +#: model:ir.ui.view,arch_db:connector.view_connector_checkpoint_review +msgid "Set as reviewed" +msgstr "" + +#. module: connector +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_state +msgid "Status" +msgstr "" + +#. module: connector +#: model:ir.actions.act_window,help:connector.action_connector_checkpoint +msgid "" +"The connectors list the new records to verify\n" +" based on their type. Only some need a manual\n" +" review." +msgstr "" + +#. module: connector +#: model:ir.model.fields,help:connector.field_connector_checkpoint_backend_id +msgid "The record has been imported from this backend" +msgstr "" + +#. module: connector +#: model:ir.model.fields,help:connector.field_connector_checkpoint_record +msgid "The record to review." +msgstr "" + +#. module: connector +#: model:ir.ui.view,arch_db:connector.view_connector_checkpoint_review +msgid "The selected checkpoints will be set as reviewed." +msgstr "" + +#. module: connector +#: model:ir.model.fields,field_description:connector.field_connector_backend_version +msgid "Version" +msgstr "" + +#. module: connector +#: model:ir.actions.act_window,help:connector.action_connector_checkpoint +msgid "" +"When a connector imports new records which have\n" +" configuration or reviews to do manually, they\n" +" will appear in this list. Once a record has been\n" +" checked, click on the 'Reviewed' button." +msgstr "" + +#. module: connector +#: model:ir.model,name:connector.model_base +msgid "base" +msgstr "" + +#. module: connector +#: model:ir.ui.view,arch_db:connector.view_connector_checkpoint_review +#: model:ir.ui.view,arch_db:connector.view_connector_config_settings +msgid "or" +msgstr "" + +#. module: connector +#: model:ir.ui.view,arch_db:connector.view_connector_checkpoint_form +msgid "to verify it:" +msgstr "" diff --git a/ext/3rd-party-addons/connector/i18n/ru.po b/ext/3rd-party-addons/connector/i18n/ru.po new file mode 100644 index 00000000..77bb55a2 --- /dev/null +++ b/ext/3rd-party-addons/connector/i18n/ru.po @@ -0,0 +1,317 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * connector +# +# Translators: +# OCA Transbot , 2017 +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server 10.0\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2017-03-10 03:36+0000\n" +"PO-Revision-Date: 2017-03-10 03:36+0000\n" +"Last-Translator: OCA Transbot , 2017\n" +"Language-Team: Russian (https://www.transifex.com/oca/teams/23907/ru/)\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: \n" +"Language: ru\n" +"Plural-Forms: nplurals=4; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<12 || n%100>14) ? 1 : n%10==0 || (n%10>=5 && n%10<=9) || (n%100>=11 && n%100<=14)? 2 : 3);\n" + +#. module: connector +#: code:addons/connector/checkpoint/checkpoint.py:119 +#, python-format +msgid "A %s needs a review." +msgstr "" + +#. module: connector +#: model:ir.ui.view,arch_db:connector.view_connector_config_settings +msgid "Apply" +msgstr "" + +#. module: connector +#: model:ir.ui.view,arch_db:connector.view_connector_config_settings +msgid "Backends" +msgstr "" + +#. module: connector +#: model:ir.ui.view,arch_db:connector.view_connector_checkpoint_review +#: model:ir.ui.view,arch_db:connector.view_connector_config_settings +msgid "Cancel" +msgstr "Отменена" + +#. module: connector +#: model:ir.ui.menu,name:connector.menu_checkpoint +msgid "Checkpoint" +msgstr "" + +#. module: connector +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_review_checkpoint_ids +msgid "Checkpoints" +msgstr "" + +#. module: connector +#: model:ir.model,name:connector.model_connector_checkpoint_review +msgid "Checkpoints Review" +msgstr "" + +#. module: connector +#: model:ir.ui.view,arch_db:connector.view_connector_checkpoint_form +msgid "Click on the" +msgstr "" + +#. module: connector +#: model:ir.actions.act_window,name:connector.action_connector_config_settings +#: model:ir.ui.view,arch_db:connector.view_connector_config_settings +msgid "Configure Connector" +msgstr "" + +#. module: connector +#: model:ir.module.category,name:connector.module_category_connector +#: model:ir.ui.menu,name:connector.menu_connector_config_settings +msgid "Connector" +msgstr "" + +#. module: connector +#: model:ir.model,name:connector.model_connector_backend +msgid "Connector Backend" +msgstr "" + +#. module: connector +#: model:ir.actions.act_window,name:connector.action_connector_checkpoint +#: model:ir.model,name:connector.model_connector_checkpoint +#: model:ir.ui.view,arch_db:connector.view_connector_checkpoint_form +#: model:ir.ui.view,arch_db:connector.view_connector_checkpoint_search +#: model:ir.ui.view,arch_db:connector.view_connector_checkpoint_tree +msgid "Connector Checkpoint" +msgstr "" + +#. module: connector +#: model:ir.model,name:connector.model_connector_config_settings +msgid "Connector Configuration" +msgstr "" + +#. module: connector +#: model:res.groups,name:connector.group_connector_manager +msgid "Connector Manager" +msgstr "" + +#. module: connector +#: model:ir.ui.menu,name:connector.menu_connector +#: model:ir.ui.menu,name:connector.menu_connector_root +#: model:ir.ui.view,arch_db:connector.view_partner_connector_form +msgid "Connectors" +msgstr "" + +#. module: connector +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_create_uid +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_review_create_uid +#: model:ir.model.fields,field_description:connector.field_connector_config_settings_create_uid +msgid "Created by" +msgstr "" + +#. module: connector +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_create_date +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_review_create_date +#: model:ir.model.fields,field_description:connector.field_connector_config_settings_create_date +msgid "Created on" +msgstr "" + +#. module: connector +#: model:ir.model.fields,field_description:connector.field_connector_backend_display_name +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_display_name +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_review_display_name +#: model:ir.model.fields,field_description:connector.field_connector_config_settings_display_name +#: model:ir.model.fields,field_description:connector.field_external_binding_display_name +msgid "Display Name" +msgstr "" + +#. module: connector +#: model:ir.model,name:connector.model_external_binding +msgid "External Binding (abstract)" +msgstr "" + +#. module: connector +#: model:ir.ui.view,arch_db:connector.view_connector_checkpoint_search +msgid "Group By..." +msgstr "" + +#. module: connector +#: model:ir.model.fields,field_description:connector.field_connector_backend_id +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_id +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_review_id +#: model:ir.model.fields,field_description:connector.field_connector_config_settings_id +#: model:ir.model.fields,field_description:connector.field_external_binding_id +msgid "ID" +msgstr "" + +#. module: connector +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_backend_id +msgid "Imported from" +msgstr "" + +#. module: connector +#: model:ir.model.fields,field_description:connector.field_connector_backend___last_update +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint___last_update +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_review___last_update +#: model:ir.model.fields,field_description:connector.field_connector_config_settings___last_update +#: model:ir.model.fields,field_description:connector.field_external_binding___last_update +msgid "Last Modified on" +msgstr "" + +#. module: connector +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_review_write_uid +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_write_uid +#: model:ir.model.fields,field_description:connector.field_connector_config_settings_write_uid +msgid "Last Updated by" +msgstr "" + +#. module: connector +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_review_write_date +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_write_date +#: model:ir.model.fields,field_description:connector.field_connector_config_settings_write_date +msgid "Last Updated on" +msgstr "" + +#. module: connector +#: model:ir.model.fields,field_description:connector.field_connector_test_binding_sync_date +#: model:ir.model.fields,field_description:connector.field_external_binding_sync_date +#: model:ir.model.fields,field_description:connector.field_no_inherits_binding_sync_date +msgid "Last synchronization date" +msgstr "" + +#. module: connector +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_model_id +#: model:ir.ui.view,arch_db:connector.view_connector_checkpoint_search +msgid "Model" +msgstr "" + +#. module: connector +#: model:ir.model.fields,field_description:connector.field_connector_backend_name +#: model:ir.model.fields,field_description:connector.field_test_backend_name +msgid "Name" +msgstr "" + +#. module: connector +#: model:ir.model.fields,help:connector.field_connector_checkpoint_name +msgid "Name of the record to review" +msgstr "" + +#. module: connector +#: selection:connector.checkpoint,state:0 +#: model:ir.ui.view,arch_db:connector.view_connector_checkpoint_search +msgid "Need Review" +msgstr "" + +#. module: connector +#: model:ir.actions.act_window,help:connector.action_connector_checkpoint +msgid "No record to check." +msgstr "" + +#. module: connector +#: model:ir.actions.client,name:connector.action_client_connector_menu +msgid "Open Connector Menu" +msgstr "" + +#. module: connector +#: model:ir.model,name:connector.model_queue_job +msgid "Queue Job" +msgstr "" + +#. module: connector +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_record +msgid "Record" +msgstr "" + +#. module: connector +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_record_id +msgid "Record ID" +msgstr "" + +#. module: connector +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_name +msgid "Record Name" +msgstr "" + +#. module: connector +#: code:addons/connector/models/queue_job.py:32 +#, python-format +msgid "Related Record" +msgstr "" + +#. module: connector +#: model:ir.actions.act_window,name:connector.action_connector_checkpoint_review +#: model:ir.ui.view,arch_db:connector.view_connector_checkpoint_review +msgid "Review Checkpoints" +msgstr "" + +#. module: connector +#: selection:connector.checkpoint,state:0 +#: model:ir.ui.view,arch_db:connector.view_connector_checkpoint_form +#: model:ir.ui.view,arch_db:connector.view_connector_checkpoint_search +#: model:ir.ui.view,arch_db:connector.view_connector_checkpoint_tree +msgid "Reviewed" +msgstr "" + +#. module: connector +#: model:ir.ui.view,arch_db:connector.view_connector_checkpoint_review +msgid "Set as reviewed" +msgstr "" + +#. module: connector +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_state +msgid "Status" +msgstr "" + +#. module: connector +#: model:ir.actions.act_window,help:connector.action_connector_checkpoint +msgid "" +"The connectors list the new records to verify\n" +" based on their type. Only some need a manual\n" +" review." +msgstr "" + +#. module: connector +#: model:ir.model.fields,help:connector.field_connector_checkpoint_backend_id +msgid "The record has been imported from this backend" +msgstr "" + +#. module: connector +#: model:ir.model.fields,help:connector.field_connector_checkpoint_record +msgid "The record to review." +msgstr "" + +#. module: connector +#: model:ir.ui.view,arch_db:connector.view_connector_checkpoint_review +msgid "The selected checkpoints will be set as reviewed." +msgstr "" + +#. module: connector +#: model:ir.model.fields,field_description:connector.field_connector_backend_version +msgid "Version" +msgstr "" + +#. module: connector +#: model:ir.actions.act_window,help:connector.action_connector_checkpoint +msgid "" +"When a connector imports new records which have\n" +" configuration or reviews to do manually, they\n" +" will appear in this list. Once a record has been\n" +" checked, click on the 'Reviewed' button." +msgstr "" + +#. module: connector +#: model:ir.model,name:connector.model_base +msgid "base" +msgstr "" + +#. module: connector +#: model:ir.ui.view,arch_db:connector.view_connector_checkpoint_review +#: model:ir.ui.view,arch_db:connector.view_connector_config_settings +msgid "or" +msgstr "" + +#. module: connector +#: model:ir.ui.view,arch_db:connector.view_connector_checkpoint_form +msgid "to verify it:" +msgstr "" diff --git a/ext/3rd-party-addons/connector/i18n/sl.po b/ext/3rd-party-addons/connector/i18n/sl.po new file mode 100644 index 00000000..03ad497c --- /dev/null +++ b/ext/3rd-party-addons/connector/i18n/sl.po @@ -0,0 +1,317 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * connector +# +# Translators: +# OCA Transbot , 2017 +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server 10.0\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2017-03-10 03:36+0000\n" +"PO-Revision-Date: 2017-03-10 03:36+0000\n" +"Last-Translator: OCA Transbot , 2017\n" +"Language-Team: Slovenian (https://www.transifex.com/oca/teams/23907/sl/)\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: \n" +"Language: sl\n" +"Plural-Forms: nplurals=4; plural=(n%100==1 ? 0 : n%100==2 ? 1 : n%100==3 || n%100==4 ? 2 : 3);\n" + +#. module: connector +#: code:addons/connector/checkpoint/checkpoint.py:119 +#, python-format +msgid "A %s needs a review." +msgstr "Potrebna je revizija %s ." + +#. module: connector +#: model:ir.ui.view,arch_db:connector.view_connector_config_settings +msgid "Apply" +msgstr "Uporabi" + +#. module: connector +#: model:ir.ui.view,arch_db:connector.view_connector_config_settings +msgid "Backends" +msgstr "Ozadja" + +#. module: connector +#: model:ir.ui.view,arch_db:connector.view_connector_checkpoint_review +#: model:ir.ui.view,arch_db:connector.view_connector_config_settings +msgid "Cancel" +msgstr "Preklic" + +#. module: connector +#: model:ir.ui.menu,name:connector.menu_checkpoint +msgid "Checkpoint" +msgstr "Kontrolna točka" + +#. module: connector +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_review_checkpoint_ids +msgid "Checkpoints" +msgstr "Kontrolne točke" + +#. module: connector +#: model:ir.model,name:connector.model_connector_checkpoint_review +msgid "Checkpoints Review" +msgstr "Preverjanje kontrolnih točk" + +#. module: connector +#: model:ir.ui.view,arch_db:connector.view_connector_checkpoint_form +msgid "Click on the" +msgstr "Kliknite na" + +#. module: connector +#: model:ir.actions.act_window,name:connector.action_connector_config_settings +#: model:ir.ui.view,arch_db:connector.view_connector_config_settings +msgid "Configure Connector" +msgstr "Nastavitve povezovalnika" + +#. module: connector +#: model:ir.module.category,name:connector.module_category_connector +#: model:ir.ui.menu,name:connector.menu_connector_config_settings +msgid "Connector" +msgstr "Povezovalnik" + +#. module: connector +#: model:ir.model,name:connector.model_connector_backend +msgid "Connector Backend" +msgstr "Ozadje povezovalnika" + +#. module: connector +#: model:ir.actions.act_window,name:connector.action_connector_checkpoint +#: model:ir.model,name:connector.model_connector_checkpoint +#: model:ir.ui.view,arch_db:connector.view_connector_checkpoint_form +#: model:ir.ui.view,arch_db:connector.view_connector_checkpoint_search +#: model:ir.ui.view,arch_db:connector.view_connector_checkpoint_tree +msgid "Connector Checkpoint" +msgstr "Kontrolna točka povezovalnika" + +#. module: connector +#: model:ir.model,name:connector.model_connector_config_settings +msgid "Connector Configuration" +msgstr "Nastavitve povezovalnika" + +#. module: connector +#: model:res.groups,name:connector.group_connector_manager +msgid "Connector Manager" +msgstr "Upravitelj povezovalnika" + +#. module: connector +#: model:ir.ui.menu,name:connector.menu_connector +#: model:ir.ui.menu,name:connector.menu_connector_root +#: model:ir.ui.view,arch_db:connector.view_partner_connector_form +msgid "Connectors" +msgstr "Konektorji" + +#. module: connector +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_create_uid +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_review_create_uid +#: model:ir.model.fields,field_description:connector.field_connector_config_settings_create_uid +msgid "Created by" +msgstr "Ustvaril" + +#. module: connector +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_create_date +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_review_create_date +#: model:ir.model.fields,field_description:connector.field_connector_config_settings_create_date +msgid "Created on" +msgstr "Ustvarjeno" + +#. module: connector +#: model:ir.model.fields,field_description:connector.field_connector_backend_display_name +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_display_name +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_review_display_name +#: model:ir.model.fields,field_description:connector.field_connector_config_settings_display_name +#: model:ir.model.fields,field_description:connector.field_external_binding_display_name +msgid "Display Name" +msgstr "Prikazni naziv" + +#. module: connector +#: model:ir.model,name:connector.model_external_binding +msgid "External Binding (abstract)" +msgstr "Zunanja povezava (povzetek)" + +#. module: connector +#: model:ir.ui.view,arch_db:connector.view_connector_checkpoint_search +msgid "Group By..." +msgstr "Združi po..." + +#. module: connector +#: model:ir.model.fields,field_description:connector.field_connector_backend_id +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_id +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_review_id +#: model:ir.model.fields,field_description:connector.field_connector_config_settings_id +#: model:ir.model.fields,field_description:connector.field_external_binding_id +msgid "ID" +msgstr "ID" + +#. module: connector +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_backend_id +msgid "Imported from" +msgstr "Uvoženo iz" + +#. module: connector +#: model:ir.model.fields,field_description:connector.field_connector_backend___last_update +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint___last_update +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_review___last_update +#: model:ir.model.fields,field_description:connector.field_connector_config_settings___last_update +#: model:ir.model.fields,field_description:connector.field_external_binding___last_update +msgid "Last Modified on" +msgstr "Zadnjič spremenjeno" + +#. module: connector +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_review_write_uid +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_write_uid +#: model:ir.model.fields,field_description:connector.field_connector_config_settings_write_uid +msgid "Last Updated by" +msgstr "Zadnji posodobil" + +#. module: connector +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_review_write_date +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_write_date +#: model:ir.model.fields,field_description:connector.field_connector_config_settings_write_date +msgid "Last Updated on" +msgstr "Zadnjič posodobljeno" + +#. module: connector +#: model:ir.model.fields,field_description:connector.field_connector_test_binding_sync_date +#: model:ir.model.fields,field_description:connector.field_external_binding_sync_date +#: model:ir.model.fields,field_description:connector.field_no_inherits_binding_sync_date +msgid "Last synchronization date" +msgstr "Datum zadnje sinhronizacije" + +#. module: connector +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_model_id +#: model:ir.ui.view,arch_db:connector.view_connector_checkpoint_search +msgid "Model" +msgstr "Model" + +#. module: connector +#: model:ir.model.fields,field_description:connector.field_connector_backend_name +#: model:ir.model.fields,field_description:connector.field_test_backend_name +msgid "Name" +msgstr "Naziv" + +#. module: connector +#: model:ir.model.fields,help:connector.field_connector_checkpoint_name +msgid "Name of the record to review" +msgstr "" + +#. module: connector +#: selection:connector.checkpoint,state:0 +#: model:ir.ui.view,arch_db:connector.view_connector_checkpoint_search +msgid "Need Review" +msgstr "Potrebna revizija" + +#. module: connector +#: model:ir.actions.act_window,help:connector.action_connector_checkpoint +msgid "No record to check." +msgstr "" + +#. module: connector +#: model:ir.actions.client,name:connector.action_client_connector_menu +msgid "Open Connector Menu" +msgstr "Odpri meni povezovalnika" + +#. module: connector +#: model:ir.model,name:connector.model_queue_job +msgid "Queue Job" +msgstr "Delo čakalne vrste" + +#. module: connector +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_record +msgid "Record" +msgstr "" + +#. module: connector +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_record_id +msgid "Record ID" +msgstr "ID zapisa" + +#. module: connector +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_name +msgid "Record Name" +msgstr "" + +#. module: connector +#: code:addons/connector/models/queue_job.py:32 +#, python-format +msgid "Related Record" +msgstr "Povezani zapis" + +#. module: connector +#: model:ir.actions.act_window,name:connector.action_connector_checkpoint_review +#: model:ir.ui.view,arch_db:connector.view_connector_checkpoint_review +msgid "Review Checkpoints" +msgstr "Pregled kontrolnih točk" + +#. module: connector +#: selection:connector.checkpoint,state:0 +#: model:ir.ui.view,arch_db:connector.view_connector_checkpoint_form +#: model:ir.ui.view,arch_db:connector.view_connector_checkpoint_search +#: model:ir.ui.view,arch_db:connector.view_connector_checkpoint_tree +msgid "Reviewed" +msgstr "Pregledano" + +#. module: connector +#: model:ir.ui.view,arch_db:connector.view_connector_checkpoint_review +msgid "Set as reviewed" +msgstr "Nastavi kot pregledano" + +#. module: connector +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_state +msgid "Status" +msgstr "Status" + +#. module: connector +#: model:ir.actions.act_window,help:connector.action_connector_checkpoint +msgid "" +"The connectors list the new records to verify\n" +" based on their type. Only some need a manual\n" +" review." +msgstr "" + +#. module: connector +#: model:ir.model.fields,help:connector.field_connector_checkpoint_backend_id +msgid "The record has been imported from this backend" +msgstr "Zapis je bil uvožen iz tega ozadja." + +#. module: connector +#: model:ir.model.fields,help:connector.field_connector_checkpoint_record +msgid "The record to review." +msgstr "" + +#. module: connector +#: model:ir.ui.view,arch_db:connector.view_connector_checkpoint_review +msgid "The selected checkpoints will be set as reviewed." +msgstr "Izbrane kontrolne točke bodo označene kot pregledane." + +#. module: connector +#: model:ir.model.fields,field_description:connector.field_connector_backend_version +msgid "Version" +msgstr "Verzija" + +#. module: connector +#: model:ir.actions.act_window,help:connector.action_connector_checkpoint +msgid "" +"When a connector imports new records which have\n" +" configuration or reviews to do manually, they\n" +" will appear in this list. Once a record has been\n" +" checked, click on the 'Reviewed' button." +msgstr "" + +#. module: connector +#: model:ir.model,name:connector.model_base +msgid "base" +msgstr "" + +#. module: connector +#: model:ir.ui.view,arch_db:connector.view_connector_checkpoint_review +#: model:ir.ui.view,arch_db:connector.view_connector_config_settings +msgid "or" +msgstr "ali" + +#. module: connector +#: model:ir.ui.view,arch_db:connector.view_connector_checkpoint_form +msgid "to verify it:" +msgstr "za preverjanje:" diff --git a/ext/3rd-party-addons/connector/i18n/th.po b/ext/3rd-party-addons/connector/i18n/th.po new file mode 100644 index 00000000..5ad4a6dd --- /dev/null +++ b/ext/3rd-party-addons/connector/i18n/th.po @@ -0,0 +1,317 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * connector +# +# Translators: +# OCA Transbot , 2017 +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server 10.0\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2017-03-10 03:36+0000\n" +"PO-Revision-Date: 2017-03-10 03:36+0000\n" +"Last-Translator: OCA Transbot , 2017\n" +"Language-Team: Thai (https://www.transifex.com/oca/teams/23907/th/)\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: \n" +"Language: th\n" +"Plural-Forms: nplurals=1; plural=0;\n" + +#. module: connector +#: code:addons/connector/checkpoint/checkpoint.py:119 +#, python-format +msgid "A %s needs a review." +msgstr "" + +#. module: connector +#: model:ir.ui.view,arch_db:connector.view_connector_config_settings +msgid "Apply" +msgstr "" + +#. module: connector +#: model:ir.ui.view,arch_db:connector.view_connector_config_settings +msgid "Backends" +msgstr "" + +#. module: connector +#: model:ir.ui.view,arch_db:connector.view_connector_checkpoint_review +#: model:ir.ui.view,arch_db:connector.view_connector_config_settings +msgid "Cancel" +msgstr "ยกเลิก" + +#. module: connector +#: model:ir.ui.menu,name:connector.menu_checkpoint +msgid "Checkpoint" +msgstr "" + +#. module: connector +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_review_checkpoint_ids +msgid "Checkpoints" +msgstr "" + +#. module: connector +#: model:ir.model,name:connector.model_connector_checkpoint_review +msgid "Checkpoints Review" +msgstr "" + +#. module: connector +#: model:ir.ui.view,arch_db:connector.view_connector_checkpoint_form +msgid "Click on the" +msgstr "" + +#. module: connector +#: model:ir.actions.act_window,name:connector.action_connector_config_settings +#: model:ir.ui.view,arch_db:connector.view_connector_config_settings +msgid "Configure Connector" +msgstr "" + +#. module: connector +#: model:ir.module.category,name:connector.module_category_connector +#: model:ir.ui.menu,name:connector.menu_connector_config_settings +msgid "Connector" +msgstr "" + +#. module: connector +#: model:ir.model,name:connector.model_connector_backend +msgid "Connector Backend" +msgstr "" + +#. module: connector +#: model:ir.actions.act_window,name:connector.action_connector_checkpoint +#: model:ir.model,name:connector.model_connector_checkpoint +#: model:ir.ui.view,arch_db:connector.view_connector_checkpoint_form +#: model:ir.ui.view,arch_db:connector.view_connector_checkpoint_search +#: model:ir.ui.view,arch_db:connector.view_connector_checkpoint_tree +msgid "Connector Checkpoint" +msgstr "" + +#. module: connector +#: model:ir.model,name:connector.model_connector_config_settings +msgid "Connector Configuration" +msgstr "" + +#. module: connector +#: model:res.groups,name:connector.group_connector_manager +msgid "Connector Manager" +msgstr "" + +#. module: connector +#: model:ir.ui.menu,name:connector.menu_connector +#: model:ir.ui.menu,name:connector.menu_connector_root +#: model:ir.ui.view,arch_db:connector.view_partner_connector_form +msgid "Connectors" +msgstr "" + +#. module: connector +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_create_uid +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_review_create_uid +#: model:ir.model.fields,field_description:connector.field_connector_config_settings_create_uid +msgid "Created by" +msgstr "" + +#. module: connector +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_create_date +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_review_create_date +#: model:ir.model.fields,field_description:connector.field_connector_config_settings_create_date +msgid "Created on" +msgstr "" + +#. module: connector +#: model:ir.model.fields,field_description:connector.field_connector_backend_display_name +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_display_name +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_review_display_name +#: model:ir.model.fields,field_description:connector.field_connector_config_settings_display_name +#: model:ir.model.fields,field_description:connector.field_external_binding_display_name +msgid "Display Name" +msgstr "" + +#. module: connector +#: model:ir.model,name:connector.model_external_binding +msgid "External Binding (abstract)" +msgstr "" + +#. module: connector +#: model:ir.ui.view,arch_db:connector.view_connector_checkpoint_search +msgid "Group By..." +msgstr "" + +#. module: connector +#: model:ir.model.fields,field_description:connector.field_connector_backend_id +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_id +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_review_id +#: model:ir.model.fields,field_description:connector.field_connector_config_settings_id +#: model:ir.model.fields,field_description:connector.field_external_binding_id +msgid "ID" +msgstr "" + +#. module: connector +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_backend_id +msgid "Imported from" +msgstr "" + +#. module: connector +#: model:ir.model.fields,field_description:connector.field_connector_backend___last_update +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint___last_update +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_review___last_update +#: model:ir.model.fields,field_description:connector.field_connector_config_settings___last_update +#: model:ir.model.fields,field_description:connector.field_external_binding___last_update +msgid "Last Modified on" +msgstr "" + +#. module: connector +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_review_write_uid +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_write_uid +#: model:ir.model.fields,field_description:connector.field_connector_config_settings_write_uid +msgid "Last Updated by" +msgstr "" + +#. module: connector +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_review_write_date +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_write_date +#: model:ir.model.fields,field_description:connector.field_connector_config_settings_write_date +msgid "Last Updated on" +msgstr "" + +#. module: connector +#: model:ir.model.fields,field_description:connector.field_connector_test_binding_sync_date +#: model:ir.model.fields,field_description:connector.field_external_binding_sync_date +#: model:ir.model.fields,field_description:connector.field_no_inherits_binding_sync_date +msgid "Last synchronization date" +msgstr "" + +#. module: connector +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_model_id +#: model:ir.ui.view,arch_db:connector.view_connector_checkpoint_search +msgid "Model" +msgstr "" + +#. module: connector +#: model:ir.model.fields,field_description:connector.field_connector_backend_name +#: model:ir.model.fields,field_description:connector.field_test_backend_name +msgid "Name" +msgstr "" + +#. module: connector +#: model:ir.model.fields,help:connector.field_connector_checkpoint_name +msgid "Name of the record to review" +msgstr "" + +#. module: connector +#: selection:connector.checkpoint,state:0 +#: model:ir.ui.view,arch_db:connector.view_connector_checkpoint_search +msgid "Need Review" +msgstr "" + +#. module: connector +#: model:ir.actions.act_window,help:connector.action_connector_checkpoint +msgid "No record to check." +msgstr "" + +#. module: connector +#: model:ir.actions.client,name:connector.action_client_connector_menu +msgid "Open Connector Menu" +msgstr "" + +#. module: connector +#: model:ir.model,name:connector.model_queue_job +msgid "Queue Job" +msgstr "" + +#. module: connector +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_record +msgid "Record" +msgstr "" + +#. module: connector +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_record_id +msgid "Record ID" +msgstr "" + +#. module: connector +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_name +msgid "Record Name" +msgstr "" + +#. module: connector +#: code:addons/connector/models/queue_job.py:32 +#, python-format +msgid "Related Record" +msgstr "" + +#. module: connector +#: model:ir.actions.act_window,name:connector.action_connector_checkpoint_review +#: model:ir.ui.view,arch_db:connector.view_connector_checkpoint_review +msgid "Review Checkpoints" +msgstr "" + +#. module: connector +#: selection:connector.checkpoint,state:0 +#: model:ir.ui.view,arch_db:connector.view_connector_checkpoint_form +#: model:ir.ui.view,arch_db:connector.view_connector_checkpoint_search +#: model:ir.ui.view,arch_db:connector.view_connector_checkpoint_tree +msgid "Reviewed" +msgstr "" + +#. module: connector +#: model:ir.ui.view,arch_db:connector.view_connector_checkpoint_review +msgid "Set as reviewed" +msgstr "" + +#. module: connector +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_state +msgid "Status" +msgstr "" + +#. module: connector +#: model:ir.actions.act_window,help:connector.action_connector_checkpoint +msgid "" +"The connectors list the new records to verify\n" +" based on their type. Only some need a manual\n" +" review." +msgstr "" + +#. module: connector +#: model:ir.model.fields,help:connector.field_connector_checkpoint_backend_id +msgid "The record has been imported from this backend" +msgstr "" + +#. module: connector +#: model:ir.model.fields,help:connector.field_connector_checkpoint_record +msgid "The record to review." +msgstr "" + +#. module: connector +#: model:ir.ui.view,arch_db:connector.view_connector_checkpoint_review +msgid "The selected checkpoints will be set as reviewed." +msgstr "" + +#. module: connector +#: model:ir.model.fields,field_description:connector.field_connector_backend_version +msgid "Version" +msgstr "" + +#. module: connector +#: model:ir.actions.act_window,help:connector.action_connector_checkpoint +msgid "" +"When a connector imports new records which have\n" +" configuration or reviews to do manually, they\n" +" will appear in this list. Once a record has been\n" +" checked, click on the 'Reviewed' button." +msgstr "" + +#. module: connector +#: model:ir.model,name:connector.model_base +msgid "base" +msgstr "" + +#. module: connector +#: model:ir.ui.view,arch_db:connector.view_connector_checkpoint_review +#: model:ir.ui.view,arch_db:connector.view_connector_config_settings +msgid "or" +msgstr "" + +#. module: connector +#: model:ir.ui.view,arch_db:connector.view_connector_checkpoint_form +msgid "to verify it:" +msgstr "" diff --git a/ext/3rd-party-addons/connector/i18n/tr.po b/ext/3rd-party-addons/connector/i18n/tr.po new file mode 100644 index 00000000..7977c681 --- /dev/null +++ b/ext/3rd-party-addons/connector/i18n/tr.po @@ -0,0 +1,317 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * connector +# +# Translators: +# OCA Transbot , 2017 +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server 10.0\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2017-03-10 03:36+0000\n" +"PO-Revision-Date: 2017-03-10 03:36+0000\n" +"Last-Translator: OCA Transbot , 2017\n" +"Language-Team: Turkish (https://www.transifex.com/oca/teams/23907/tr/)\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: \n" +"Language: tr\n" +"Plural-Forms: nplurals=2; plural=(n > 1);\n" + +#. module: connector +#: code:addons/connector/checkpoint/checkpoint.py:119 +#, python-format +msgid "A %s needs a review." +msgstr "" + +#. module: connector +#: model:ir.ui.view,arch_db:connector.view_connector_config_settings +msgid "Apply" +msgstr "" + +#. module: connector +#: model:ir.ui.view,arch_db:connector.view_connector_config_settings +msgid "Backends" +msgstr "" + +#. module: connector +#: model:ir.ui.view,arch_db:connector.view_connector_checkpoint_review +#: model:ir.ui.view,arch_db:connector.view_connector_config_settings +msgid "Cancel" +msgstr "Vazgeç" + +#. module: connector +#: model:ir.ui.menu,name:connector.menu_checkpoint +msgid "Checkpoint" +msgstr "" + +#. module: connector +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_review_checkpoint_ids +msgid "Checkpoints" +msgstr "" + +#. module: connector +#: model:ir.model,name:connector.model_connector_checkpoint_review +msgid "Checkpoints Review" +msgstr "" + +#. module: connector +#: model:ir.ui.view,arch_db:connector.view_connector_checkpoint_form +msgid "Click on the" +msgstr "" + +#. module: connector +#: model:ir.actions.act_window,name:connector.action_connector_config_settings +#: model:ir.ui.view,arch_db:connector.view_connector_config_settings +msgid "Configure Connector" +msgstr "" + +#. module: connector +#: model:ir.module.category,name:connector.module_category_connector +#: model:ir.ui.menu,name:connector.menu_connector_config_settings +msgid "Connector" +msgstr "" + +#. module: connector +#: model:ir.model,name:connector.model_connector_backend +msgid "Connector Backend" +msgstr "" + +#. module: connector +#: model:ir.actions.act_window,name:connector.action_connector_checkpoint +#: model:ir.model,name:connector.model_connector_checkpoint +#: model:ir.ui.view,arch_db:connector.view_connector_checkpoint_form +#: model:ir.ui.view,arch_db:connector.view_connector_checkpoint_search +#: model:ir.ui.view,arch_db:connector.view_connector_checkpoint_tree +msgid "Connector Checkpoint" +msgstr "" + +#. module: connector +#: model:ir.model,name:connector.model_connector_config_settings +msgid "Connector Configuration" +msgstr "" + +#. module: connector +#: model:res.groups,name:connector.group_connector_manager +msgid "Connector Manager" +msgstr "" + +#. module: connector +#: model:ir.ui.menu,name:connector.menu_connector +#: model:ir.ui.menu,name:connector.menu_connector_root +#: model:ir.ui.view,arch_db:connector.view_partner_connector_form +msgid "Connectors" +msgstr "" + +#. module: connector +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_create_uid +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_review_create_uid +#: model:ir.model.fields,field_description:connector.field_connector_config_settings_create_uid +msgid "Created by" +msgstr "Oluşturan" + +#. module: connector +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_create_date +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_review_create_date +#: model:ir.model.fields,field_description:connector.field_connector_config_settings_create_date +msgid "Created on" +msgstr "Oluşturuldu" + +#. module: connector +#: model:ir.model.fields,field_description:connector.field_connector_backend_display_name +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_display_name +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_review_display_name +#: model:ir.model.fields,field_description:connector.field_connector_config_settings_display_name +#: model:ir.model.fields,field_description:connector.field_external_binding_display_name +msgid "Display Name" +msgstr "" + +#. module: connector +#: model:ir.model,name:connector.model_external_binding +msgid "External Binding (abstract)" +msgstr "" + +#. module: connector +#: model:ir.ui.view,arch_db:connector.view_connector_checkpoint_search +msgid "Group By..." +msgstr "" + +#. module: connector +#: model:ir.model.fields,field_description:connector.field_connector_backend_id +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_id +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_review_id +#: model:ir.model.fields,field_description:connector.field_connector_config_settings_id +#: model:ir.model.fields,field_description:connector.field_external_binding_id +msgid "ID" +msgstr "ID" + +#. module: connector +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_backend_id +msgid "Imported from" +msgstr "" + +#. module: connector +#: model:ir.model.fields,field_description:connector.field_connector_backend___last_update +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint___last_update +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_review___last_update +#: model:ir.model.fields,field_description:connector.field_connector_config_settings___last_update +#: model:ir.model.fields,field_description:connector.field_external_binding___last_update +msgid "Last Modified on" +msgstr "" + +#. module: connector +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_review_write_uid +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_write_uid +#: model:ir.model.fields,field_description:connector.field_connector_config_settings_write_uid +msgid "Last Updated by" +msgstr "Son güncelleyen" + +#. module: connector +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_review_write_date +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_write_date +#: model:ir.model.fields,field_description:connector.field_connector_config_settings_write_date +msgid "Last Updated on" +msgstr "Son güncelleme" + +#. module: connector +#: model:ir.model.fields,field_description:connector.field_connector_test_binding_sync_date +#: model:ir.model.fields,field_description:connector.field_external_binding_sync_date +#: model:ir.model.fields,field_description:connector.field_no_inherits_binding_sync_date +msgid "Last synchronization date" +msgstr "" + +#. module: connector +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_model_id +#: model:ir.ui.view,arch_db:connector.view_connector_checkpoint_search +msgid "Model" +msgstr "" + +#. module: connector +#: model:ir.model.fields,field_description:connector.field_connector_backend_name +#: model:ir.model.fields,field_description:connector.field_test_backend_name +msgid "Name" +msgstr "" + +#. module: connector +#: model:ir.model.fields,help:connector.field_connector_checkpoint_name +msgid "Name of the record to review" +msgstr "" + +#. module: connector +#: selection:connector.checkpoint,state:0 +#: model:ir.ui.view,arch_db:connector.view_connector_checkpoint_search +msgid "Need Review" +msgstr "" + +#. module: connector +#: model:ir.actions.act_window,help:connector.action_connector_checkpoint +msgid "No record to check." +msgstr "" + +#. module: connector +#: model:ir.actions.client,name:connector.action_client_connector_menu +msgid "Open Connector Menu" +msgstr "" + +#. module: connector +#: model:ir.model,name:connector.model_queue_job +msgid "Queue Job" +msgstr "" + +#. module: connector +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_record +msgid "Record" +msgstr "" + +#. module: connector +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_record_id +msgid "Record ID" +msgstr "" + +#. module: connector +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_name +msgid "Record Name" +msgstr "" + +#. module: connector +#: code:addons/connector/models/queue_job.py:32 +#, python-format +msgid "Related Record" +msgstr "" + +#. module: connector +#: model:ir.actions.act_window,name:connector.action_connector_checkpoint_review +#: model:ir.ui.view,arch_db:connector.view_connector_checkpoint_review +msgid "Review Checkpoints" +msgstr "" + +#. module: connector +#: selection:connector.checkpoint,state:0 +#: model:ir.ui.view,arch_db:connector.view_connector_checkpoint_form +#: model:ir.ui.view,arch_db:connector.view_connector_checkpoint_search +#: model:ir.ui.view,arch_db:connector.view_connector_checkpoint_tree +msgid "Reviewed" +msgstr "" + +#. module: connector +#: model:ir.ui.view,arch_db:connector.view_connector_checkpoint_review +msgid "Set as reviewed" +msgstr "" + +#. module: connector +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_state +msgid "Status" +msgstr "" + +#. module: connector +#: model:ir.actions.act_window,help:connector.action_connector_checkpoint +msgid "" +"The connectors list the new records to verify\n" +" based on their type. Only some need a manual\n" +" review." +msgstr "" + +#. module: connector +#: model:ir.model.fields,help:connector.field_connector_checkpoint_backend_id +msgid "The record has been imported from this backend" +msgstr "" + +#. module: connector +#: model:ir.model.fields,help:connector.field_connector_checkpoint_record +msgid "The record to review." +msgstr "" + +#. module: connector +#: model:ir.ui.view,arch_db:connector.view_connector_checkpoint_review +msgid "The selected checkpoints will be set as reviewed." +msgstr "" + +#. module: connector +#: model:ir.model.fields,field_description:connector.field_connector_backend_version +msgid "Version" +msgstr "" + +#. module: connector +#: model:ir.actions.act_window,help:connector.action_connector_checkpoint +msgid "" +"When a connector imports new records which have\n" +" configuration or reviews to do manually, they\n" +" will appear in this list. Once a record has been\n" +" checked, click on the 'Reviewed' button." +msgstr "" + +#. module: connector +#: model:ir.model,name:connector.model_base +msgid "base" +msgstr "" + +#. module: connector +#: model:ir.ui.view,arch_db:connector.view_connector_checkpoint_review +#: model:ir.ui.view,arch_db:connector.view_connector_config_settings +msgid "or" +msgstr "" + +#. module: connector +#: model:ir.ui.view,arch_db:connector.view_connector_checkpoint_form +msgid "to verify it:" +msgstr "" diff --git a/ext/3rd-party-addons/connector/i18n/vi.po b/ext/3rd-party-addons/connector/i18n/vi.po new file mode 100644 index 00000000..82e20cca --- /dev/null +++ b/ext/3rd-party-addons/connector/i18n/vi.po @@ -0,0 +1,317 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * connector +# +# Translators: +# OCA Transbot , 2017 +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server 10.0\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2017-03-10 03:36+0000\n" +"PO-Revision-Date: 2017-03-10 03:36+0000\n" +"Last-Translator: OCA Transbot , 2017\n" +"Language-Team: Vietnamese (https://www.transifex.com/oca/teams/23907/vi/)\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: \n" +"Language: vi\n" +"Plural-Forms: nplurals=1; plural=0;\n" + +#. module: connector +#: code:addons/connector/checkpoint/checkpoint.py:119 +#, python-format +msgid "A %s needs a review." +msgstr "" + +#. module: connector +#: model:ir.ui.view,arch_db:connector.view_connector_config_settings +msgid "Apply" +msgstr "" + +#. module: connector +#: model:ir.ui.view,arch_db:connector.view_connector_config_settings +msgid "Backends" +msgstr "" + +#. module: connector +#: model:ir.ui.view,arch_db:connector.view_connector_checkpoint_review +#: model:ir.ui.view,arch_db:connector.view_connector_config_settings +msgid "Cancel" +msgstr "Hủy bỏ" + +#. module: connector +#: model:ir.ui.menu,name:connector.menu_checkpoint +msgid "Checkpoint" +msgstr "" + +#. module: connector +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_review_checkpoint_ids +msgid "Checkpoints" +msgstr "" + +#. module: connector +#: model:ir.model,name:connector.model_connector_checkpoint_review +msgid "Checkpoints Review" +msgstr "" + +#. module: connector +#: model:ir.ui.view,arch_db:connector.view_connector_checkpoint_form +msgid "Click on the" +msgstr "" + +#. module: connector +#: model:ir.actions.act_window,name:connector.action_connector_config_settings +#: model:ir.ui.view,arch_db:connector.view_connector_config_settings +msgid "Configure Connector" +msgstr "" + +#. module: connector +#: model:ir.module.category,name:connector.module_category_connector +#: model:ir.ui.menu,name:connector.menu_connector_config_settings +msgid "Connector" +msgstr "" + +#. module: connector +#: model:ir.model,name:connector.model_connector_backend +msgid "Connector Backend" +msgstr "" + +#. module: connector +#: model:ir.actions.act_window,name:connector.action_connector_checkpoint +#: model:ir.model,name:connector.model_connector_checkpoint +#: model:ir.ui.view,arch_db:connector.view_connector_checkpoint_form +#: model:ir.ui.view,arch_db:connector.view_connector_checkpoint_search +#: model:ir.ui.view,arch_db:connector.view_connector_checkpoint_tree +msgid "Connector Checkpoint" +msgstr "" + +#. module: connector +#: model:ir.model,name:connector.model_connector_config_settings +msgid "Connector Configuration" +msgstr "" + +#. module: connector +#: model:res.groups,name:connector.group_connector_manager +msgid "Connector Manager" +msgstr "" + +#. module: connector +#: model:ir.ui.menu,name:connector.menu_connector +#: model:ir.ui.menu,name:connector.menu_connector_root +#: model:ir.ui.view,arch_db:connector.view_partner_connector_form +msgid "Connectors" +msgstr "" + +#. module: connector +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_create_uid +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_review_create_uid +#: model:ir.model.fields,field_description:connector.field_connector_config_settings_create_uid +msgid "Created by" +msgstr "" + +#. module: connector +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_create_date +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_review_create_date +#: model:ir.model.fields,field_description:connector.field_connector_config_settings_create_date +msgid "Created on" +msgstr "" + +#. module: connector +#: model:ir.model.fields,field_description:connector.field_connector_backend_display_name +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_display_name +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_review_display_name +#: model:ir.model.fields,field_description:connector.field_connector_config_settings_display_name +#: model:ir.model.fields,field_description:connector.field_external_binding_display_name +msgid "Display Name" +msgstr "" + +#. module: connector +#: model:ir.model,name:connector.model_external_binding +msgid "External Binding (abstract)" +msgstr "" + +#. module: connector +#: model:ir.ui.view,arch_db:connector.view_connector_checkpoint_search +msgid "Group By..." +msgstr "" + +#. module: connector +#: model:ir.model.fields,field_description:connector.field_connector_backend_id +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_id +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_review_id +#: model:ir.model.fields,field_description:connector.field_connector_config_settings_id +#: model:ir.model.fields,field_description:connector.field_external_binding_id +msgid "ID" +msgstr "" + +#. module: connector +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_backend_id +msgid "Imported from" +msgstr "" + +#. module: connector +#: model:ir.model.fields,field_description:connector.field_connector_backend___last_update +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint___last_update +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_review___last_update +#: model:ir.model.fields,field_description:connector.field_connector_config_settings___last_update +#: model:ir.model.fields,field_description:connector.field_external_binding___last_update +msgid "Last Modified on" +msgstr "" + +#. module: connector +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_review_write_uid +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_write_uid +#: model:ir.model.fields,field_description:connector.field_connector_config_settings_write_uid +msgid "Last Updated by" +msgstr "" + +#. module: connector +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_review_write_date +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_write_date +#: model:ir.model.fields,field_description:connector.field_connector_config_settings_write_date +msgid "Last Updated on" +msgstr "" + +#. module: connector +#: model:ir.model.fields,field_description:connector.field_connector_test_binding_sync_date +#: model:ir.model.fields,field_description:connector.field_external_binding_sync_date +#: model:ir.model.fields,field_description:connector.field_no_inherits_binding_sync_date +msgid "Last synchronization date" +msgstr "" + +#. module: connector +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_model_id +#: model:ir.ui.view,arch_db:connector.view_connector_checkpoint_search +msgid "Model" +msgstr "" + +#. module: connector +#: model:ir.model.fields,field_description:connector.field_connector_backend_name +#: model:ir.model.fields,field_description:connector.field_test_backend_name +msgid "Name" +msgstr "" + +#. module: connector +#: model:ir.model.fields,help:connector.field_connector_checkpoint_name +msgid "Name of the record to review" +msgstr "" + +#. module: connector +#: selection:connector.checkpoint,state:0 +#: model:ir.ui.view,arch_db:connector.view_connector_checkpoint_search +msgid "Need Review" +msgstr "" + +#. module: connector +#: model:ir.actions.act_window,help:connector.action_connector_checkpoint +msgid "No record to check." +msgstr "" + +#. module: connector +#: model:ir.actions.client,name:connector.action_client_connector_menu +msgid "Open Connector Menu" +msgstr "" + +#. module: connector +#: model:ir.model,name:connector.model_queue_job +msgid "Queue Job" +msgstr "" + +#. module: connector +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_record +msgid "Record" +msgstr "" + +#. module: connector +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_record_id +msgid "Record ID" +msgstr "" + +#. module: connector +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_name +msgid "Record Name" +msgstr "" + +#. module: connector +#: code:addons/connector/models/queue_job.py:32 +#, python-format +msgid "Related Record" +msgstr "" + +#. module: connector +#: model:ir.actions.act_window,name:connector.action_connector_checkpoint_review +#: model:ir.ui.view,arch_db:connector.view_connector_checkpoint_review +msgid "Review Checkpoints" +msgstr "" + +#. module: connector +#: selection:connector.checkpoint,state:0 +#: model:ir.ui.view,arch_db:connector.view_connector_checkpoint_form +#: model:ir.ui.view,arch_db:connector.view_connector_checkpoint_search +#: model:ir.ui.view,arch_db:connector.view_connector_checkpoint_tree +msgid "Reviewed" +msgstr "" + +#. module: connector +#: model:ir.ui.view,arch_db:connector.view_connector_checkpoint_review +msgid "Set as reviewed" +msgstr "" + +#. module: connector +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_state +msgid "Status" +msgstr "" + +#. module: connector +#: model:ir.actions.act_window,help:connector.action_connector_checkpoint +msgid "" +"The connectors list the new records to verify\n" +" based on their type. Only some need a manual\n" +" review." +msgstr "" + +#. module: connector +#: model:ir.model.fields,help:connector.field_connector_checkpoint_backend_id +msgid "The record has been imported from this backend" +msgstr "" + +#. module: connector +#: model:ir.model.fields,help:connector.field_connector_checkpoint_record +msgid "The record to review." +msgstr "" + +#. module: connector +#: model:ir.ui.view,arch_db:connector.view_connector_checkpoint_review +msgid "The selected checkpoints will be set as reviewed." +msgstr "" + +#. module: connector +#: model:ir.model.fields,field_description:connector.field_connector_backend_version +msgid "Version" +msgstr "" + +#. module: connector +#: model:ir.actions.act_window,help:connector.action_connector_checkpoint +msgid "" +"When a connector imports new records which have\n" +" configuration or reviews to do manually, they\n" +" will appear in this list. Once a record has been\n" +" checked, click on the 'Reviewed' button." +msgstr "" + +#. module: connector +#: model:ir.model,name:connector.model_base +msgid "base" +msgstr "" + +#. module: connector +#: model:ir.ui.view,arch_db:connector.view_connector_checkpoint_review +#: model:ir.ui.view,arch_db:connector.view_connector_config_settings +msgid "or" +msgstr "" + +#. module: connector +#: model:ir.ui.view,arch_db:connector.view_connector_checkpoint_form +msgid "to verify it:" +msgstr "" diff --git a/ext/3rd-party-addons/connector/i18n/zh_CN.po b/ext/3rd-party-addons/connector/i18n/zh_CN.po new file mode 100644 index 00000000..8d960370 --- /dev/null +++ b/ext/3rd-party-addons/connector/i18n/zh_CN.po @@ -0,0 +1,317 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * connector +# +# Translators: +# OCA Transbot , 2017 +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server 10.0\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2017-03-10 03:36+0000\n" +"PO-Revision-Date: 2017-03-10 03:36+0000\n" +"Last-Translator: OCA Transbot , 2017\n" +"Language-Team: Chinese (China) (https://www.transifex.com/oca/teams/23907/zh_CN/)\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: \n" +"Language: zh_CN\n" +"Plural-Forms: nplurals=1; plural=0;\n" + +#. module: connector +#: code:addons/connector/checkpoint/checkpoint.py:119 +#, python-format +msgid "A %s needs a review." +msgstr "" + +#. module: connector +#: model:ir.ui.view,arch_db:connector.view_connector_config_settings +msgid "Apply" +msgstr "应用" + +#. module: connector +#: model:ir.ui.view,arch_db:connector.view_connector_config_settings +msgid "Backends" +msgstr "后台" + +#. module: connector +#: model:ir.ui.view,arch_db:connector.view_connector_checkpoint_review +#: model:ir.ui.view,arch_db:connector.view_connector_config_settings +msgid "Cancel" +msgstr "取消" + +#. module: connector +#: model:ir.ui.menu,name:connector.menu_checkpoint +msgid "Checkpoint" +msgstr "检查点" + +#. module: connector +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_review_checkpoint_ids +msgid "Checkpoints" +msgstr "检查点" + +#. module: connector +#: model:ir.model,name:connector.model_connector_checkpoint_review +msgid "Checkpoints Review" +msgstr "检查点视图" + +#. module: connector +#: model:ir.ui.view,arch_db:connector.view_connector_checkpoint_form +msgid "Click on the" +msgstr "单击" + +#. module: connector +#: model:ir.actions.act_window,name:connector.action_connector_config_settings +#: model:ir.ui.view,arch_db:connector.view_connector_config_settings +msgid "Configure Connector" +msgstr "配置连接器" + +#. module: connector +#: model:ir.module.category,name:connector.module_category_connector +#: model:ir.ui.menu,name:connector.menu_connector_config_settings +msgid "Connector" +msgstr "连接器" + +#. module: connector +#: model:ir.model,name:connector.model_connector_backend +msgid "Connector Backend" +msgstr "" + +#. module: connector +#: model:ir.actions.act_window,name:connector.action_connector_checkpoint +#: model:ir.model,name:connector.model_connector_checkpoint +#: model:ir.ui.view,arch_db:connector.view_connector_checkpoint_form +#: model:ir.ui.view,arch_db:connector.view_connector_checkpoint_search +#: model:ir.ui.view,arch_db:connector.view_connector_checkpoint_tree +msgid "Connector Checkpoint" +msgstr "连接器检查点" + +#. module: connector +#: model:ir.model,name:connector.model_connector_config_settings +msgid "Connector Configuration" +msgstr "" + +#. module: connector +#: model:res.groups,name:connector.group_connector_manager +msgid "Connector Manager" +msgstr "连接器管理" + +#. module: connector +#: model:ir.ui.menu,name:connector.menu_connector +#: model:ir.ui.menu,name:connector.menu_connector_root +#: model:ir.ui.view,arch_db:connector.view_partner_connector_form +msgid "Connectors" +msgstr "连接器" + +#. module: connector +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_create_uid +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_review_create_uid +#: model:ir.model.fields,field_description:connector.field_connector_config_settings_create_uid +msgid "Created by" +msgstr "" + +#. module: connector +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_create_date +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_review_create_date +#: model:ir.model.fields,field_description:connector.field_connector_config_settings_create_date +msgid "Created on" +msgstr "" + +#. module: connector +#: model:ir.model.fields,field_description:connector.field_connector_backend_display_name +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_display_name +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_review_display_name +#: model:ir.model.fields,field_description:connector.field_connector_config_settings_display_name +#: model:ir.model.fields,field_description:connector.field_external_binding_display_name +msgid "Display Name" +msgstr "" + +#. module: connector +#: model:ir.model,name:connector.model_external_binding +msgid "External Binding (abstract)" +msgstr "外部绑定" + +#. module: connector +#: model:ir.ui.view,arch_db:connector.view_connector_checkpoint_search +msgid "Group By..." +msgstr "分组依据是" + +#. module: connector +#: model:ir.model.fields,field_description:connector.field_connector_backend_id +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_id +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_review_id +#: model:ir.model.fields,field_description:connector.field_connector_config_settings_id +#: model:ir.model.fields,field_description:connector.field_external_binding_id +msgid "ID" +msgstr "" + +#. module: connector +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_backend_id +msgid "Imported from" +msgstr "导入自" + +#. module: connector +#: model:ir.model.fields,field_description:connector.field_connector_backend___last_update +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint___last_update +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_review___last_update +#: model:ir.model.fields,field_description:connector.field_connector_config_settings___last_update +#: model:ir.model.fields,field_description:connector.field_external_binding___last_update +msgid "Last Modified on" +msgstr "" + +#. module: connector +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_review_write_uid +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_write_uid +#: model:ir.model.fields,field_description:connector.field_connector_config_settings_write_uid +msgid "Last Updated by" +msgstr "" + +#. module: connector +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_review_write_date +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_write_date +#: model:ir.model.fields,field_description:connector.field_connector_config_settings_write_date +msgid "Last Updated on" +msgstr "" + +#. module: connector +#: model:ir.model.fields,field_description:connector.field_connector_test_binding_sync_date +#: model:ir.model.fields,field_description:connector.field_external_binding_sync_date +#: model:ir.model.fields,field_description:connector.field_no_inherits_binding_sync_date +msgid "Last synchronization date" +msgstr "最后同步日期" + +#. module: connector +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_model_id +#: model:ir.ui.view,arch_db:connector.view_connector_checkpoint_search +msgid "Model" +msgstr "模型" + +#. module: connector +#: model:ir.model.fields,field_description:connector.field_connector_backend_name +#: model:ir.model.fields,field_description:connector.field_test_backend_name +msgid "Name" +msgstr "名称" + +#. module: connector +#: model:ir.model.fields,help:connector.field_connector_checkpoint_name +msgid "Name of the record to review" +msgstr "" + +#. module: connector +#: selection:connector.checkpoint,state:0 +#: model:ir.ui.view,arch_db:connector.view_connector_checkpoint_search +msgid "Need Review" +msgstr "需要审阅" + +#. module: connector +#: model:ir.actions.act_window,help:connector.action_connector_checkpoint +msgid "No record to check." +msgstr "" + +#. module: connector +#: model:ir.actions.client,name:connector.action_client_connector_menu +msgid "Open Connector Menu" +msgstr "打开连接器菜单" + +#. module: connector +#: model:ir.model,name:connector.model_queue_job +msgid "Queue Job" +msgstr "队列中作业" + +#. module: connector +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_record +msgid "Record" +msgstr "" + +#. module: connector +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_record_id +msgid "Record ID" +msgstr "记录 ID" + +#. module: connector +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_name +msgid "Record Name" +msgstr "" + +#. module: connector +#: code:addons/connector/models/queue_job.py:32 +#, python-format +msgid "Related Record" +msgstr "" + +#. module: connector +#: model:ir.actions.act_window,name:connector.action_connector_checkpoint_review +#: model:ir.ui.view,arch_db:connector.view_connector_checkpoint_review +msgid "Review Checkpoints" +msgstr "审查检查点" + +#. module: connector +#: selection:connector.checkpoint,state:0 +#: model:ir.ui.view,arch_db:connector.view_connector_checkpoint_form +#: model:ir.ui.view,arch_db:connector.view_connector_checkpoint_search +#: model:ir.ui.view,arch_db:connector.view_connector_checkpoint_tree +msgid "Reviewed" +msgstr "已审阅" + +#. module: connector +#: model:ir.ui.view,arch_db:connector.view_connector_checkpoint_review +msgid "Set as reviewed" +msgstr "设置为已读" + +#. module: connector +#: model:ir.model.fields,field_description:connector.field_connector_checkpoint_state +msgid "Status" +msgstr "状态" + +#. module: connector +#: model:ir.actions.act_window,help:connector.action_connector_checkpoint +msgid "" +"The connectors list the new records to verify\n" +" based on their type. Only some need a manual\n" +" review." +msgstr "" + +#. module: connector +#: model:ir.model.fields,help:connector.field_connector_checkpoint_backend_id +msgid "The record has been imported from this backend" +msgstr "记录已经成功从后台导入" + +#. module: connector +#: model:ir.model.fields,help:connector.field_connector_checkpoint_record +msgid "The record to review." +msgstr "" + +#. module: connector +#: model:ir.ui.view,arch_db:connector.view_connector_checkpoint_review +msgid "The selected checkpoints will be set as reviewed." +msgstr "已选择的检查点将被设置为已审阅" + +#. module: connector +#: model:ir.model.fields,field_description:connector.field_connector_backend_version +msgid "Version" +msgstr "版本" + +#. module: connector +#: model:ir.actions.act_window,help:connector.action_connector_checkpoint +msgid "" +"When a connector imports new records which have\n" +" configuration or reviews to do manually, they\n" +" will appear in this list. Once a record has been\n" +" checked, click on the 'Reviewed' button." +msgstr "" + +#. module: connector +#: model:ir.model,name:connector.model_base +msgid "base" +msgstr "" + +#. module: connector +#: model:ir.ui.view,arch_db:connector.view_connector_checkpoint_review +#: model:ir.ui.view,arch_db:connector.view_connector_config_settings +msgid "or" +msgstr "或" + +#. module: connector +#: model:ir.ui.view,arch_db:connector.view_connector_checkpoint_form +msgid "to verify it:" +msgstr "来验证他" diff --git a/ext/3rd-party-addons/connector/models/__init__.py b/ext/3rd-party-addons/connector/models/__init__.py new file mode 100644 index 00000000..32298039 --- /dev/null +++ b/ext/3rd-party-addons/connector/models/__init__.py @@ -0,0 +1,5 @@ +# -*- coding: utf-8 -*- +from . import backend_model +from . import checkpoint +from . import queue_job +from . import setting diff --git a/ext/3rd-party-addons/connector/models/backend_model.py b/ext/3rd-party-addons/connector/models/backend_model.py new file mode 100644 index 00000000..83dfa1f5 --- /dev/null +++ b/ext/3rd-party-addons/connector/models/backend_model.py @@ -0,0 +1,120 @@ +# -*- coding: utf-8 -*- +# Copyright 2013-2017 Camptocamp SA +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html) + + +from odoo import models, fields + + +class ConnectorBackend(models.AbstractModel): + """ An instance of an external backend to synchronize with. + + The backends have to ``_inherit`` this model in the connectors + modules. + + The components articulates around a collection, which in the context of the + connectors is called a Backend. + + It must be defined as a Model that inherits from ``'connector.backend'``. + + Example with the Magento Connector:: + + # in connector_magento/models/magento_backend.py + + class MagentoBackend(models.Model): + _name = 'magento.backend' + _inherit = 'connector.backend' + _description = 'Magento Backend' + + # the version in not mandatory + @api.model + def _select_versions(self): + \"\"\" Available versions + + Can be inherited to add custom versions. + \"\"\" + return [('1.7', 'Magento 1.7')] + + location = fields.Char(string='Location', required=True) + username = fields.Char(string='Username') + password = fields.Char(string='Password') + versions = fields.Selection( + selection='_select_versions', required=True + ) + + + """ + _name = 'connector.backend' + _inherit = ['collection.base'] + _description = 'Connector Backend' + + +class ExternalBinding(models.AbstractModel): + """ An abstract model for bindings to external records. + + An external binding is a binding between a backend and Odoo. For + example, for a partner, it could be ``magento.res.partner`` or for a + product, ``magento.product``. + + The final model, will be an ``_inherits`` of the Odoo model and + will ``_inherit`` this model. + + It will have a relation to the record (via ``_inherits``) and to the + concrete backend model (``magento.backend`` for instance). + + It will also contains all the data relative to the backend for the + record. + + It needs to implements at least these fields: + + odoo_id + The many2one to the record it links (used by ``_inherits``). + + backend_id + The many2one to the backend (for instance ``magento.backend``). + + external_id + The ID on the backend. + + sync_date + Last date of synchronization + + + The definition of the field relations is to be done in the + concrete classes because the relations themselves do not exist in + this addon. + + For example, for a ``res.partner.category`` from Magento, I would have + (this is a consolidation of all the columns from the abstract models, + in ``magentoerpconnect`` you would not find that):: + + class MagentoResPartnerCategory(models.Model): + _name = 'magento.res.partner.category' + + _inherits = {'res.partner.category': 'odoo_id'} + + odoo_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') + external_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.'), + ] + + + """ + _name = 'external.binding' + _description = 'External Binding (abstract)' + + sync_date = fields.Datetime(string='Last synchronization date') + # add other fields in concrete models + # XXX we could add a default 'external_id' diff --git a/ext/3rd-party-addons/connector/models/checkpoint.py b/ext/3rd-party-addons/connector/models/checkpoint.py new file mode 100644 index 00000000..c51afe55 --- /dev/null +++ b/ext/3rd-party-addons/connector/models/checkpoint.py @@ -0,0 +1,174 @@ +# -*- coding: utf-8 -*- +# Copyright 2013-2017 Camptocamp SA +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html) + +""" +The checkpoint is a model containing records to be reviewed by the end +users. The connectors register records to verify so the user can check +them and flag them as reviewed. + +A concrete use case is the import of new products from Magento. Once +they are imported, the user have to configure things like the supplier, +so they appears in this list. +""" + +from odoo import models, fields, api, _ + + +class ConnectorCheckpoint(models.Model): + _name = 'connector.checkpoint' + _description = 'Connector Checkpoint' + + _inherit = ['mail.thread', 'mail.activity.mixin'] + + @api.model + def _reference_models(self): + models = self.env['ir.model'].search([('state', '!=', 'manual')]) + return [(model.model, model.name) + for model in models + if not model.model.startswith('ir.')] + + @api.depends('model_id', 'record_id') + def _compute_record(self): + for check in self: + check.record = check.model_id.model + ',' + str(check.record_id) + + @api.depends('model_id', 'record_id') + def _compute_name(self): + for check in self: + model = self.env[check.model_id.model] + check.name = model.browse(check.record_id).display_name + + @api.model + def _search_record(self, operator, value): + model_model = self.env['ir.model'] + sql = "SELECT DISTINCT model_id FROM connector_checkpoint" + self.env.cr.execute(sql) + model_ids = [row[0] for row in self.env.cr.fetchall()] + models = model_model.browse(model_ids) + + ids = set() + for model in models: + model_id = model.id + model_name = model.model + model_obj = self.env[model_name] + results = model_obj.name_search(name=value, + operator=operator) + res_ids = [res[0] for res in results] + checks = self.search([('model_id', '=', model_id), + ('record_id', 'in', res_ids)]) + ids.update(checks.ids) + if not ids: + return [('id', '=', '0')] + return [('id', 'in', tuple(ids))] + + record = fields.Reference( + compute='_compute_record', + selection='_reference_models', + help="The record to review.", + readonly=True, + ) + name = fields.Char( + compute='_compute_name', + search='_search_record', + string='Record Name', + help="Name of the record to review", + readonly=True, + ) + record_id = fields.Integer(string='Record ID', + required=True, + readonly=True) + model_id = fields.Many2one(comodel_name='ir.model', + string='Model', + required=True, + readonly=True) + backend_id = fields.Reference( + string='Imported from', + selection='_reference_models', + readonly=True, + required=True, + help="The record has been imported from this backend", + index=True, + ) + state = fields.Selection( + selection=[('need_review', 'Need Review'), + ('reviewed', 'Reviewed')], + string='Status', + required=True, + readonly=True, + default='need_review', + ) + + @api.multi + def reviewed(self): + return self.write({'state': 'reviewed'}) + + @api.multi + def _subscribe_users(self): + """ Subscribe all users having the 'Connector Manager' group """ + group = self.env.ref('connector.group_connector_manager') + if not group: + return + users = self.env['res.users'].search([('groups_id', '=', group.id)]) + self.message_subscribe_users(user_ids=users.ids) + + @api.model + def create(self, vals): + record = super(ConnectorCheckpoint, self).create(vals) + record._subscribe_users() + msg = _('A %s needs a review.') % record.model_id.name + record.message_post(body=msg, subtype='mail.mt_comment',) + return record + + @api.model + def create_from_name(self, model_name, record_id, + backend_model_name, backend_id): + model_model = self.env['ir.model'] + model = model_model.search([('model', '=', model_name)], limit=1) + assert model, "The model %s does not exist" % model_name + backend = backend_model_name + ',' + str(backend_id) + return self.create({'model_id': model.id, + 'record_id': record_id, + 'backend_id': backend}) + + @api.model + def _needaction_domain_get(self): + """ Returns the domain to filter records that require an action + :return: domain or False is no action + """ + return [('state', '=', 'need_review')] + + +def add_checkpoint(env, model_name, record_id, + backend_model_name, backend_id): + checkpoint_model = env['connector.checkpoint'] + return checkpoint_model.create_from_name(model_name, record_id, + backend_model_name, backend_id) + + +class ConnectorCheckpointReview(models.TransientModel): + _name = 'connector.checkpoint.review' + _description = 'Checkpoints Review' + + @api.model + def _get_checkpoint_ids(self): + res = False + context = self.env.context + if (context.get('active_model') == 'connector.checkpoint' and + context.get('active_ids')): + res = context['active_ids'] + return res + + checkpoint_ids = fields.Many2many( + comodel_name='connector.checkpoint', + relation='connector_checkpoint_review_rel', + column1='review_id', + column2='checkpoint_id', + string='Checkpoints', + domain="[('state', '=', 'need_review')]", + default=_get_checkpoint_ids) + + @api.multi + def review(self): + self.checkpoint_ids.reviewed() + return {'type': 'ir.actions.act_window_close'} diff --git a/ext/3rd-party-addons/connector/models/queue_job.py b/ext/3rd-party-addons/connector/models/queue_job.py new file mode 100644 index 00000000..1d856e26 --- /dev/null +++ b/ext/3rd-party-addons/connector/models/queue_job.py @@ -0,0 +1,52 @@ +# -*- coding: utf-8 -*- +# Copyright 2017 Camptocamp SA +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html) + +from odoo import _, api, models + + +class QueueJob(models.Model): + + _inherit = 'queue.job' + + @api.multi + def related_action_unwrap_binding(self, component_usage='binder'): + """ Open a form view with the unwrapped record. + + For instance, for a job on a ``magento.product.product``, + it will open a ``product.product`` form view with the unwrapped + record. + + :param component_usage: base component usage to search for the binder + """ + self.ensure_one() + model_name = self.model_name + binding = self.env[model_name].browse(self.record_ids).exists() + if not binding: + return None + if len(binding) > 1: + # not handled + return None + action = { + 'name': _('Related Record'), + 'type': 'ir.actions.act_window', + 'view_type': 'form', + 'view_mode': 'form', + } + with binding.backend_id.work_on(binding._name) as work: + binder = work.component(usage=component_usage) + try: + model = binder.unwrap_model() + record = binder.unwrap_binding(binding) + # the unwrapped record will be displayed + action.update({ + 'res_model': model, + 'res_id': record.id, + }) + except ValueError: + # the binding record will be displayed + action.update({ + 'res_model': binding._name, + 'res_id': binding.id, + }) + return action diff --git a/ext/3rd-party-addons/connector/models/setting.py b/ext/3rd-party-addons/connector/models/setting.py new file mode 100644 index 00000000..e857bd87 --- /dev/null +++ b/ext/3rd-party-addons/connector/models/setting.py @@ -0,0 +1,12 @@ +# -*- coding: utf-8 -*- +# Copyright 2013-2017 Camptocamp SA +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html) + +from odoo import models + + +class ConnectorConfigSettings(models.TransientModel): + + _name = 'connector.config.settings' + _description = 'Connector Configuration' + _inherit = 'res.config.settings' diff --git a/ext/3rd-party-addons/connector/security/connector_security.xml b/ext/3rd-party-addons/connector/security/connector_security.xml new file mode 100644 index 00000000..e5587574 --- /dev/null +++ b/ext/3rd-party-addons/connector/security/connector_security.xml @@ -0,0 +1,19 @@ + + + + + Connector + 20 + + + + Connector Manager + + + + + + + + + diff --git a/ext/3rd-party-addons/connector/security/ir.model.access.csv b/ext/3rd-party-addons/connector/security/ir.model.access.csv new file mode 100644 index 00000000..aebedec1 --- /dev/null +++ b/ext/3rd-party-addons/connector/security/ir.model.access.csv @@ -0,0 +1,2 @@ +id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink +access_connector_checkpoint_manager,connector checkpoint manager,connector.model_connector_checkpoint,connector.group_connector_manager,1,1,1,1 diff --git a/ext/3rd-party-addons/connector/static/description/icon.png b/ext/3rd-party-addons/connector/static/description/icon.png new file mode 100644 index 00000000..3a0328b5 Binary files /dev/null and b/ext/3rd-party-addons/connector/static/description/icon.png differ diff --git a/ext/3rd-party-addons/connector/tests/__init__.py b/ext/3rd-party-addons/connector/tests/__init__.py new file mode 100644 index 00000000..c0804033 --- /dev/null +++ b/ext/3rd-party-addons/connector/tests/__init__.py @@ -0,0 +1,5 @@ +# -*- coding: utf-8 -*- + +from . import test_advisory_lock +from . import test_listener +from . import test_mapper diff --git a/ext/3rd-party-addons/connector/tests/test_advisory_lock.py b/ext/3rd-party-addons/connector/tests/test_advisory_lock.py new file mode 100644 index 00000000..fe9c356a --- /dev/null +++ b/ext/3rd-party-addons/connector/tests/test_advisory_lock.py @@ -0,0 +1,75 @@ +# -*- coding: utf-8 -*- +# Copyright 2017 Camptocamp SA +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html) + +import mock +from odoo import api +from odoo.tests import common +from odoo.modules.registry import Registry +from odoo.addons.queue_job.exception import RetryableJobError +from odoo.addons.connector.database import pg_try_advisory_lock +from odoo.addons.component.core import WorkContext +from odoo.addons.component.tests.common import TransactionComponentCase + + +class TestAdvisoryLock(TransactionComponentCase): + + def setUp(self): + super(TestAdvisoryLock, self).setUp() + self.registry2 = Registry(common.get_db_name()) + self.cr2 = self.registry2.cursor() + self.env2 = api.Environment(self.cr2, self.env.uid, {}) + + @self.addCleanup + def reset_cr2(): + # rollback and close the cursor, and reset the environments + self.env2.reset() + self.cr2.rollback() + self.cr2.close() + + def test_concurrent_lock(self): + """ 2 concurrent transactions cannot acquire the same lock """ + # the lock is based on a string, a second transaction trying + # to acquire the same lock won't be able to acquire it + lock = 'import_record({}, {}, {}, {})'.format( + 'backend.name', + 1, + 'res.partner', + '999999', + ) + acquired = pg_try_advisory_lock(self.env, lock) + self.assertTrue(acquired) + # we test the base function + inner_acquired = pg_try_advisory_lock(self.env2, lock) + self.assertFalse(inner_acquired) + + def test_concurrent_import_lock(self): + """ A 2nd concurrent transaction must retry """ + # the lock is based on a string, a second transaction trying + # to acquire the same lock won't be able to acquire it + lock = 'import_record({}, {}, {}, {})'.format( + 'backend.name', + 1, + 'res.partner', + '999999', + ) + + backend = mock.MagicMock() + backend.env = self.env + work = WorkContext(model_name='res.partner', + collection=backend) + # we test the function through a Component instance + component = work.component_by_name('base.connector') + # acquire the lock + component.advisory_lock_or_retry(lock) + + # instanciate another component using a different odoo env + # hence another PG transaction + backend2 = mock.MagicMock() + backend2.env = self.env2 + work2 = WorkContext(model_name='res.partner', + collection=backend2) + component2 = work2.component_by_name('base.connector') + with self.assertRaises(RetryableJobError) as cm: + component2.advisory_lock_or_retry(lock, retry_seconds=3) + self.assertEqual(cm.exception.seconds, 3) diff --git a/ext/3rd-party-addons/connector/tests/test_listener.py b/ext/3rd-party-addons/connector/tests/test_listener.py new file mode 100644 index 00000000..4a7f6445 --- /dev/null +++ b/ext/3rd-party-addons/connector/tests/test_listener.py @@ -0,0 +1,53 @@ +# -*- coding: utf-8 -*- +# Copyright 2017 Camptocamp SA +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html) + +import mock + +from odoo.tools import frozendict +from odoo.addons.component.core import Component +from odoo.addons.component_event.core import EventWorkContext +from odoo.addons.component_event.components.event import skip_if +from odoo.addons.component.tests.common import TransactionComponentRegistryCase +from odoo.addons.connector import components + + +class TestEventListener(TransactionComponentRegistryCase): + """ Test Connecter Listener """ + + def test_skip_if_no_connector_export(self): + class MyEventListener(Component): + _name = 'my.event.listener' + _inherit = 'base.event.listener' + + def on_record_create(self, record, fields=None): + assert True + + class MyOtherEventListener(Component): + _name = 'my.other.event.listener' + _inherit = 'base.connector.listener' + + @skip_if(lambda self, record, fields=None: + self.no_connector_export(record)) + def on_record_create(self, record, fields=None): + assert False + + self.env.context = frozendict(self.env.context, + no_connector_export=True) + work = EventWorkContext(model_name='res.users', env=self.env, + components_registry=self.comp_registry) + + # get the collecter to notify the event + # we don't mind about the collection and the model here, + # the events we test are global + self.collecter = self.comp_registry['base.event.collecter'](work) + + self._build_components(components.core.BaseConnectorComponent, + components.listener.ConnectorListener, + MyEventListener, MyOtherEventListener) + + # collect the event and notify it + record = mock.Mock(name='record') + collected = self.collecter.collect_events('on_record_create') + self.assertEqual(2, len(collected.events)) + collected.notify(record) diff --git a/ext/3rd-party-addons/connector/tests/test_mapper.py b/ext/3rd-party-addons/connector/tests/test_mapper.py new file mode 100644 index 00000000..3b297944 --- /dev/null +++ b/ext/3rd-party-addons/connector/tests/test_mapper.py @@ -0,0 +1,926 @@ +# -*- coding: utf-8 -*- +# Copyright 2013-2017 Camptocamp SA +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html) + +import mock +from odoo.addons.component.core import Component, WorkContext +from odoo.addons.component.tests.common import ( + ComponentRegistryCase, + TransactionComponentRegistryCase, +) + +from odoo.addons.connector.components.mapper import ( + MappingDefinition, + changed_by, + only_create, + convert, + follow_m2o_relations, + m2o_to_external, + external_to_m2o, + none, + MapOptions, + mapping, +) + + +class TestMapper(ComponentRegistryCase): + + def setUp(self): + super(TestMapper, self).setUp() + self.comp_registry.load_components('connector') + + def test_mapping_decorator(self): + class KifKrokerMapper(Component): + _name = 'kif.kroker.mapper' + _inherit = 'base.mapper' + + @changed_by('name', 'city') + @mapping + @only_create + def name(self): + pass + + @changed_by('email') + @mapping + def email(self): + pass + + @changed_by('street') + @mapping + def street(self): + pass + + def no_decorator(self): + pass + + # build our mapper component + KifKrokerMapper._build_component(self.comp_registry) + + # what mappings we expect + name_def = MappingDefinition(changed_by=set(('name', 'city')), + only_create=True) + email_def = MappingDefinition(changed_by=set(('email',)), + only_create=False) + street_def = MappingDefinition(changed_by=set(('street',)), + only_create=False) + + # get our component by name in the components registry + comp = self.comp_registry['kif.kroker.mapper'] + # _map_methods contains the aggregated mapping methods for a Mapper + self.assertEqual(comp._map_methods, + {'name': name_def, + 'email': email_def, + 'street': street_def, + }) + + def test_mapping_decorator_cross_classes(self): + """ Mappings should not propagate to other classes""" + class MomMapper(Component): + _name = 'mom.mapper' + _inherit = 'base.mapper' + _apply_on = 'res.users' + + @changed_by('name', 'city') + @mapping + def name(self): + pass + + class ZappMapper(Component): + _name = 'zapp.mapper' + _inherit = 'base.mapper' + _apply_on = 'res.users' + + @changed_by('email') + @only_create + @mapping + def email(self): + pass + + self._build_components(MomMapper, ZappMapper) + + mom_def = MappingDefinition(changed_by=set(('name', 'city')), + only_create=False) + zapp_def = MappingDefinition(changed_by=set(('email',)), + only_create=True) + + comp = self.comp_registry['mom.mapper'] + self.assertEqual(comp._map_methods, {'name': mom_def}) + comp = self.comp_registry['zapp.mapper'] + self.assertEqual(comp._map_methods, {'email': zapp_def}) + + def test_mapping_decorator_cumul(self): + """ Mappings should cumulate the ``super`` mappings + and the local mappings.""" + class FryMapper(Component): + _name = 'fry.mapper' + _inherit = 'base.mapper' + _apply_on = 'res.users' + + @changed_by('name', 'city') + @mapping + def name(self): + pass + + class FryMapperInherit(Component): + _inherit = 'fry.mapper' + + @changed_by('email') + @mapping + def email(self): + pass + + self._build_components(FryMapper, FryMapperInherit) + + name_def = MappingDefinition(changed_by=set(('name', 'city')), + only_create=False) + email_def = MappingDefinition(changed_by=set(('email',)), + only_create=False) + + comp = self.comp_registry['fry.mapper'] + self.assertEqual(comp._map_methods, + {'name': name_def, + 'email': email_def}) + + def test_mapping_decorator_cumul_changed_by(self): + """ Mappings should cumulate the changed_by fields of the + ``super`` mappings and the local mappings """ + class FryMapper(Component): + _name = 'fry.mapper' + _inherit = 'base.mapper' + _apply_on = 'res.users' + + @changed_by('name', 'city') + @mapping + def name(self): + pass + + class FryMapperInherit(Component): + _inherit = 'fry.mapper' + _apply_on = 'res.users' + + @changed_by('email') + @mapping + def name(self): + pass + + class ThirdMapper(Component): + _name = 'third.mapper' + _inherit = 'fry.mapper' + _apply_on = 'res.users' + + @changed_by('email', 'street') + @mapping + def name(self): + pass + + self._build_components(FryMapper, FryMapperInherit, ThirdMapper) + + name_def = MappingDefinition(changed_by=set(('name', 'city', 'email')), + only_create=False) + + comp = self.comp_registry['fry.mapper'] + self.assertEqual(comp._map_methods, {'name': name_def}) + + name_def = MappingDefinition(changed_by=set(('name', 'city', + 'email', 'street')), + only_create=False) + comp = self.comp_registry['third.mapper'] + self.assertEqual(comp._map_methods, {'name': name_def}) + + def test_several_bases_cumul(self): + class FryMapper(Component): + _name = 'fry.mapper' + _inherit = 'base.mapper' + _apply_on = 'res.users' + + @changed_by('name', 'city') + @mapping + def name(self): + pass + + @only_create + @mapping + def street(self): + pass + + @only_create + @mapping + def zip(self): + pass + + class FarnsworthMapper(Component): + _name = 'farnsworth.mapper' + _inherit = 'base.mapper' + _apply_on = 'res.users' + + @changed_by('email') + @mapping + def name(self): + pass + + @changed_by('street') + @mapping + def city(self): + pass + + @mapping + def zip(self): + pass + + class ThirdMapper(Component): + _name = 'third.mapper' + _inherit = ['fry.mapper', 'farnsworth.mapper'] + _apply_on = 'res.users' + + @changed_by('email', 'street') + @mapping + def name(self): + pass + + @mapping + def email(self): + pass + + self._build_components(FryMapper, FarnsworthMapper, ThirdMapper) + + name_def = MappingDefinition(changed_by=set(('name', 'city', + 'email', 'street')), + only_create=False) + street_def = MappingDefinition(changed_by=set([]), + only_create=True) + city_def = MappingDefinition(changed_by=set(('street',)), + only_create=False) + email_def = MappingDefinition(changed_by=set([]), + only_create=False) + zip_def = MappingDefinition(changed_by=set([]), + only_create=True) + + comp = self.comp_registry['third.mapper'] + self.assertEqual(comp._map_methods['name'], name_def) + self.assertEqual(comp._map_methods['street'], street_def) + self.assertEqual(comp._map_methods['city'], city_def) + self.assertEqual(comp._map_methods['email'], email_def) + self.assertEqual(comp._map_methods['zip'], zip_def) + + def test_mapping_record(self): + """ Map a record and check the result """ + class MyMapper(Component): + _name = 'my.mapper' + _inherit = 'base.import.mapper' + _apply_on = 'res.users' + + direct = [('name', 'out_name')] + + @mapping + def street(self, record): + return {'out_street': record['street'].upper()} + + self._build_components(MyMapper) + + record = {'name': 'Guewen', 'street': 'street'} + work = mock.MagicMock(name='WorkContext()') + mapper = self.comp_registry['my.mapper'](work) + map_record = mapper.map_record(record) + expected = {'out_name': 'Guewen', 'out_street': 'STREET'} + self.assertEqual(map_record.values(), expected) + self.assertEqual(map_record.values(for_create=True), expected) + + def test_mapping_record_on_create(self): + """ Map a record and check the result for creation of record """ + class MyMapper(Component): + _name = 'my.mapper' + _inherit = 'base.import.mapper' + _apply_on = 'res.users' + + direct = [('name', 'out_name')] + + @mapping + def street(self, record): + return {'out_street': record['street'].upper()} + + @only_create + @mapping + def city(self, record): + return {'out_city': 'city'} + + self._build_components(MyMapper) + + record = {'name': 'Guewen', 'street': 'street'} + work = mock.MagicMock(name='WorkContext()') + mapper = self.comp_registry['my.mapper'](work) + map_record = mapper.map_record(record) + expected = {'out_name': 'Guewen', 'out_street': 'STREET'} + self.assertEqual(map_record.values(), expected) + expected = {'out_name': 'Guewen', + 'out_street': 'STREET', + 'out_city': 'city'} + self.assertEqual(map_record.values(for_create=True), expected) + + def test_mapping_update(self): + """ Force values on a map record """ + class MyMapper(Component): + _name = 'my.mapper' + _inherit = 'base.import.mapper' + + direct = [('name', 'out_name')] + + @mapping + def street(self, record): + return {'out_street': record['street'].upper()} + + @only_create + @mapping + def city(self, record): + return {'out_city': 'city'} + + self._build_components(MyMapper) + + record = {'name': 'Guewen', 'street': 'street'} + work = mock.MagicMock(name='WorkContext()') + mapper = self.comp_registry['my.mapper'](work) + map_record = mapper.map_record(record) + map_record.update({'test': 1}, out_city='forced') + expected = {'out_name': 'Guewen', + 'out_street': 'STREET', + 'out_city': 'forced', + 'test': 1} + self.assertEqual(map_record.values(), expected) + expected = {'out_name': 'Guewen', + 'out_street': 'STREET', + 'out_city': 'forced', + 'test': 1} + self.assertEqual(map_record.values(for_create=True), expected) + + def test_finalize(self): + """ Inherit finalize to modify values """ + class MyMapper(Component): + _name = 'my.mapper' + _inherit = 'base.import.mapper' + + direct = [('name', 'out_name')] + + def finalize(self, record, values): + result = super(MyMapper, self).finalize(record, values) + result['test'] = 'abc' + return result + + self._build_components(MyMapper) + + record = {'name': 'Guewen', + 'street': 'street'} + work = mock.MagicMock(name='WorkContext()') + mapper = self.comp_registry['my.mapper'](work) + map_record = mapper.map_record(record) + expected = {'out_name': 'Guewen', + 'test': 'abc'} + self.assertEqual(map_record.values(), expected) + expected = {'out_name': 'Guewen', + 'test': 'abc'} + self.assertEqual(map_record.values(for_create=True), expected) + + def test_some_fields(self): + """ Map only a selection of fields """ + class MyMapper(Component): + _name = 'my.mapper' + _inherit = 'base.import.mapper' + + direct = [('name', 'out_name'), + ('street', 'out_street'), + ] + + @changed_by('country') + @mapping + def country(self, record): + return {'country': 'country'} + + self._build_components(MyMapper) + + record = {'name': 'Guewen', + 'street': 'street', + 'country': 'country'} + work = mock.MagicMock(name='WorkContext()') + mapper = self.comp_registry['my.mapper'](work) + map_record = mapper.map_record(record) + expected = {'out_name': 'Guewen', + 'country': 'country'} + self.assertEqual(map_record.values(fields=['name', 'country']), + expected) + expected = {'out_name': 'Guewen', + 'country': 'country'} + self.assertEqual(map_record.values(for_create=True, + fields=['name', 'country']), + expected) + + def test_mapping_modifier(self): + """ Map a direct record with a modifier function """ + + def do_nothing(field): + def transform(self, record, to_attr): + return record[field] + return transform + + class MyMapper(Component): + _name = 'my.mapper' + _inherit = 'base.import.mapper' + + direct = [(do_nothing('name'), 'out_name')] + + self._build_components(MyMapper) + + record = {'name': 'Guewen'} + work = mock.MagicMock(name='WorkContext()') + mapper = self.comp_registry['my.mapper'](work) + map_record = mapper.map_record(record) + expected = {'out_name': 'Guewen'} + self.assertEqual(map_record.values(), expected) + self.assertEqual(map_record.values(for_create=True), expected) + + def test_mapping_direct_property(self): + """ Map a direct record with 'direct' being a property """ + class MyMapper(Component): + _name = 'my.mapper' + _inherit = 'base.import.mapper' + + @property + def direct(self): + return [('name', 'out_name')] + + self._build_components(MyMapper) + + record = {'name': 'Foo'} + work = mock.MagicMock(name='WorkContext()') + mapper = self.comp_registry['my.mapper'](work) + map_record = mapper.map_record(record) + expected = {'out_name': 'Foo'} + self.assertEqual(map_record.values(), expected) + self.assertEqual(map_record.values(for_create=True), expected) + + def test_mapping_convert(self): + """ Map a direct record with the convert modifier function """ + class MyMapper(Component): + _name = 'my.mapper' + _inherit = 'base.import.mapper' + + direct = [(convert('name', int), 'out_name')] + + self._build_components(MyMapper) + + record = {'name': '300'} + work = mock.MagicMock(name='WorkContext()') + mapper = self.comp_registry['my.mapper'](work) + map_record = mapper.map_record(record) + expected = {'out_name': 300} + self.assertEqual(map_record.values(), expected) + self.assertEqual(map_record.values(for_create=True), expected) + + def test_mapping_modifier_none(self): + """ Pipeline of modifiers """ + class MyMapper(Component): + _name = 'my.mapper' + _inherit = 'base.import.mapper' + + direct = [(none('in_f'), 'out_f'), + (none('in_t'), 'out_t')] + + self._build_components(MyMapper) + + record = {'in_f': False, 'in_t': True} + work = mock.MagicMock(name='WorkContext()') + mapper = self.comp_registry['my.mapper'](work) + map_record = mapper.map_record(record) + expected = {'out_f': None, 'out_t': True} + self.assertEqual(map_record.values(), expected) + self.assertEqual(map_record.values(for_create=True), expected) + + def test_mapping_modifier_pipeline(self): + """ Pipeline of modifiers """ + class MyMapper(Component): + _name = 'my.mapper' + _inherit = 'base.import.mapper' + + direct = [(none(convert('in_f', bool)), 'out_f'), + (none(convert('in_t', bool)), 'out_t')] + + self._build_components(MyMapper) + + record = {'in_f': 0, 'in_t': 1} + work = mock.MagicMock(name='WorkContext()') + mapper = self.comp_registry['my.mapper'](work) + map_record = mapper.map_record(record) + expected = {'out_f': None, 'out_t': True} + self.assertEqual(map_record.values(), expected) + self.assertEqual(map_record.values(for_create=True), expected) + + def test_modifier_import_filter_field(self): + """ A direct mapping with a modifier must still be considered + from the list of fields + """ + class MyMapper(Component): + _name = 'my.mapper' + _inherit = 'base.import.mapper' + + direct = [('field', 'field2'), + ('no_field', 'no_field2'), + (convert('name', int), 'out_name')] + + self._build_components(MyMapper) + + record = {'name': '300', 'field': 'value', 'no_field': 'no_value'} + work = mock.MagicMock(name='WorkContext()') + mapper = self.comp_registry['my.mapper'](work) + map_record = mapper.map_record(record) + expected = {'out_name': 300, 'field2': 'value'} + self.assertEqual(map_record.values(fields=['field', 'name']), expected) + self.assertEqual(map_record.values(for_create=True, + fields=['field', 'name']), expected) + + def test_modifier_export_filter_field(self): + """ A direct mapping with a modifier on an export mapping """ + class MyMapper(Component): + _name = 'my.mapper' + _inherit = 'base.export.mapper' + + direct = [('field', 'field2'), + ('no_field', 'no_field2'), + (convert('name', int), 'out_name')] + + self._build_components(MyMapper) + + record = {'name': '300', 'field': 'value', 'no_field': 'no_value'} + work = mock.MagicMock(name='WorkContext()') + mapper = self.comp_registry['my.mapper'](work) + map_record = mapper.map_record(record) + expected = {'out_name': 300, 'field2': 'value'} + self.assertEqual(map_record.values(fields=['field', 'name']), expected) + self.assertEqual(map_record.values(for_create=True, + fields=['field', 'name']), expected) + + def test_mapping_custom_option(self): + """ Usage of custom options in mappings """ + class MyMapper(Component): + _name = 'my.mapper' + _inherit = 'base.import.mapper' + + @mapping + def any(self, record): + if self.options.custom: + res = True + else: + res = False + return {'res': res} + + self._build_components(MyMapper) + + record = {} + work = mock.MagicMock(name='WorkContext()') + mapper = self.comp_registry['my.mapper'](work) + map_record = mapper.map_record(record) + expected = {'res': True} + self.assertEqual(map_record.values(custom=True), expected) + + def test_mapping_custom_option_not_defined(self): + """ Usage of custom options not defined raise AttributeError """ + class MyMapper(Component): + _name = 'my.mapper' + _inherit = 'base.import.mapper' + + @mapping + def any(self, record): + if self.options.custom is None: + res = True + else: + res = False + return {'res': res} + + self._build_components(MyMapper) + + record = {} + work = mock.MagicMock(name='WorkContext()') + mapper = self.comp_registry['my.mapper'](work) + map_record = mapper.map_record(record) + expected = {'res': True} + self.assertEqual(map_record.values(), expected) + + def test_map_options(self): + """ Test MapOptions """ + options = MapOptions({'xyz': 'abc'}, k=1) + options.l = 2 + self.assertEqual(options['xyz'], 'abc') + self.assertEqual(options['k'], 1) + self.assertEqual(options['l'], 2) + self.assertEqual(options.xyz, 'abc') + self.assertEqual(options.k, 1) + self.assertEqual(options.l, 2) + self.assertEqual(options['undefined'], None) + self.assertEqual(options.undefined, None) + + def test_changed_by_fields(self): + """ Test attribute ``_changed_by_fields`` on Mapper.""" + class MyMapper(Component): + _name = 'my.mapper' + _inherit = 'base.export.mapper' + + direct = [('street', 'out_street'), + (none('in_t'), 'out_t'), + (none(convert('in_f', bool)), 'out_f')] + + @changed_by('name', 'city') + @mapping + def name(self): + pass + + @changed_by('email') + @mapping + def email(self): + pass + + def no_decorator(self): + pass + + self._build_components(MyMapper) + + work = mock.MagicMock(name='WorkContext()') + mapper = self.comp_registry['my.mapper'](work) + + self.assertEqual( + mapper.changed_by_fields(), + set(['street', 'in_t', 'in_f', 'name', 'city', 'email'])) + + +class TestMapperRecordsets(TransactionComponentRegistryCase): + """ Test mapper with "real" records instead of mocks """ + + def setUp(self): + super(TestMapperRecordsets, self).setUp() + self.comp_registry.load_components('connector') + + backend_record = mock.Mock() + backend_record.env = self.env + self.work = WorkContext(model_name='res.partner', + collection=backend_record, + components_registry=self.comp_registry) + + def test_mapping_modifier_follow_m2o_relations(self): + """ Map with the follow_m2o_relations modifier """ + class MyMapper(Component): + _name = 'my.mapper' + _inherit = 'base.import.mapper' + + direct = [ + (follow_m2o_relations('parent_id.name'), 'parent_name'), + ] + + self._build_components(MyMapper) + + partner = self.env.ref('base.res_partner_address_4') + mapper = self.comp_registry['my.mapper'](self.work) + map_record = mapper.map_record(partner) + expected = {'parent_name': 'Agrolait'} + self.assertEqual(map_record.values(), expected) + self.assertEqual(map_record.values(for_create=True), expected) + + +class TestMapperBinding(TransactionComponentRegistryCase): + """ Test Mapper with Bindings""" + + def setUp(self): + super(TestMapperBinding, self).setUp() + self.comp_registry.load_components('connector') + + backend_record = mock.Mock() + backend_record.env = self.env + backend_record._name = 'my.collection' + self.work = WorkContext(model_name='res.partner', + collection=backend_record, + components_registry=self.comp_registry) + + self.country_binder = mock.MagicMock(name='country_binder') + self.country_binder.return_value = self.country_binder + self.country_binder._name = 'test.binder' + self.country_binder._inherit = 'base.binder' + self.country_binder.apply_on_models = ['res.country'] + self.country_binder._usage = 'binder' + self.country_binder._collection = 'my.collection' + self.country_binder._abstract = False + self.comp_registry['test.binder'] = self.country_binder + + def test_mapping_m2o_to_external(self): + """ Map a direct record with the m2o_to_external modifier function """ + class MyMapper(Component): + _name = 'my.mapper' + _inherit = 'base.import.mapper' + _apply_on = 'res.partner' + + direct = [(m2o_to_external('country_id'), 'country')] + + self._build_components(MyMapper) + + partner = self.env.ref('base.main_partner') + partner.write({'country_id': self.env.ref('base.ch').id}) + self.country_binder.to_external.return_value = 10 + + mapper = self.comp_registry['my.mapper'](self.work) + map_record = mapper.map_record(partner) + self.assertEqual(map_record.values(), {'country': 10}) + self.country_binder.to_external.assert_called_once_with( + partner.country_id.id, wrap=False) + + def test_mapping_backend_to_m2o(self): + """ Map a direct record with the backend_to_m2o modifier function """ + class MyMapper(Component): + _name = 'my.mapper' + _inherit = 'base.import.mapper' + _apply_on = 'res.partner' + + direct = [(external_to_m2o('country'), 'country_id')] + + self._build_components(MyMapper) + + record = {'country': 10} + ch = self.env.ref('base.ch') + self.country_binder.to_internal.return_value = ch + mapper = self.comp_registry['my.mapper'](self.work) + map_record = mapper.map_record(record) + self.assertEqual(map_record.values(), {'country_id': ch.id}) + self.country_binder.to_internal.assert_called_once_with( + 10, unwrap=False) + + def test_mapping_record_children_no_map_child(self): + """ Map a record with children, using default MapChild """ + # we need these components which make the 'link' between + # the main mapper and the line mapper + + class LineMapper(Component): + _name = 'line.mapper' + _inherit = 'base.import.mapper' + _apply_on = 'res.currency.rate' + + direct = [('name', 'name')] + + @mapping + def price(self, record): + return {'rate': record['rate'] * 2} + + @only_create + @mapping + def discount(self, record): + return {'test': .5} + + class MyMapper(Component): + _name = 'my.mapper' + _inherit = 'base.import.mapper' + _apply_on = 'res.currency' + + direct = [('name', 'name')] + + children = [('lines', 'line_ids', 'res.currency.rate')] + + self._build_components(LineMapper, MyMapper) + + record = {'name': 'SO1', + 'lines': [{'name': '2013-11-07', + 'rate': 10}, + {'name': '2013-11-08', + 'rate': 20}]} + mapper = self.comp_registry['my.mapper'](self.work) + map_record = mapper.map_record(record) + expected = {'name': 'SO1', + 'line_ids': [(0, 0, {'name': '2013-11-07', + 'rate': 20}), + (0, 0, {'name': '2013-11-08', + 'rate': 40})] + } + self.assertEqual(map_record.values(), expected) + expected = {'name': 'SO1', + 'line_ids': [(0, 0, {'name': '2013-11-07', + 'rate': 20, + 'test': .5}), + (0, 0, {'name': '2013-11-08', + 'rate': 40, + 'test': .5})] + } + self.assertEqual(map_record.values(for_create=True), expected) + + def test_mapping_record_children(self): + """ Map a record with children, using defined MapChild """ + # we need these components which make the 'link' between + # the main mapper and the line mapper + + class LineMapper(Component): + _name = 'line.mapper' + _inherit = 'base.import.mapper' + _apply_on = 'res.currency.rate' + + direct = [('name', 'name')] + + @mapping + def price(self, record): + return {'rate': record['rate'] * 2} + + @only_create + @mapping + def discount(self, record): + return {'test': .5} + + class LineImportMapChild(Component): + _name = 'line.map.child.import' + _inherit = 'base.map.child.import' + _apply_on = 'res.currency.rate' + + def format_items(self, items_values): + return [('ABC', values) for values in items_values] + + class MyMapper(Component): + _name = 'my.mapper' + _inherit = 'base.import.mapper' + _apply_on = 'res.currency' + + direct = [('name', 'name')] + + children = [('lines', 'line_ids', 'res.currency.rate')] + + self._build_components(LineMapper, LineImportMapChild, MyMapper) + + record = {'name': 'SO1', + 'lines': [{'name': '2013-11-07', + 'rate': 10}, + {'name': '2013-11-08', + 'rate': 20}]} + mapper = self.comp_registry['my.mapper'](self.work) + map_record = mapper.map_record(record) + expected = {'name': 'SO1', + 'line_ids': [('ABC', {'name': '2013-11-07', + 'rate': 20}), + ('ABC', {'name': '2013-11-08', + 'rate': 40})] + } + self.assertEqual(map_record.values(), expected) + expected = {'name': 'SO1', + 'line_ids': [('ABC', {'name': '2013-11-07', + 'rate': 20, + 'test': .5}), + ('ABC', {'name': '2013-11-08', + 'rate': 40, + 'test': .5})] + } + self.assertEqual(map_record.values(for_create=True), expected) + + def test_mapping_record_children_void(self): + """ Map a record with children, using defined MapChild """ + + class LineMapper(Component): + _name = 'line.mapper' + _inherit = 'base.import.mapper' + _apply_on = 'res.currency.rate' + + @mapping + def price(self, record): + rate = record.get('rate') + if rate and rate < 40: + return {'rate': record['rate'] * 2} + + class SaleLineImportMapChild(Component): + _name = 'sale.line.mapper' + _inherit = 'base.map.child.import' + _apply_on = 'res.currency.rate' + + def format_items(self, items_values): + return [('ABC', values) for values in items_values] + + class ObjectMapper(Component): + _name = 'currency.mapper' + _inherit = 'base.import.mapper' + _apply_on = 'res.currency' + + direct = [('name', 'name')] + + children = [('lines', 'line_ids', 'res.currency.rate')] + + self._build_components( + ObjectMapper, + SaleLineImportMapChild, + LineMapper + ) + + # Test with an excluded child record + record = { + 'name': 'SO1', + 'lines': [ + {'rate': 10}, + {'rate': 20}, + {'rate': 30}, + {'rate': 40}, + ] + } + mapper = self.comp_registry['currency.mapper'](self.work) + map_record = mapper.map_record(record) + + expected = { + 'name': 'SO1', + 'line_ids': [ + ('ABC', {'rate': 20}), + ('ABC', {'rate': 40}), + ('ABC', {'rate': 60}), + ] + } + self.assertEqual(map_record.values(), expected) diff --git a/ext/3rd-party-addons/connector/views/checkpoint_views.xml b/ext/3rd-party-addons/connector/views/checkpoint_views.xml new file mode 100644 index 00000000..25001137 --- /dev/null +++ b/ext/3rd-party-addons/connector/views/checkpoint_views.xml @@ -0,0 +1,121 @@ + + + + + connector.checkpoint.form + connector.checkpoint + +
+
+
+ +

+ Click on the + to verify it: + +

+ + + +
+
+ + +
+
+
+
+ + + connector.checkpoint.tree + connector.checkpoint + + + + + + +