3 import dateutil.relativedelta
10 _logger = logging.getLogger(__name__)
11 #----------------------------------------------------------
12 # OpenERPSession RPC openerp backend access
13 #----------------------------------------------------------
14 class OpenERPSession(object):
16 An OpenERP RPC session, a given user can own multiple such sessions
19 .. attribute:: context
21 The session context, a ``dict``. Can be reloaded by calling
22 :meth:`openerpweb.openerpweb.OpenERPSession.get_context`
24 .. attribute:: domains_store
26 A ``dict`` matching domain keys to evaluable (but non-literal) domains.
28 Used to store references to non-literal domains which need to be
29 round-tripped to the client browser.
36 self._password = False
38 self.contexts_store = {}
39 self.domains_store = {}
40 self.jsonp_requests = {} # FIXME use a LRU
42 def __getstate__(self):
43 state = dict(self.__dict__)
48 def openerp_entreprise(self):
52 return self.model('publisher_warranty.contract').status()['status'] == 'full'
54 def build_connection(self):
55 conn = openerplib.Connection(self.config.connector, database=self._db, login=self._login,
56 user_id=self._uid, password=self._password)
59 def proxy(self, service):
60 return self.build_connection().get_service(service)
62 def bind(self, db, uid, login, password):
66 self._password = password
68 def authenticate(self, db, login, password, env):
69 # TODO use the openerplib API once it exposes authenticate()
70 uid = self.proxy('common').authenticate(db, login, password, env)
71 self.bind(db, uid, login, password)
73 if uid: self.get_context()
76 def assert_valid(self, force=False):
78 Ensures this session is valid (logged into the openerp server)
80 self.build_connection().check_login(force)
82 def execute(self, model, func, *l, **d):
84 model = self.build_connection().get_model(model)
85 r = getattr(model, func)(*l, **d)
88 def exec_workflow(self, model, id, signal):
90 r = self.proxy('object').exec_workflow(self._db, self._uid, self._password, model, signal, id)
93 def model(self, model):
94 """ Get an RPC proxy for the object ``model``, bound to this session.
96 :param model: an OpenERP model name
98 :rtype: a model object
100 return self.build_connection().get_model(model)
102 def get_context(self):
103 """ Re-initializes the current user's session context (based on
104 his preferences) by calling res.users.get_context() with the old
107 :returns: the new context
109 assert self._uid, "The user needs to be logged-in to initialize his context"
110 self.context = self.build_connection().get_user_context() or {}
115 def base_eval_context(self):
116 """ Default evaluation context for the session.
118 Used to evaluate contexts and domains.
122 current_date=datetime.date.today().strftime('%Y-%m-%d'),
125 relativedelta=dateutil.relativedelta.relativedelta
127 base.update(self.context)
130 def evaluation_context(self, context=None):
131 """ Returns the session's evaluation context, augmented with the
132 provided context if any.
134 :param dict context: to add merge in the session's base eval context
135 :returns: the augmented context
138 d = dict(self.base_eval_context)
144 def eval_context(self, context_to_eval, context=None):
145 """ Evaluates the provided context_to_eval in the context (haha) of
146 the context. Also merges the evaluated context with the session's context.
148 :param context_to_eval: a context to evaluate. Must be a dict or a
149 non-literal context. If it's a dict, will be
151 :type context_to_eval: openerpweb.nonliterals.Context
152 :returns: the evaluated context
155 :raises: ``TypeError`` if ``context_to_eval`` is neither a dict nor
159 self.base_eval_context,
162 # adding the context of the session to send to the openerp server
163 ccontext = nonliterals.CompoundContext(self.context, context_to_eval or {})
164 ccontext.session = self
165 return ccontext.evaluate(ctx)
167 def eval_domain(self, domain, context=None):
168 """ Evaluates the provided domain using the provided context
169 (merged with the session's evaluation context)
171 :param domain: an OpenERP domain as a list or as a
172 :class:`openerpweb.nonliterals.Domain` instance
174 In the second case, it will be evaluated and returned.
175 :type domain: openerpweb.nonliterals.Domain
176 :param dict context: the context to use in the evaluation, if any.
177 :returns: the evaluated domain
180 :raises: ``TypeError`` if ``domain`` is neither a list nor a Domain
182 if isinstance(domain, list):
185 cdomain = nonliterals.CompoundDomain(domain)
186 cdomain.session = self
187 return cdomain.evaluate(context or {})