forked from OCA/connector
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathcore.py
160 lines (134 loc) · 5.85 KB
/
core.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
# Copyright 2017 Camptocamp SA
# License LGPL-3.0 or later (http://www.gnu.org/licenses/lgpl.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({},{})".format(
repr(self._env or self._collection), self.model_name
)