sst02 mit connector

develop
Ahmed Aly 2017-11-28 16:27:00 +01:00
parent 48ac763dc7
commit 5ab62cd904
159 changed files with 30938 additions and 2 deletions

View File

@ -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

View File

@ -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
<https://github.com/OCA/connector/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 <https://github.com/OCA/maintainer-tools/blob/master/template/module/static/description/icon.svg>`_.
Contributors
------------
* Guewen Baconnier <guewen.baconnier@camptocamp.com>
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.

View File

@ -0,0 +1,6 @@
# -*- coding: utf-8 -*-
from . import core
from . import components
from . import builder
from . import models

View File

@ -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,
}

View File

@ -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)

View File

@ -0,0 +1,2 @@
# -*- coding: utf-8 -*-
from . import base

View File

@ -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'

View File

@ -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 = "<one of %r>" % (
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

View File

@ -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 """

View File

@ -0,0 +1,3 @@
# -*- coding: utf-8 -*-
from . import collection

View File

@ -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)

View File

@ -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

View File

@ -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)

View File

@ -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)

View File

@ -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)

View File

@ -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])

View File

@ -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)

View File

@ -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
<https://github.com/OCA/connector/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 <https://github.com/OCA/maintainer-tools/blob/master/template/module/static/description/icon.svg>`_.
Contributors
------------
* Guewen Baconnier <guewen.baconnier@camptocamp.com>
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.

View File

@ -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

View File

@ -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,
}

View File

@ -0,0 +1,2 @@
# -*- coding: utf-8 -*-
from . import event

View File

@ -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()

View File

@ -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))

View File

@ -0,0 +1,2 @@
# -*- coding: utf-8 -*-
from . import base

View File

@ -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

View File

@ -0,0 +1,2 @@
# -*- coding: utf-8 -*-
from . import test_event

View File

@ -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)

View File

@ -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

View File

@ -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

View File

@ -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 <https://github.com/OCA/connector/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 <https://github.com/OCA/connector/issues/new?body=module:%20connector%0Aversion:%208.0%0A%0A**Steps%20to%20reproduce**%0A-%20...%0A%0A**Current%20behavior**%0A%0A**Expected%20behavior**>`_.
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.

View File

@ -0,0 +1,3 @@
# -*- coding: utf-8 -*-
from . import components
from . import models

View File

@ -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,
}

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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)

View File

@ -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'))

File diff suppressed because it is too large Load Diff

View File

@ -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'

View File

@ -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

View File

@ -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 <target>' where <target> 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."

Binary file not shown.

After

Width:  |  Height:  |  Size: 375 KiB

View File

@ -0,0 +1,4 @@
.navbar span.navbar-text {
visibility: hidden;
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 24 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 28 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 74 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 68 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

View File

@ -0,0 +1,14 @@
{% extends "!layout.html" %}
{%- block extrahead %}
{{ super() }}
<script>
(function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
(i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
})(window,document,'script','//www.google-analytics.com/analytics.js','ga');
ga('create', 'UA-7628916-3', 'odoo-connector.com');
ga('send', 'pageview');
</script>
{% endblock %}

View File

@ -0,0 +1,31 @@
{% extends "!navbar.html" %}
{% block navbartoc %}
<li class="dropdown">
<a role="button"
id="dLabelTranslations"
data-toggle="dropdown"
data-target="#"
href="#">Translations<b class="caret"></b></a>
<ul class="dropdown-menu"
role="menu"
aria-labelledby="dLabelTranslations">
<li><a class="reference" href="http://odoo-connector.com">English</a><li>
<li><a class="reference" href="http://odoo-connector.com/fr">French</a><li>
</ul>
</li>
<li class="dropdown">
<a role="button"
id="dLabelVersions"
data-toggle="dropdown"
data-target="#"
href="#">Version<b class="caret"></b></a>
<ul class="dropdown-menu"
role="menu"
aria-labelledby="dLabeVersions">
<li><a class="reference" href="http://odoo-connector.com/8.0">8.0</a><li>
<li><a class="reference" href="http://odoo-connector.com/9.0">9.0</a><li>
</ul>
</li>
{{ super() }}
{% endblock %}

View File

@ -0,0 +1,3 @@
*.pyc
*.pyo
.DS_Store

View File

@ -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:

View File

@ -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:

View File

@ -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:

View File

@ -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:

View File

@ -0,0 +1,8 @@
Exceptions
==========
.. automodule:: connector.exception
:members:
:undoc-members:
:show-inheritance:

View File

@ -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:

View File

@ -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):

View File

@ -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 <div> 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
# "<project> v<release> 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 <link> 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),
}

View File

@ -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

View File

@ -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`

View File

@ -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

View File

@ -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

View File

@ -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.

View File

@ -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 <http://www.odoo-magento-connector.com>`_
* `Prestashop Connector <https://github.com/OCA/connector-prestashop>`_
* `Search Engine Connector <https://github.com/akretion/connector-search-engine>`_
* `CMIS <https://github.com/OCA/connector-cmis>`_
* `Odoo Asynchronous import module <https://github.com/OCA/connector-interfaces/tree/8.0/base_import_async>`_
* `Salesforce Connector <https://github.com/OCA/connector-salesforce>`_
* `JIRA Connector <https://github.com/camptocamp/connector-jira>`_
* `Google Spreadsheet Connector <https://github.com/akretion/connector-google-spreadsheet>`_
* `Connector Exchange <https://github.com/camptocamp/connector-exchange/tree/10.0>`_
* 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) <https://fr.slideshare.net/camptocamp/a-jobs-queue-for-processing-tasks-asynchronously>`_
* `E-commerce: the new Magento - OpenERP Connector: a generic connector to any apps. Luc Maurer & Guewen Baconnier, Camptocamp (2013) <https://fr.slideshare.net/openobject/ecommerce-the-new-magento-open-erp-connector-a-generic-connector-to-any-apps-luc-maurer-guewen-baconnier-camptocamp>`_
******************
Indices and tables
******************
* :ref:`genindex`
* :ref:`modindex`
* :ref:`search`

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -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 <guewen.baconnier@camptocamp.com>\n"
"Language-Team: fr <LL@li.org>\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 <http://www.odoo-magento-connector.com>`_"
msgstr "`Connecteur Magento <http://www.odoo-magento-connector.com>`_"
#: ../../index.rst:51
msgid "`Prestashop Connector <https://github.com/OCA/connector-prestashop>`_"
msgstr "`Connecteur Prestashop <https://github.com/OCA/connector-prestashop>`_"
#: ../../index.rst:52
msgid "`solerp (Solr Connector) <https://github.com/akretion/solerp>`_"
msgstr "`solerp (Connecteur Solr) <https://github.com/akretion/solerp>`_"
#: ../../index.rst:54
msgid "`CMIS <https://github.com/OCA/connector-cmis>`_"
msgstr "`Connecteur CMIS <https://github.com/OCA/connector-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 <http://www.odoo.net.cn/new-intercompany-process-"
"module/>`_"
msgstr ""
"`Odoo Multi-sociétés <http://www.odoo.net.cn/new-intercompany-process-"
"module/>`_"
#: ../../index.rst:55
msgid ""
"`Odoo Asynchronous import module <https://github.com/OCA/connector-"
"interfaces/tree/8.0/base_import_async>`_"
msgstr ""
"`Module Odoo d'import asynchrone <https://github.com/OCA/connector-"
"interfaces/tree/8.0/base_import_async>`_"
#: ../../index.rst:56
msgid "`Salesforce Connector <https://github.com/OCA/connector-salesforce>`_"
msgstr "`Connecteur Salesforce <https://github.com/OCA/connector-salesforce>`_"
#: ../../index.rst:57
msgid ""
"`Google Spreadsheet Connector <https://github.com/akretion/connector-google-"
"spreadsheet>`_"
msgstr ""
"`Connecteur Google Spreadsheet <https://github.com/akretion/connector-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 <http://www.odoo.net.cn/new-intercompany-"
#~ "process-module/>`_"
#~ msgstr ""
#~ "`Odoo Multi-sociétés <http://www.odoo.net.cn/new-intercompany-"
#~ "process-module/>`_"
#~ 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…"

View File

@ -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 <guewen.baconnier@camptocamp.com>\n"
"Language-Team: fr <LL@li.org>\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 "
"<connectormagento:contribute>` which is more complete, most of the "
"information is the same."
msgstr ""
"Jetez un œil au :ref:`Guide du développeur du Connecteur Magento "
"<connectormagento:contribute>` 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 <https://bitbucket.org/anybox/"
"public_buildbot_buildouts/src/tip/odoo-connector.cfg>`_::"
msgstr ""
"La même chose en utilisant un `buildout <https://bitbucket.org/anybox/"
"public_buildbot_buildouts/src/tip/odoo-connector.cfg>`_::"
#: ../../project/contribute.rst:69
msgid ""
"Add `this patch <https://bitbucket.org/shimizukawa/sphinx-intl/pull-"
"request/9/>`_ to sphinx-intl (until merged) to support *fuzzy* translations"
msgstr ""
"Ajoutez `ce patch <https://bitbucket.org/shimizukawa/sphinx-intl/pull-"
"request/9/>`_ à 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 <https://bitbucket.org/shimizukawa/sphinx-intl/pull-"
#~ "request/9/issue-9-support-fuzzy-translations>`_ to sphinx-intl (until "
#~ "merged)"
#~ msgstr ""
#~ "Ajoutez `ce patch <https://bitbucket.org/shimizukawa/sphinx-intl/pull-"
#~ "request/9/issue-9-support-fuzzy-translations>`_ 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)"

View File

@ -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 ^<target^>` where ^<target^> 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

View File

@ -0,0 +1,9 @@
.. _changes:
#######
Changes
#######
.. include:: ../../CHANGES.rst
:start-line: 3

View File

@ -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
<connectormagento:contribute>` 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
<https://bitbucket.org/shimizukawa/sphinx-intl/pull-request/9/>`_
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
<https://bitbucket.org/anybox/public_buildbot_buildouts/src/tip/odoo-connector.cfg>`_::
$ 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.

View File

@ -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!

View File

@ -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. <http://fsf.org/>
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.
<one line to give the program's name and a brief idea of what it does.>
Copyright (C) <year> <name of author>
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 <http://www.gnu.org/licenses/>.
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
<http://www.gnu.org/licenses/>.

View File

@ -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

View File

@ -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"""

View File

@ -0,0 +1,317 @@
# Translation of Odoo Server.
# This file contains the translation of the following modules:
# * connector
#
# Translators:
# OCA Transbot <transbot@odoo-community.org>, 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 <transbot@odoo-community.org>, 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 ""

View File

@ -0,0 +1,317 @@
# Translation of Odoo Server.
# This file contains the translation of the following modules:
# * connector
#
# Translators:
# OCA Transbot <transbot@odoo-community.org>, 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 <transbot@odoo-community.org>, 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 ""

View File

@ -0,0 +1,317 @@
# Translation of Odoo Server.
# This file contains the translation of the following modules:
# * connector
#
# Translators:
# OCA Transbot <transbot@odoo-community.org>, 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 <transbot@odoo-community.org>, 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:"

View File

@ -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 "<p>No record to check.</p>\n"
" <p> 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. </p>\n"
" <p>The connectors list the new records to verify\n"
" based on their type. Only some need a manual\n"
" review.</p>\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 ""

View File

@ -0,0 +1,317 @@
# Translation of Odoo Server.
# This file contains the translation of the following modules:
# * connector
#
# Translators:
# OCA Transbot <transbot@odoo-community.org>, 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 <transbot@odoo-community.org>, 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 ""

View File

@ -0,0 +1,317 @@
# Translation of Odoo Server.
# This file contains the translation of the following modules:
# * connector
#
# Translators:
# OCA Transbot <transbot@odoo-community.org>, 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 <transbot@odoo-community.org>, 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:"

View File

@ -0,0 +1,317 @@
# Translation of Odoo Server.
# This file contains the translation of the following modules:
# * connector
#
# Translators:
# OCA Transbot <transbot@odoo-community.org>, 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 <transbot@odoo-community.org>, 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 ""

View File

@ -0,0 +1,317 @@
# Translation of Odoo Server.
# This file contains the translation of the following modules:
# * connector
#
# Translators:
# OCA Transbot <transbot@odoo-community.org>, 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 <transbot@odoo-community.org>, 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:"

View File

@ -0,0 +1,317 @@
# Translation of Odoo Server.
# This file contains the translation of the following modules:
# * connector
#
# Translators:
# OCA Transbot <transbot@odoo-community.org>, 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 <transbot@odoo-community.org>, 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 ""

View File

@ -0,0 +1,317 @@
# Translation of Odoo Server.
# This file contains the translation of the following modules:
# * connector
#
# Translators:
# OCA Transbot <transbot@odoo-community.org>, 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 <transbot@odoo-community.org>, 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 ""

View File

@ -0,0 +1,317 @@
# Translation of Odoo Server.
# This file contains the translation of the following modules:
# * connector
#
# Translators:
# OCA Transbot <transbot@odoo-community.org>, 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 <transbot@odoo-community.org>, 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 ""

View File

@ -0,0 +1,317 @@
# Translation of Odoo Server.
# This file contains the translation of the following modules:
# * connector
#
# Translators:
# OCA Transbot <transbot@odoo-community.org>, 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 <transbot@odoo-community.org>, 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 ""

View File

@ -0,0 +1,317 @@
# Translation of Odoo Server.
# This file contains the translation of the following modules:
# * connector
#
# Translators:
# OCA Transbot <transbot@odoo-community.org>, 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 <transbot@odoo-community.org>, 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 ""

View File

@ -0,0 +1,317 @@
# Translation of Odoo Server.
# This file contains the translation of the following modules:
# * connector
#
# Translators:
# OCA Transbot <transbot@odoo-community.org>, 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 <transbot@odoo-community.org>, 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 ""

View File

@ -0,0 +1,317 @@
# Translation of Odoo Server.
# This file contains the translation of the following modules:
# * connector
#
# Translators:
# OCA Transbot <transbot@odoo-community.org>, 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 <transbot@odoo-community.org>, 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 ""

View File

@ -0,0 +1,322 @@
# Translation of Odoo Server.
# This file contains the translation of the following modules:
# * connector
#
# Translators:
# OCA Transbot <transbot@odoo-community.org>, 2017
# leemannd <denis.leemann@camptocamp.com>, 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 <denis.leemann@camptocamp.com>, 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:"

View File

@ -0,0 +1,317 @@
# Translation of Odoo Server.
# This file contains the translation of the following modules:
# * connector
#
# Translators:
# OCA Transbot <transbot@odoo-community.org>, 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 <transbot@odoo-community.org>, 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 ""

View File

@ -0,0 +1,317 @@
# Translation of Odoo Server.
# This file contains the translation of the following modules:
# * connector
#
# Translators:
# OCA Transbot <transbot@odoo-community.org>, 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 <transbot@odoo-community.org>, 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 ""

View File

@ -0,0 +1,317 @@
# Translation of Odoo Server.
# This file contains the translation of the following modules:
# * connector
#
# Translators:
# OCA Transbot <transbot@odoo-community.org>, 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 <transbot@odoo-community.org>, 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 ""

View File

@ -0,0 +1,317 @@
# Translation of Odoo Server.
# This file contains the translation of the following modules:
# * connector
#
# Translators:
# OCA Transbot <transbot@odoo-community.org>, 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 <transbot@odoo-community.org>, 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:"

View File

@ -0,0 +1,317 @@
# Translation of Odoo Server.
# This file contains the translation of the following modules:
# * connector
#
# Translators:
# OCA Transbot <transbot@odoo-community.org>, 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 <transbot@odoo-community.org>, 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 ""

Some files were not shown because too many files have changed in this diff Show More