entities/wfobjs.py
author Aurelien Campeas <aurelien.campeas@logilab.fr>
Fri, 25 May 2012 16:19:21 +0200
changeset 8427 63c4c65e4db1
parent 8216 99ff746e8de8
child 8900 010a59e12d89
permissions -rw-r--r--
[web/views/staticcontroller] safety belt for unguessed mimetypes (closes #2380304)
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
8190
2a3c1b787688 [vreg] move base registry implementation to logilab.common. Closes #1916014
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7990
diff changeset
     1
# copyright 2003-2012 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
5421
8167de96c523 proper licensing information (LGPL-2.1). Hope I get it right this time.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4835
diff changeset
     2
# contact http://www.logilab.fr/ -- mailto:contact@logilab.fr
8167de96c523 proper licensing information (LGPL-2.1). Hope I get it right this time.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4835
diff changeset
     3
#
8167de96c523 proper licensing information (LGPL-2.1). Hope I get it right this time.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4835
diff changeset
     4
# This file is part of CubicWeb.
8167de96c523 proper licensing information (LGPL-2.1). Hope I get it right this time.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4835
diff changeset
     5
#
8167de96c523 proper licensing information (LGPL-2.1). Hope I get it right this time.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4835
diff changeset
     6
# CubicWeb is free software: you can redistribute it and/or modify it under the
8167de96c523 proper licensing information (LGPL-2.1). Hope I get it right this time.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4835
diff changeset
     7
# terms of the GNU Lesser General Public License as published by the Free
8167de96c523 proper licensing information (LGPL-2.1). Hope I get it right this time.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4835
diff changeset
     8
# Software Foundation, either version 2.1 of the License, or (at your option)
8167de96c523 proper licensing information (LGPL-2.1). Hope I get it right this time.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4835
diff changeset
     9
# any later version.
8167de96c523 proper licensing information (LGPL-2.1). Hope I get it right this time.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4835
diff changeset
    10
#
5424
8ecbcbff9777 replace logilab-common by CubicWeb in disclaimer
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5421
diff changeset
    11
# CubicWeb is distributed in the hope that it will be useful, but WITHOUT
5421
8167de96c523 proper licensing information (LGPL-2.1). Hope I get it right this time.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4835
diff changeset
    12
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
8167de96c523 proper licensing information (LGPL-2.1). Hope I get it right this time.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4835
diff changeset
    13
# FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License for more
8167de96c523 proper licensing information (LGPL-2.1). Hope I get it right this time.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4835
diff changeset
    14
# details.
8167de96c523 proper licensing information (LGPL-2.1). Hope I get it right this time.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4835
diff changeset
    15
#
8167de96c523 proper licensing information (LGPL-2.1). Hope I get it right this time.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4835
diff changeset
    16
# You should have received a copy of the GNU Lesser General Public License along
8167de96c523 proper licensing information (LGPL-2.1). Hope I get it right this time.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4835
diff changeset
    17
# with CubicWeb.  If not, see <http://www.gnu.org/licenses/>.
5556
9ab2b4c74baf [entity] introduce a new 'adapters' registry
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5426
diff changeset
    18
"""workflow handling:
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    19
5556
9ab2b4c74baf [entity] introduce a new 'adapters' registry
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5426
diff changeset
    20
* entity types defining workflow (Workflow, State, Transition...)
9ab2b4c74baf [entity] introduce a new 'adapters' registry
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5426
diff changeset
    21
* workflow history (TrInfo)
9ab2b4c74baf [entity] introduce a new 'adapters' registry
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5426
diff changeset
    22
* adapter for workflowable entities (IWorkflowableAdapter)
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    23
"""
5556
9ab2b4c74baf [entity] introduce a new 'adapters' registry
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5426
diff changeset
    24
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    25
__docformat__ = "restructuredtext en"
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    26
2920
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2917
diff changeset
    27
from warnings import warn
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2917
diff changeset
    28
2948
d3cd8bd20ee5 override clear_all_caches to clear cwetype_workflow cache
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2947
diff changeset
    29
from logilab.common.decorators import cached, clear_cache
2920
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2917
diff changeset
    30
from logilab.common.deprecation import deprecated
3757
122a01751d59 2.4 compat
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3698
diff changeset
    31
from logilab.common.compat import any
2920
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2917
diff changeset
    32
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    33
from cubicweb.entities import AnyEntity, fetch_config
5556
9ab2b4c74baf [entity] introduce a new 'adapters' registry
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5426
diff changeset
    34
from cubicweb.view import EntityAdapter
8190
2a3c1b787688 [vreg] move base registry implementation to logilab.common. Closes #1916014
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7990
diff changeset
    35
from cubicweb.predicates import relation_possible
4023
eae23c40627a drop common subpackage
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4012
diff changeset
    36
from cubicweb.mixins import MI_REL_TRIGGERS
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    37
2988
89d97d7c0508 [wf] use custom exception class
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2987
diff changeset
    38
class WorkflowException(Exception): pass
1572
469787f6ea2b delete-trailing-whitespaces
sylvain.thenault@logilab.fr
parents: 1154
diff changeset
    39
2920
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2917
diff changeset
    40
class Workflow(AnyEntity):
3377
dd9d292b6a6d use __regid__ instead of id on appobject classes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3038
diff changeset
    41
    __regid__ = 'Workflow'
2920
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2917
diff changeset
    42
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2917
diff changeset
    43
    @property
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2917
diff changeset
    44
    def initial(self):
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2917
diff changeset
    45
        """return the initial state for this workflow"""
2944
3bd49b70f7f9 [wf] return None, not empty list
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2943
diff changeset
    46
        return self.initial_state and self.initial_state[0] or None
2920
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2917
diff changeset
    47
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2917
diff changeset
    48
    def is_default_workflow_of(self, etype):
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2917
diff changeset
    49
        """return True if this workflow is the default workflow for the given
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2917
diff changeset
    50
        entity type
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2917
diff changeset
    51
        """
2943
77622caef9bd [schema] default_workflow_of more naturally expressed as default_workflow
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2920
diff changeset
    52
        return any(et for et in self.reverse_default_workflow
77622caef9bd [schema] default_workflow_of more naturally expressed as default_workflow
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2920
diff changeset
    53
                   if et.name == etype)
2920
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2917
diff changeset
    54
2976
d01417c14f35 [wf] new iter_worfklows method on workflow
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2975
diff changeset
    55
    def iter_workflows(self, _done=None):
d01417c14f35 [wf] new iter_worfklows method on workflow
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2975
diff changeset
    56
        """return an iterator on actual workflows, eg this workflow and its
d01417c14f35 [wf] new iter_worfklows method on workflow
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2975
diff changeset
    57
        subworkflows
d01417c14f35 [wf] new iter_worfklows method on workflow
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2975
diff changeset
    58
        """
d01417c14f35 [wf] new iter_worfklows method on workflow
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2975
diff changeset
    59
        # infinite loop safety belt
d01417c14f35 [wf] new iter_worfklows method on workflow
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2975
diff changeset
    60
        if _done is None:
d01417c14f35 [wf] new iter_worfklows method on workflow
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2975
diff changeset
    61
            _done = set()
d01417c14f35 [wf] new iter_worfklows method on workflow
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2975
diff changeset
    62
        yield self
d01417c14f35 [wf] new iter_worfklows method on workflow
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2975
diff changeset
    63
        _done.add(self.eid)
3406
e343f37f7013 use self._cw instead of self.req
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3405
diff changeset
    64
        for tr in self._cw.execute('Any T WHERE T is WorkflowTransition, '
2976
d01417c14f35 [wf] new iter_worfklows method on workflow
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2975
diff changeset
    65
                                   'T transition_of WF, WF eid %(wf)s',
d01417c14f35 [wf] new iter_worfklows method on workflow
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2975
diff changeset
    66
                                   {'wf': self.eid}).entities():
d01417c14f35 [wf] new iter_worfklows method on workflow
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2975
diff changeset
    67
            if tr.subwf.eid in _done:
d01417c14f35 [wf] new iter_worfklows method on workflow
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2975
diff changeset
    68
                continue
d01417c14f35 [wf] new iter_worfklows method on workflow
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2975
diff changeset
    69
            for subwf in tr.subwf.iter_workflows(_done):
d01417c14f35 [wf] new iter_worfklows method on workflow
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2975
diff changeset
    70
                yield subwf
d01417c14f35 [wf] new iter_worfklows method on workflow
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2975
diff changeset
    71
2920
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2917
diff changeset
    72
    # state / transitions accessors ############################################
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2917
diff changeset
    73
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2917
diff changeset
    74
    def state_by_name(self, statename):
3406
e343f37f7013 use self._cw instead of self.req
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3405
diff changeset
    75
        rset = self._cw.execute('Any S, SN WHERE S name SN, S name %(n)s, '
2920
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2917
diff changeset
    76
                                'S state_of WF, WF eid %(wf)s',
5174
78438ad513ca #759035: Automate addition of eid cachekey in RQL analysis
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4835
diff changeset
    77
                                {'n': statename, 'wf': self.eid})
2920
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2917
diff changeset
    78
        if rset:
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2917
diff changeset
    79
            return rset.get_entity(0, 0)
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2917
diff changeset
    80
        return None
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2917
diff changeset
    81
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2917
diff changeset
    82
    def state_by_eid(self, eid):
3406
e343f37f7013 use self._cw instead of self.req
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3405
diff changeset
    83
        rset = self._cw.execute('Any S, SN WHERE S name SN, S eid %(s)s, '
2920
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2917
diff changeset
    84
                                'S state_of WF, WF eid %(wf)s',
5174
78438ad513ca #759035: Automate addition of eid cachekey in RQL analysis
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4835
diff changeset
    85
                                {'s': eid, 'wf': self.eid})
2920
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2917
diff changeset
    86
        if rset:
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2917
diff changeset
    87
            return rset.get_entity(0, 0)
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2917
diff changeset
    88
        return None
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2917
diff changeset
    89
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2917
diff changeset
    90
    def transition_by_name(self, trname):
3406
e343f37f7013 use self._cw instead of self.req
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3405
diff changeset
    91
        rset = self._cw.execute('Any T, TN WHERE T name TN, T name %(n)s, '
2920
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2917
diff changeset
    92
                                'T transition_of WF, WF eid %(wf)s',
5174
78438ad513ca #759035: Automate addition of eid cachekey in RQL analysis
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4835
diff changeset
    93
                                {'n': trname, 'wf': self.eid})
2920
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2917
diff changeset
    94
        if rset:
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2917
diff changeset
    95
            return rset.get_entity(0, 0)
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2917
diff changeset
    96
        return None
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    97
2920
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2917
diff changeset
    98
    def transition_by_eid(self, eid):
3406
e343f37f7013 use self._cw instead of self.req
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3405
diff changeset
    99
        rset = self._cw.execute('Any T, TN WHERE T name TN, T eid %(t)s, '
2920
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2917
diff changeset
   100
                                'T transition_of WF, WF eid %(wf)s',
5174
78438ad513ca #759035: Automate addition of eid cachekey in RQL analysis
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4835
diff changeset
   101
                                {'t': eid, 'wf': self.eid})
2920
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2917
diff changeset
   102
        if rset:
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2917
diff changeset
   103
            return rset.get_entity(0, 0)
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2917
diff changeset
   104
        return None
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2917
diff changeset
   105
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2917
diff changeset
   106
    # wf construction methods ##################################################
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2917
diff changeset
   107
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2917
diff changeset
   108
    def add_state(self, name, initial=False, **kwargs):
2986
d8f2e53702be [wf] new methods to build wf w/ workflow transition
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2980
diff changeset
   109
        """add a state to this workflow"""
3406
e343f37f7013 use self._cw instead of self.req
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3405
diff changeset
   110
        state = self._cw.create_entity('State', name=unicode(name), **kwargs)
e343f37f7013 use self._cw instead of self.req
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3405
diff changeset
   111
        self._cw.execute('SET S state_of WF WHERE S eid %(s)s, WF eid %(wf)s',
5174
78438ad513ca #759035: Automate addition of eid cachekey in RQL analysis
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4835
diff changeset
   112
                         {'s': state.eid, 'wf': self.eid})
2920
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2917
diff changeset
   113
        if initial:
3959
e6ecaf93c0ba improve error message for redundant initial workflow states
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 3765
diff changeset
   114
            assert not self.initial, "Initial state already defined as %s" % self.initial
3406
e343f37f7013 use self._cw instead of self.req
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3405
diff changeset
   115
            self._cw.execute('SET WF initial_state S '
2920
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2917
diff changeset
   116
                             'WHERE S eid %(s)s, WF eid %(wf)s',
5174
78438ad513ca #759035: Automate addition of eid cachekey in RQL analysis
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4835
diff changeset
   117
                             {'s': state.eid, 'wf': self.eid})
2920
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2917
diff changeset
   118
        return state
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2917
diff changeset
   119
2986
d8f2e53702be [wf] new methods to build wf w/ workflow transition
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2980
diff changeset
   120
    def _add_transition(self, trtype, name, fromstates,
d8f2e53702be [wf] new methods to build wf w/ workflow transition
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2980
diff changeset
   121
                        requiredgroups=(), conditions=(), **kwargs):
3406
e343f37f7013 use self._cw instead of self.req
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3405
diff changeset
   122
        tr = self._cw.create_entity(trtype, name=unicode(name), **kwargs)
e343f37f7013 use self._cw instead of self.req
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3405
diff changeset
   123
        self._cw.execute('SET T transition_of WF '
2920
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2917
diff changeset
   124
                         'WHERE T eid %(t)s, WF eid %(wf)s',
5174
78438ad513ca #759035: Automate addition of eid cachekey in RQL analysis
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4835
diff changeset
   125
                         {'t': tr.eid, 'wf': self.eid})
2987
5082dec70ed8 [wf] ensure fromstates given, allow to give an entity (avoid spotless error, we can iter on entities...)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2986
diff changeset
   126
        assert fromstates, fromstates
5082dec70ed8 [wf] ensure fromstates given, allow to give an entity (avoid spotless error, we can iter on entities...)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2986
diff changeset
   127
        if not isinstance(fromstates, (tuple, list)):
5082dec70ed8 [wf] ensure fromstates given, allow to give an entity (avoid spotless error, we can iter on entities...)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2986
diff changeset
   128
            fromstates = (fromstates,)
2920
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2917
diff changeset
   129
        for state in fromstates:
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2917
diff changeset
   130
            if hasattr(state, 'eid'):
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2917
diff changeset
   131
                state = state.eid
3406
e343f37f7013 use self._cw instead of self.req
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3405
diff changeset
   132
            self._cw.execute('SET S allowed_transition T '
2920
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2917
diff changeset
   133
                             'WHERE S eid %(s)s, T eid %(t)s',
5174
78438ad513ca #759035: Automate addition of eid cachekey in RQL analysis
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4835
diff changeset
   134
                             {'s': state, 't': tr.eid})
4645
fd4e32f17211 deprecate Transition.set_transition_permissions in favor of set_permissions (after all we know we're on a transition entity)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4644
diff changeset
   135
        tr.set_permissions(requiredgroups, conditions, reset=False)
2986
d8f2e53702be [wf] new methods to build wf w/ workflow transition
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2980
diff changeset
   136
        return tr
d8f2e53702be [wf] new methods to build wf w/ workflow transition
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2980
diff changeset
   137
3628
440931181322 [wf engine] support for subwf exit point with no destination state: go back to state from which we entered into the subworkflow
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3621
diff changeset
   138
    def add_transition(self, name, fromstates, tostate=None,
2986
d8f2e53702be [wf] new methods to build wf w/ workflow transition
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2980
diff changeset
   139
                       requiredgroups=(), conditions=(), **kwargs):
d8f2e53702be [wf] new methods to build wf w/ workflow transition
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2980
diff changeset
   140
        """add a transition to this workflow from some state(s) to another"""
d8f2e53702be [wf] new methods to build wf w/ workflow transition
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2980
diff changeset
   141
        tr = self._add_transition('Transition', name, fromstates,
d8f2e53702be [wf] new methods to build wf w/ workflow transition
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2980
diff changeset
   142
                                  requiredgroups, conditions, **kwargs)
3628
440931181322 [wf engine] support for subwf exit point with no destination state: go back to state from which we entered into the subworkflow
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3621
diff changeset
   143
        if tostate is not None:
440931181322 [wf engine] support for subwf exit point with no destination state: go back to state from which we entered into the subworkflow
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3621
diff changeset
   144
            if hasattr(tostate, 'eid'):
440931181322 [wf engine] support for subwf exit point with no destination state: go back to state from which we entered into the subworkflow
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3621
diff changeset
   145
                tostate = tostate.eid
3629
559cad62c786 backport stable branch
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3589 3628
diff changeset
   146
            self._cw.execute('SET T destination_state S '
3628
440931181322 [wf engine] support for subwf exit point with no destination state: go back to state from which we entered into the subworkflow
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3621
diff changeset
   147
                             'WHERE S eid %(s)s, T eid %(t)s',
5174
78438ad513ca #759035: Automate addition of eid cachekey in RQL analysis
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4835
diff changeset
   148
                             {'t': tr.eid, 's': tostate})
2986
d8f2e53702be [wf] new methods to build wf w/ workflow transition
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2980
diff changeset
   149
        return tr
d8f2e53702be [wf] new methods to build wf w/ workflow transition
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2980
diff changeset
   150
3628
440931181322 [wf engine] support for subwf exit point with no destination state: go back to state from which we entered into the subworkflow
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3621
diff changeset
   151
    def add_wftransition(self, name, subworkflow, fromstates, exitpoints=(),
3582
28547f21308e two bits of docstring
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 3542
diff changeset
   152
                         requiredgroups=(), conditions=(), **kwargs):
2986
d8f2e53702be [wf] new methods to build wf w/ workflow transition
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2980
diff changeset
   153
        """add a workflow transition to this workflow"""
d8f2e53702be [wf] new methods to build wf w/ workflow transition
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2980
diff changeset
   154
        tr = self._add_transition('WorkflowTransition', name, fromstates,
d8f2e53702be [wf] new methods to build wf w/ workflow transition
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2980
diff changeset
   155
                                  requiredgroups, conditions, **kwargs)
d8f2e53702be [wf] new methods to build wf w/ workflow transition
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2980
diff changeset
   156
        if hasattr(subworkflow, 'eid'):
d8f2e53702be [wf] new methods to build wf w/ workflow transition
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2980
diff changeset
   157
            subworkflow = subworkflow.eid
4024
6a14cff373c3 more api update
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4023
diff changeset
   158
        assert self._cw.execute('SET T subworkflow WF WHERE WF eid %(wf)s,T eid %(t)s',
5174
78438ad513ca #759035: Automate addition of eid cachekey in RQL analysis
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4835
diff changeset
   159
                                {'t': tr.eid, 'wf': subworkflow})
2986
d8f2e53702be [wf] new methods to build wf w/ workflow transition
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2980
diff changeset
   160
        for fromstate, tostate in exitpoints:
d8f2e53702be [wf] new methods to build wf w/ workflow transition
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2980
diff changeset
   161
            tr.add_exit_point(fromstate, tostate)
2920
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2917
diff changeset
   162
        return tr
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2917
diff changeset
   163
3999
5dd6ffc2ccae added replace_state method to ease workflow migration. backported from forge as a reminder, not really tested yet
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3986
diff changeset
   164
    def replace_state(self, todelstate, replacement):
5dd6ffc2ccae added replace_state method to ease workflow migration. backported from forge as a reminder, not really tested yet
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3986
diff changeset
   165
        """migration convenience method"""
5dd6ffc2ccae added replace_state method to ease workflow migration. backported from forge as a reminder, not really tested yet
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3986
diff changeset
   166
        if not hasattr(todelstate, 'eid'):
5dd6ffc2ccae added replace_state method to ease workflow migration. backported from forge as a reminder, not really tested yet
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3986
diff changeset
   167
            todelstate = self.state_by_name(todelstate)
5dd6ffc2ccae added replace_state method to ease workflow migration. backported from forge as a reminder, not really tested yet
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3986
diff changeset
   168
        if not hasattr(replacement, 'eid'):
5dd6ffc2ccae added replace_state method to ease workflow migration. backported from forge as a reminder, not really tested yet
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3986
diff changeset
   169
            replacement = self.state_by_name(replacement)
4835
13b0b96d7982 [repo] enhanced security handling: deprecates unsafe_execute, in favor of explicit read/write security control using the `enabled_security` context manager. Also code executed on the repository side is now unsafe by default.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4716
diff changeset
   170
        execute = self._cw.execute
5174
78438ad513ca #759035: Automate addition of eid cachekey in RQL analysis
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4835
diff changeset
   171
        execute('SET X in_state S WHERE S eid %(s)s', {'s': todelstate.eid})
3999
5dd6ffc2ccae added replace_state method to ease workflow migration. backported from forge as a reminder, not really tested yet
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3986
diff changeset
   172
        execute('SET X from_state NS WHERE X to_state OS, OS eid %(os)s, NS eid %(ns)s',
5174
78438ad513ca #759035: Automate addition of eid cachekey in RQL analysis
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4835
diff changeset
   173
                {'os': todelstate.eid, 'ns': replacement.eid})
3999
5dd6ffc2ccae added replace_state method to ease workflow migration. backported from forge as a reminder, not really tested yet
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3986
diff changeset
   174
        execute('SET X to_state NS WHERE X to_state OS, OS eid %(os)s, NS eid %(ns)s',
5174
78438ad513ca #759035: Automate addition of eid cachekey in RQL analysis
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4835
diff changeset
   175
                {'os': todelstate.eid, 'ns': replacement.eid})
5557
1a534c596bff [entity] continue cleanup of Entity/AnyEntity namespace
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5556
diff changeset
   176
        todelstate.cw_delete()
3999
5dd6ffc2ccae added replace_state method to ease workflow migration. backported from forge as a reminder, not really tested yet
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3986
diff changeset
   177
2920
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2917
diff changeset
   178
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2917
diff changeset
   179
class BaseTransition(AnyEntity):
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2917
diff changeset
   180
    """customized class for abstract transition
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2917
diff changeset
   181
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2917
diff changeset
   182
    provides a specific may_be_fired method to check if the relation may be
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2917
diff changeset
   183
    fired by the logged user
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   184
    """
3377
dd9d292b6a6d use __regid__ instead of id on appobject classes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3038
diff changeset
   185
    __regid__ = 'BaseTransition'
7827
9bbf83f68bcc [entity] upgrade fetch_[unrelated_]order to benefit from changes introduced in 3.14 (closes #1942758)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7406
diff changeset
   186
    fetch_attrs, cw_fetch_order = fetch_config(['name', 'type'])
1572
469787f6ea2b delete-trailing-whitespaces
sylvain.thenault@logilab.fr
parents: 1154
diff changeset
   187
2951
d0b77dd27740 [wf] BaseTransition is a virtual type
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2948
diff changeset
   188
    def __init__(self, *args, **kwargs):
3377
dd9d292b6a6d use __regid__ instead of id on appobject classes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3038
diff changeset
   189
        if self.__regid__ == 'BaseTransition':
2988
89d97d7c0508 [wf] use custom exception class
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2987
diff changeset
   190
            raise WorkflowException('should not be instantiated')
2954
48507919b6e3 [wf] oops, BaseTransition.__init__ may be called for subclasses
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2951
diff changeset
   191
        super(BaseTransition, self).__init__(*args, **kwargs)
2951
d0b77dd27740 [wf] BaseTransition is a virtual type
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2948
diff changeset
   192
2975
fed52d317ba7 [wf] new .workflow property on states and transitions
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2954
diff changeset
   193
    @property
fed52d317ba7 [wf] new .workflow property on states and transitions
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2954
diff changeset
   194
    def workflow(self):
fed52d317ba7 [wf] new .workflow property on states and transitions
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2954
diff changeset
   195
        return self.transition_of[0]
fed52d317ba7 [wf] new .workflow property on states and transitions
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2954
diff changeset
   196
2991
dab951c08896 cleanup
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2990
diff changeset
   197
    def has_input_state(self, state):
dab951c08896 cleanup
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2990
diff changeset
   198
        if hasattr(state, 'eid'):
dab951c08896 cleanup
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2990
diff changeset
   199
            state = state.eid
dab951c08896 cleanup
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2990
diff changeset
   200
        return any(s for s in self.reverse_allowed_transition if s.eid == state)
dab951c08896 cleanup
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2990
diff changeset
   201
2920
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2917
diff changeset
   202
    def may_be_fired(self, eid):
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2917
diff changeset
   203
        """return true if the logged user may fire this transition
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   204
2920
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2917
diff changeset
   205
        `eid` is the eid of the object on which we may fire the transition
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   206
        """
3406
e343f37f7013 use self._cw instead of self.req
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3405
diff changeset
   207
        user = self._cw.user
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   208
        # check user is at least in one of the required groups if any
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   209
        groups = frozenset(g.name for g in self.require_group)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   210
        if groups:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   211
            matches = user.matching_groups(groups)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   212
            if matches:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   213
                return matches
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   214
            if 'owners' in groups and user.owns(eid):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   215
                return True
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   216
        # check one of the rql expression conditions matches if any
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   217
        if self.condition:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   218
            for rqlexpr in self.condition:
3406
e343f37f7013 use self._cw instead of self.req
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3405
diff changeset
   219
                if rqlexpr.check_expression(self._cw, eid):
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   220
                    return True
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   221
        if self.condition or groups:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   222
            return False
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   223
        return True
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   224
4645
fd4e32f17211 deprecate Transition.set_transition_permissions in favor of set_permissions (after all we know we're on a transition entity)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4644
diff changeset
   225
    def set_permissions(self, requiredgroups=(), conditions=(), reset=True):
2920
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2917
diff changeset
   226
        """set or add (if `reset` is False) groups and conditions for this
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2917
diff changeset
   227
        transition
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2917
diff changeset
   228
        """
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2917
diff changeset
   229
        if reset:
3406
e343f37f7013 use self._cw instead of self.req
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3405
diff changeset
   230
            self._cw.execute('DELETE T require_group G WHERE T eid %(x)s',
5174
78438ad513ca #759035: Automate addition of eid cachekey in RQL analysis
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4835
diff changeset
   231
                             {'x': self.eid})
3406
e343f37f7013 use self._cw instead of self.req
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3405
diff changeset
   232
            self._cw.execute('DELETE T condition R WHERE T eid %(x)s',
5174
78438ad513ca #759035: Automate addition of eid cachekey in RQL analysis
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4835
diff changeset
   233
                             {'x': self.eid})
2920
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2917
diff changeset
   234
        for gname in requiredgroups:
3406
e343f37f7013 use self._cw instead of self.req
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3405
diff changeset
   235
            rset = self._cw.execute('SET T require_group G '
2920
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2917
diff changeset
   236
                                    'WHERE T eid %(x)s, G name %(gn)s',
5174
78438ad513ca #759035: Automate addition of eid cachekey in RQL analysis
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4835
diff changeset
   237
                                    {'x': self.eid, 'gn': gname})
2920
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2917
diff changeset
   238
            assert rset, '%s is not a known group' % gname
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2917
diff changeset
   239
        if isinstance(conditions, basestring):
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2917
diff changeset
   240
            conditions = (conditions,)
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2917
diff changeset
   241
        for expr in conditions:
3542
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3528
diff changeset
   242
            if isinstance(expr, basestring):
3528
77a69de16709 support for automatic transition
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3038
diff changeset
   243
                kwargs = {'expr': unicode(expr)}
3542
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3528
diff changeset
   244
            else:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3528
diff changeset
   245
                assert isinstance(expr, dict)
3528
77a69de16709 support for automatic transition
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3038
diff changeset
   246
                kwargs = expr
77a69de16709 support for automatic transition
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3038
diff changeset
   247
            kwargs['x'] = self.eid
77a69de16709 support for automatic transition
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3038
diff changeset
   248
            kwargs.setdefault('mainvars', u'X')
3406
e343f37f7013 use self._cw instead of self.req
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3405
diff changeset
   249
            self._cw.execute('INSERT RQLExpression X: X exprtype "ERQLExpression", '
3528
77a69de16709 support for automatic transition
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3038
diff changeset
   250
                             'X expression %(expr)s, X mainvars %(mainvars)s, '
5174
78438ad513ca #759035: Automate addition of eid cachekey in RQL analysis
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4835
diff changeset
   251
                             'T condition X WHERE T eid %(x)s', kwargs)
2920
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2917
diff changeset
   252
        # XXX clear caches?
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2917
diff changeset
   253
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2917
diff changeset
   254
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2917
diff changeset
   255
class Transition(BaseTransition):
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2917
diff changeset
   256
    """customized class for Transition entities"""
3377
dd9d292b6a6d use __regid__ instead of id on appobject classes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3038
diff changeset
   257
    __regid__ = 'Transition'
2920
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2917
diff changeset
   258
8212
a045d3821990 [workflow view] Display a non-localized version of state/transition names (closes #1912537).
Damien Garaud <damien.garaud@logilab.fr>
parents: 7990
diff changeset
   259
    def dc_long_title(self):
a045d3821990 [workflow view] Display a non-localized version of state/transition names (closes #1912537).
Damien Garaud <damien.garaud@logilab.fr>
parents: 7990
diff changeset
   260
        return '%s (%s)' % (self.name, self._cw._(self.name))
a045d3821990 [workflow view] Display a non-localized version of state/transition names (closes #1912537).
Damien Garaud <damien.garaud@logilab.fr>
parents: 7990
diff changeset
   261
4644
021035b9a7ab introduce 'go back' transition: transition without destination state will go to the state we were coming from
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4436
diff changeset
   262
    def destination(self, entity):
021035b9a7ab introduce 'go back' transition: transition without destination state will go to the state we were coming from
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4436
diff changeset
   263
        try:
021035b9a7ab introduce 'go back' transition: transition without destination state will go to the state we were coming from
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4436
diff changeset
   264
            return self.destination_state[0]
021035b9a7ab introduce 'go back' transition: transition without destination state will go to the state we were coming from
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4436
diff changeset
   265
        except IndexError:
5556
9ab2b4c74baf [entity] introduce a new 'adapters' registry
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5426
diff changeset
   266
            return entity.cw_adapt_to('IWorkflowable').latest_trinfo().previous_state
4644
021035b9a7ab introduce 'go back' transition: transition without destination state will go to the state we were coming from
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4436
diff changeset
   267
4646
322c3dd96dd5 [workflow] finish refactoring introduced by 021035b9a7ab for 'go back' transition:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4645
diff changeset
   268
    def potential_destinations(self):
322c3dd96dd5 [workflow] finish refactoring introduced by 021035b9a7ab for 'go back' transition:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4645
diff changeset
   269
        try:
322c3dd96dd5 [workflow] finish refactoring introduced by 021035b9a7ab for 'go back' transition:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4645
diff changeset
   270
            yield self.destination_state[0]
322c3dd96dd5 [workflow] finish refactoring introduced by 021035b9a7ab for 'go back' transition:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4645
diff changeset
   271
        except IndexError:
4647
6d7589b4ae6f [workflow] fix potential destination for go back transition
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4646
diff changeset
   272
            for incomingstate in self.reverse_allowed_transition:
6d7589b4ae6f [workflow] fix potential destination for go back transition
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4646
diff changeset
   273
                for tr in incomingstate.reverse_destination_state:
6d7589b4ae6f [workflow] fix potential destination for go back transition
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4646
diff changeset
   274
                    for previousstate in tr.reverse_allowed_transition:
6d7589b4ae6f [workflow] fix potential destination for go back transition
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4646
diff changeset
   275
                        yield previousstate
2920
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2917
diff changeset
   276
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2917
diff changeset
   277
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2917
diff changeset
   278
class WorkflowTransition(BaseTransition):
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2917
diff changeset
   279
    """customized class for WorkflowTransition entities"""
3377
dd9d292b6a6d use __regid__ instead of id on appobject classes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3038
diff changeset
   280
    __regid__ = 'WorkflowTransition'
2920
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2917
diff changeset
   281
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2917
diff changeset
   282
    @property
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2917
diff changeset
   283
    def subwf(self):
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2917
diff changeset
   284
        return self.subworkflow[0]
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2917
diff changeset
   285
4646
322c3dd96dd5 [workflow] finish refactoring introduced by 021035b9a7ab for 'go back' transition:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4645
diff changeset
   286
    def destination(self, entity):
2920
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2917
diff changeset
   287
        return self.subwf.initial
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2917
diff changeset
   288
4646
322c3dd96dd5 [workflow] finish refactoring introduced by 021035b9a7ab for 'go back' transition:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4645
diff changeset
   289
    def potential_destinations(self):
322c3dd96dd5 [workflow] finish refactoring introduced by 021035b9a7ab for 'go back' transition:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4645
diff changeset
   290
        yield self.subwf.initial
322c3dd96dd5 [workflow] finish refactoring introduced by 021035b9a7ab for 'go back' transition:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4645
diff changeset
   291
2986
d8f2e53702be [wf] new methods to build wf w/ workflow transition
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2980
diff changeset
   292
    def add_exit_point(self, fromstate, tostate):
d8f2e53702be [wf] new methods to build wf w/ workflow transition
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2980
diff changeset
   293
        if hasattr(fromstate, 'eid'):
d8f2e53702be [wf] new methods to build wf w/ workflow transition
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2980
diff changeset
   294
            fromstate = fromstate.eid
3628
440931181322 [wf engine] support for subwf exit point with no destination state: go back to state from which we entered into the subworkflow
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3621
diff changeset
   295
        if tostate is None:
3629
559cad62c786 backport stable branch
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3589 3628
diff changeset
   296
            self._cw.execute('INSERT SubWorkflowExitPoint X: T subworkflow_exit X, '
3628
440931181322 [wf engine] support for subwf exit point with no destination state: go back to state from which we entered into the subworkflow
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3621
diff changeset
   297
                             'X subworkflow_state FS WHERE T eid %(t)s, FS eid %(fs)s',
5174
78438ad513ca #759035: Automate addition of eid cachekey in RQL analysis
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4835
diff changeset
   298
                             {'t': self.eid, 'fs': fromstate})
3628
440931181322 [wf engine] support for subwf exit point with no destination state: go back to state from which we entered into the subworkflow
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3621
diff changeset
   299
        else:
440931181322 [wf engine] support for subwf exit point with no destination state: go back to state from which we entered into the subworkflow
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3621
diff changeset
   300
            if hasattr(tostate, 'eid'):
440931181322 [wf engine] support for subwf exit point with no destination state: go back to state from which we entered into the subworkflow
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3621
diff changeset
   301
                tostate = tostate.eid
3629
559cad62c786 backport stable branch
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3589 3628
diff changeset
   302
            self._cw.execute('INSERT SubWorkflowExitPoint X: T subworkflow_exit X, '
3628
440931181322 [wf engine] support for subwf exit point with no destination state: go back to state from which we entered into the subworkflow
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3621
diff changeset
   303
                             'X subworkflow_state FS, X destination_state TS '
440931181322 [wf engine] support for subwf exit point with no destination state: go back to state from which we entered into the subworkflow
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3621
diff changeset
   304
                             'WHERE T eid %(t)s, FS eid %(fs)s, TS eid %(ts)s',
5174
78438ad513ca #759035: Automate addition of eid cachekey in RQL analysis
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4835
diff changeset
   305
                             {'t': self.eid, 'fs': fromstate, 'ts': tostate})
2986
d8f2e53702be [wf] new methods to build wf w/ workflow transition
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2980
diff changeset
   306
3628
440931181322 [wf engine] support for subwf exit point with no destination state: go back to state from which we entered into the subworkflow
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3621
diff changeset
   307
    def get_exit_point(self, entity, stateeid):
2986
d8f2e53702be [wf] new methods to build wf w/ workflow transition
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2980
diff changeset
   308
        """if state is an exit point, return its associated destination state"""
3628
440931181322 [wf engine] support for subwf exit point with no destination state: go back to state from which we entered into the subworkflow
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3621
diff changeset
   309
        if hasattr(stateeid, 'eid'):
440931181322 [wf engine] support for subwf exit point with no destination state: go back to state from which we entered into the subworkflow
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3621
diff changeset
   310
            stateeid = stateeid.eid
440931181322 [wf engine] support for subwf exit point with no destination state: go back to state from which we entered into the subworkflow
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3621
diff changeset
   311
        try:
440931181322 [wf engine] support for subwf exit point with no destination state: go back to state from which we entered into the subworkflow
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3621
diff changeset
   312
            tostateeid = self.exit_points()[stateeid]
440931181322 [wf engine] support for subwf exit point with no destination state: go back to state from which we entered into the subworkflow
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3621
diff changeset
   313
        except KeyError:
440931181322 [wf engine] support for subwf exit point with no destination state: go back to state from which we entered into the subworkflow
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3621
diff changeset
   314
            return None
440931181322 [wf engine] support for subwf exit point with no destination state: go back to state from which we entered into the subworkflow
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3621
diff changeset
   315
        if tostateeid is None:
440931181322 [wf engine] support for subwf exit point with no destination state: go back to state from which we entered into the subworkflow
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3621
diff changeset
   316
            # go back to state from which we've entered the subworkflow
5556
9ab2b4c74baf [entity] introduce a new 'adapters' registry
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5426
diff changeset
   317
            return entity.cw_adapt_to('IWorkflowable').subworkflow_input_trinfo().previous_state
3629
559cad62c786 backport stable branch
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3589 3628
diff changeset
   318
        return self._cw.entity_from_eid(tostateeid)
2986
d8f2e53702be [wf] new methods to build wf w/ workflow transition
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2980
diff changeset
   319
d8f2e53702be [wf] new methods to build wf w/ workflow transition
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2980
diff changeset
   320
    @cached
d8f2e53702be [wf] new methods to build wf w/ workflow transition
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2980
diff changeset
   321
    def exit_points(self):
d8f2e53702be [wf] new methods to build wf w/ workflow transition
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2980
diff changeset
   322
        result = {}
d8f2e53702be [wf] new methods to build wf w/ workflow transition
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2980
diff changeset
   323
        for ep in self.subworkflow_exit:
3628
440931181322 [wf engine] support for subwf exit point with no destination state: go back to state from which we entered into the subworkflow
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3621
diff changeset
   324
            result[ep.subwf_state.eid] = ep.destination and ep.destination.eid
2986
d8f2e53702be [wf] new methods to build wf w/ workflow transition
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2980
diff changeset
   325
        return result
d8f2e53702be [wf] new methods to build wf w/ workflow transition
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2980
diff changeset
   326
7293
97505b798975 [entity 3.13 api] rename clear_all_caches into cw_clear_all_cache
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6904
diff changeset
   327
    def cw_clear_all_caches(self):
97505b798975 [entity 3.13 api] rename clear_all_caches into cw_clear_all_cache
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6904
diff changeset
   328
        super(WorkflowTransition, self).cw_clear_all_caches()
2986
d8f2e53702be [wf] new methods to build wf w/ workflow transition
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2980
diff changeset
   329
        clear_cache(self, 'exit_points')
d8f2e53702be [wf] new methods to build wf w/ workflow transition
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2980
diff changeset
   330
d8f2e53702be [wf] new methods to build wf w/ workflow transition
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2980
diff changeset
   331
d8f2e53702be [wf] new methods to build wf w/ workflow transition
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2980
diff changeset
   332
class SubWorkflowExitPoint(AnyEntity):
d8f2e53702be [wf] new methods to build wf w/ workflow transition
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2980
diff changeset
   333
    """customized class for SubWorkflowExitPoint entities"""
3377
dd9d292b6a6d use __regid__ instead of id on appobject classes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3038
diff changeset
   334
    __regid__ = 'SubWorkflowExitPoint'
2986
d8f2e53702be [wf] new methods to build wf w/ workflow transition
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2980
diff changeset
   335
d8f2e53702be [wf] new methods to build wf w/ workflow transition
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2980
diff changeset
   336
    @property
d8f2e53702be [wf] new methods to build wf w/ workflow transition
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2980
diff changeset
   337
    def subwf_state(self):
d8f2e53702be [wf] new methods to build wf w/ workflow transition
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2980
diff changeset
   338
        return self.subworkflow_state[0]
d8f2e53702be [wf] new methods to build wf w/ workflow transition
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2980
diff changeset
   339
d8f2e53702be [wf] new methods to build wf w/ workflow transition
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2980
diff changeset
   340
    @property
d8f2e53702be [wf] new methods to build wf w/ workflow transition
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2980
diff changeset
   341
    def destination(self):
3628
440931181322 [wf engine] support for subwf exit point with no destination state: go back to state from which we entered into the subworkflow
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3621
diff changeset
   342
        return self.destination_state and self.destination_state[0] or None
2986
d8f2e53702be [wf] new methods to build wf w/ workflow transition
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2980
diff changeset
   343
1572
469787f6ea2b delete-trailing-whitespaces
sylvain.thenault@logilab.fr
parents: 1154
diff changeset
   344
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   345
class State(AnyEntity):
2920
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2917
diff changeset
   346
    """customized class for State entities"""
3377
dd9d292b6a6d use __regid__ instead of id on appobject classes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3038
diff changeset
   347
    __regid__ = 'State'
7827
9bbf83f68bcc [entity] upgrade fetch_[unrelated_]order to benefit from changes introduced in 3.14 (closes #1942758)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7406
diff changeset
   348
    fetch_attrs, cw_fetch_order = fetch_config(['name'])
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   349
    rest_attr = 'eid'
1572
469787f6ea2b delete-trailing-whitespaces
sylvain.thenault@logilab.fr
parents: 1154
diff changeset
   350
8212
a045d3821990 [workflow view] Display a non-localized version of state/transition names (closes #1912537).
Damien Garaud <damien.garaud@logilab.fr>
parents: 7990
diff changeset
   351
    def dc_long_title(self):
a045d3821990 [workflow view] Display a non-localized version of state/transition names (closes #1912537).
Damien Garaud <damien.garaud@logilab.fr>
parents: 7990
diff changeset
   352
        return '%s (%s)' % (self.name, self._cw._(self.name))
a045d3821990 [workflow view] Display a non-localized version of state/transition names (closes #1912537).
Damien Garaud <damien.garaud@logilab.fr>
parents: 7990
diff changeset
   353
2975
fed52d317ba7 [wf] new .workflow property on states and transitions
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2954
diff changeset
   354
    @property
fed52d317ba7 [wf] new .workflow property on states and transitions
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2954
diff changeset
   355
    def workflow(self):
3038
1261c3df0e5a [multi-sources] in ms config we don't have state_of (and probably others, but that's the one used until now...)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2991
diff changeset
   356
        # take care, may be missing in multi-sources configuration
5556
9ab2b4c74baf [entity] introduce a new 'adapters' registry
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5426
diff changeset
   357
        return self.state_of and self.state_of[0] or None
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   358
1572
469787f6ea2b delete-trailing-whitespaces
sylvain.thenault@logilab.fr
parents: 1154
diff changeset
   359
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   360
class TrInfo(AnyEntity):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   361
    """customized class for Transition information entities
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   362
    """
3377
dd9d292b6a6d use __regid__ instead of id on appobject classes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3038
diff changeset
   363
    __regid__ = 'TrInfo'
7827
9bbf83f68bcc [entity] upgrade fetch_[unrelated_]order to benefit from changes introduced in 3.14 (closes #1942758)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7406
diff changeset
   364
    fetch_attrs, cw_fetch_order = fetch_config(['creation_date', 'comment'],
9bbf83f68bcc [entity] upgrade fetch_[unrelated_]order to benefit from changes introduced in 3.14 (closes #1942758)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7406
diff changeset
   365
                                               pclass=None) # don't want modification_date
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   366
    @property
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   367
    def for_entity(self):
2920
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2917
diff changeset
   368
        return self.wf_info_for[0]
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2917
diff changeset
   369
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   370
    @property
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   371
    def previous_state(self):
2920
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2917
diff changeset
   372
        return self.from_state[0]
1572
469787f6ea2b delete-trailing-whitespaces
sylvain.thenault@logilab.fr
parents: 1154
diff changeset
   373
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   374
    @property
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   375
    def new_state(self):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   376
        return self.to_state[0]
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   377
2920
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2917
diff changeset
   378
    @property
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2917
diff changeset
   379
    def transition(self):
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2917
diff changeset
   380
        return self.by_transition and self.by_transition[0] or None
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2917
diff changeset
   381
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2917
diff changeset
   382
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2917
diff changeset
   383
class WorkflowableMixIn(object):
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2917
diff changeset
   384
    """base mixin providing workflow helper methods for workflowable entities.
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2917
diff changeset
   385
    This mixin will be automatically set on class supporting the 'in_state'
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2917
diff changeset
   386
    relation (which implies supporting 'wf_info_for' as well)
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2917
diff changeset
   387
    """
5556
9ab2b4c74baf [entity] introduce a new 'adapters' registry
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5426
diff changeset
   388
9ab2b4c74baf [entity] introduce a new 'adapters' registry
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5426
diff changeset
   389
    @property
9ab2b4c74baf [entity] introduce a new 'adapters' registry
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5426
diff changeset
   390
    @deprecated("[3.9] use entity.cw_adapt_to('IWorkflowable').main_workflow")
9ab2b4c74baf [entity] introduce a new 'adapters' registry
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5426
diff changeset
   391
    def main_workflow(self):
9ab2b4c74baf [entity] introduce a new 'adapters' registry
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5426
diff changeset
   392
        return self.cw_adapt_to('IWorkflowable').main_workflow
9ab2b4c74baf [entity] introduce a new 'adapters' registry
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5426
diff changeset
   393
    @property
9ab2b4c74baf [entity] introduce a new 'adapters' registry
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5426
diff changeset
   394
    @deprecated("[3.9] use entity.cw_adapt_to('IWorkflowable').current_workflow")
9ab2b4c74baf [entity] introduce a new 'adapters' registry
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5426
diff changeset
   395
    def current_workflow(self):
9ab2b4c74baf [entity] introduce a new 'adapters' registry
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5426
diff changeset
   396
        return self.cw_adapt_to('IWorkflowable').current_workflow
9ab2b4c74baf [entity] introduce a new 'adapters' registry
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5426
diff changeset
   397
    @property
9ab2b4c74baf [entity] introduce a new 'adapters' registry
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5426
diff changeset
   398
    @deprecated("[3.9] use entity.cw_adapt_to('IWorkflowable').current_state")
9ab2b4c74baf [entity] introduce a new 'adapters' registry
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5426
diff changeset
   399
    def current_state(self):
9ab2b4c74baf [entity] introduce a new 'adapters' registry
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5426
diff changeset
   400
        return self.cw_adapt_to('IWorkflowable').current_state
9ab2b4c74baf [entity] introduce a new 'adapters' registry
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5426
diff changeset
   401
    @property
9ab2b4c74baf [entity] introduce a new 'adapters' registry
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5426
diff changeset
   402
    @deprecated("[3.9] use entity.cw_adapt_to('IWorkflowable').state")
9ab2b4c74baf [entity] introduce a new 'adapters' registry
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5426
diff changeset
   403
    def state(self):
9ab2b4c74baf [entity] introduce a new 'adapters' registry
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5426
diff changeset
   404
        return self.cw_adapt_to('IWorkflowable').state
9ab2b4c74baf [entity] introduce a new 'adapters' registry
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5426
diff changeset
   405
    @property
9ab2b4c74baf [entity] introduce a new 'adapters' registry
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5426
diff changeset
   406
    @deprecated("[3.9] use entity.cw_adapt_to('IWorkflowable').printable_state")
9ab2b4c74baf [entity] introduce a new 'adapters' registry
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5426
diff changeset
   407
    def printable_state(self):
9ab2b4c74baf [entity] introduce a new 'adapters' registry
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5426
diff changeset
   408
        return self.cw_adapt_to('IWorkflowable').printable_state
9ab2b4c74baf [entity] introduce a new 'adapters' registry
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5426
diff changeset
   409
    @property
9ab2b4c74baf [entity] introduce a new 'adapters' registry
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5426
diff changeset
   410
    @deprecated("[3.9] use entity.cw_adapt_to('IWorkflowable').workflow_history")
9ab2b4c74baf [entity] introduce a new 'adapters' registry
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5426
diff changeset
   411
    def workflow_history(self):
9ab2b4c74baf [entity] introduce a new 'adapters' registry
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5426
diff changeset
   412
        return self.cw_adapt_to('IWorkflowable').workflow_history
9ab2b4c74baf [entity] introduce a new 'adapters' registry
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5426
diff changeset
   413
9ab2b4c74baf [entity] introduce a new 'adapters' registry
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5426
diff changeset
   414
    @deprecated("[3.9] use entity.cw_adapt_to('IWorkflowable').cwetype_workflow()")
9ab2b4c74baf [entity] introduce a new 'adapters' registry
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5426
diff changeset
   415
    def cwetype_workflow(self):
9ab2b4c74baf [entity] introduce a new 'adapters' registry
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5426
diff changeset
   416
        return self.cw_adapt_to('IWorkflowable').main_workflow()
9ab2b4c74baf [entity] introduce a new 'adapters' registry
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5426
diff changeset
   417
    @deprecated("[3.9] use entity.cw_adapt_to('IWorkflowable').latest_trinfo()")
9ab2b4c74baf [entity] introduce a new 'adapters' registry
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5426
diff changeset
   418
    def latest_trinfo(self):
9ab2b4c74baf [entity] introduce a new 'adapters' registry
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5426
diff changeset
   419
        return self.cw_adapt_to('IWorkflowable').latest_trinfo()
9ab2b4c74baf [entity] introduce a new 'adapters' registry
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5426
diff changeset
   420
    @deprecated("[3.9] use entity.cw_adapt_to('IWorkflowable').possible_transitions()")
9ab2b4c74baf [entity] introduce a new 'adapters' registry
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5426
diff changeset
   421
    def possible_transitions(self, type='normal'):
9ab2b4c74baf [entity] introduce a new 'adapters' registry
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5426
diff changeset
   422
        return self.cw_adapt_to('IWorkflowable').possible_transitions(type)
9ab2b4c74baf [entity] introduce a new 'adapters' registry
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5426
diff changeset
   423
    @deprecated("[3.9] use entity.cw_adapt_to('IWorkflowable').fire_transition()")
9ab2b4c74baf [entity] introduce a new 'adapters' registry
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5426
diff changeset
   424
    def fire_transition(self, tr, comment=None, commentformat=None):
9ab2b4c74baf [entity] introduce a new 'adapters' registry
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5426
diff changeset
   425
        return self.cw_adapt_to('IWorkflowable').fire_transition(tr, comment, commentformat)
9ab2b4c74baf [entity] introduce a new 'adapters' registry
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5426
diff changeset
   426
    @deprecated("[3.9] use entity.cw_adapt_to('IWorkflowable').change_state()")
9ab2b4c74baf [entity] introduce a new 'adapters' registry
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5426
diff changeset
   427
    def change_state(self, statename, comment=None, commentformat=None, tr=None):
9ab2b4c74baf [entity] introduce a new 'adapters' registry
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5426
diff changeset
   428
        return self.cw_adapt_to('IWorkflowable').change_state(statename, comment, commentformat, tr)
9ab2b4c74baf [entity] introduce a new 'adapters' registry
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5426
diff changeset
   429
    @deprecated("[3.9] use entity.cw_adapt_to('IWorkflowable').subworkflow_input_trinfo()")
9ab2b4c74baf [entity] introduce a new 'adapters' registry
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5426
diff changeset
   430
    def subworkflow_input_trinfo(self):
9ab2b4c74baf [entity] introduce a new 'adapters' registry
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5426
diff changeset
   431
        return self.cw_adapt_to('IWorkflowable').subworkflow_input_trinfo()
9ab2b4c74baf [entity] introduce a new 'adapters' registry
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5426
diff changeset
   432
    @deprecated("[3.9] use entity.cw_adapt_to('IWorkflowable').subworkflow_input_transition()")
9ab2b4c74baf [entity] introduce a new 'adapters' registry
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5426
diff changeset
   433
    def subworkflow_input_transition(self):
9ab2b4c74baf [entity] introduce a new 'adapters' registry
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5426
diff changeset
   434
        return self.cw_adapt_to('IWorkflowable').subworkflow_input_transition()
9ab2b4c74baf [entity] introduce a new 'adapters' registry
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5426
diff changeset
   435
9ab2b4c74baf [entity] introduce a new 'adapters' registry
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5426
diff changeset
   436
9ab2b4c74baf [entity] introduce a new 'adapters' registry
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5426
diff changeset
   437
MI_REL_TRIGGERS[('in_state', 'subject')] = WorkflowableMixIn
9ab2b4c74baf [entity] introduce a new 'adapters' registry
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5426
diff changeset
   438
9ab2b4c74baf [entity] introduce a new 'adapters' registry
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5426
diff changeset
   439
9ab2b4c74baf [entity] introduce a new 'adapters' registry
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5426
diff changeset
   440
9ab2b4c74baf [entity] introduce a new 'adapters' registry
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5426
diff changeset
   441
class IWorkflowableAdapter(WorkflowableMixIn, EntityAdapter):
9ab2b4c74baf [entity] introduce a new 'adapters' registry
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5426
diff changeset
   442
    """base adapter providing workflow helper methods for workflowable entities.
9ab2b4c74baf [entity] introduce a new 'adapters' registry
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5426
diff changeset
   443
    """
9ab2b4c74baf [entity] introduce a new 'adapters' registry
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5426
diff changeset
   444
    __regid__ = 'IWorkflowable'
9ab2b4c74baf [entity] introduce a new 'adapters' registry
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5426
diff changeset
   445
    __select__ = relation_possible('in_state')
9ab2b4c74baf [entity] introduce a new 'adapters' registry
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5426
diff changeset
   446
9ab2b4c74baf [entity] introduce a new 'adapters' registry
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5426
diff changeset
   447
    @cached
9ab2b4c74baf [entity] introduce a new 'adapters' registry
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5426
diff changeset
   448
    def cwetype_workflow(self):
9ab2b4c74baf [entity] introduce a new 'adapters' registry
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5426
diff changeset
   449
        """return the default workflow for entities of this type"""
9ab2b4c74baf [entity] introduce a new 'adapters' registry
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5426
diff changeset
   450
        # XXX CWEType method
9ab2b4c74baf [entity] introduce a new 'adapters' registry
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5426
diff changeset
   451
        wfrset = self._cw.execute('Any WF WHERE ET default_workflow WF, '
9ab2b4c74baf [entity] introduce a new 'adapters' registry
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5426
diff changeset
   452
                                  'ET name %(et)s', {'et': self.entity.__regid__})
9ab2b4c74baf [entity] introduce a new 'adapters' registry
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5426
diff changeset
   453
        if wfrset:
9ab2b4c74baf [entity] introduce a new 'adapters' registry
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5426
diff changeset
   454
            return wfrset.get_entity(0, 0)
9ab2b4c74baf [entity] introduce a new 'adapters' registry
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5426
diff changeset
   455
        self.warning("can't find any workflow for %s", self.entity.__regid__)
9ab2b4c74baf [entity] introduce a new 'adapters' registry
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5426
diff changeset
   456
        return None
2920
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2917
diff changeset
   457
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2917
diff changeset
   458
    @property
2978
d8c5ad14ab8e [wf] distinguish main workflow / current workflow
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2976
diff changeset
   459
    def main_workflow(self):
2920
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2917
diff changeset
   460
        """return current workflow applied to this entity"""
5556
9ab2b4c74baf [entity] introduce a new 'adapters' registry
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5426
diff changeset
   461
        if self.entity.custom_workflow:
9ab2b4c74baf [entity] introduce a new 'adapters' registry
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5426
diff changeset
   462
            return self.entity.custom_workflow[0]
2946
957fd4b276e2 [wf] refactor current_workflow by extracting cwetype_workflow method
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2945
diff changeset
   463
        return self.cwetype_workflow()
2920
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2917
diff changeset
   464
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2917
diff changeset
   465
    @property
2978
d8c5ad14ab8e [wf] distinguish main workflow / current workflow
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2976
diff changeset
   466
    def current_workflow(self):
d8c5ad14ab8e [wf] distinguish main workflow / current workflow
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2976
diff changeset
   467
        """return current workflow applied to this entity"""
2991
dab951c08896 cleanup
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2990
diff changeset
   468
        return self.current_state and self.current_state.workflow or self.main_workflow
2978
d8c5ad14ab8e [wf] distinguish main workflow / current workflow
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2976
diff changeset
   469
d8c5ad14ab8e [wf] distinguish main workflow / current workflow
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2976
diff changeset
   470
    @property
2920
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2917
diff changeset
   471
    def current_state(self):
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2917
diff changeset
   472
        """return current state entity"""
5556
9ab2b4c74baf [entity] introduce a new 'adapters' registry
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5426
diff changeset
   473
        return self.entity.in_state and self.entity.in_state[0] or None
2920
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2917
diff changeset
   474
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2917
diff changeset
   475
    @property
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2917
diff changeset
   476
    def state(self):
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2917
diff changeset
   477
        """return current state name"""
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2917
diff changeset
   478
        try:
5556
9ab2b4c74baf [entity] introduce a new 'adapters' registry
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5426
diff changeset
   479
            return self.current_state.name
9ab2b4c74baf [entity] introduce a new 'adapters' registry
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5426
diff changeset
   480
        except AttributeError:
6904
cf869016a823 [workflow] fix warning: we want to see the adapted entity, not the adapter
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5557
diff changeset
   481
            self.warning('entity %s has no state', self.entity)
2920
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2917
diff changeset
   482
            return None
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2917
diff changeset
   483
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2917
diff changeset
   484
    @property
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2917
diff changeset
   485
    def printable_state(self):
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2917
diff changeset
   486
        """return current state name translated to context's language"""
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2917
diff changeset
   487
        state = self.current_state
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2917
diff changeset
   488
        if state:
3406
e343f37f7013 use self._cw instead of self.req
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3405
diff changeset
   489
            return self._cw._(state.name)
2920
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2917
diff changeset
   490
        return u''
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2917
diff changeset
   491
2947
083593802120 [wf] new workflow_history property, nicer the reverse_wf_info_for...
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2946
diff changeset
   492
    @property
083593802120 [wf] new workflow_history property, nicer the reverse_wf_info_for...
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2946
diff changeset
   493
    def workflow_history(self):
083593802120 [wf] new workflow_history property, nicer the reverse_wf_info_for...
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2946
diff changeset
   494
        """return the workflow history for this entity (eg ordered list of
083593802120 [wf] new workflow_history property, nicer the reverse_wf_info_for...
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2946
diff changeset
   495
        TrInfo entities)
083593802120 [wf] new workflow_history property, nicer the reverse_wf_info_for...
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2946
diff changeset
   496
        """
5556
9ab2b4c74baf [entity] introduce a new 'adapters' registry
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5426
diff changeset
   497
        return self.entity.reverse_wf_info_for
2947
083593802120 [wf] new workflow_history property, nicer the reverse_wf_info_for...
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2946
diff changeset
   498
2920
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2917
diff changeset
   499
    def latest_trinfo(self):
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2917
diff changeset
   500
        """return the latest transition information for this entity"""
3765
769dc0107f31 latst_trinfo : do not crash on absent wf history
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 3757
diff changeset
   501
        try:
5556
9ab2b4c74baf [entity] introduce a new 'adapters' registry
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5426
diff changeset
   502
            return self.workflow_history[-1]
3765
769dc0107f31 latst_trinfo : do not crash on absent wf history
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 3757
diff changeset
   503
        except IndexError:
769dc0107f31 latst_trinfo : do not crash on absent wf history
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 3757
diff changeset
   504
            return None
2920
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2917
diff changeset
   505
3528
77a69de16709 support for automatic transition
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3038
diff changeset
   506
    def possible_transitions(self, type='normal'):
2920
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2917
diff changeset
   507
        """generates transition that MAY be fired for the given entity,
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2917
diff changeset
   508
        expected to be in this state
3986
cc29eddf51ad add postcommit_event on Operations
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 3982
diff changeset
   509
        used only by the UI
2920
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2917
diff changeset
   510
        """
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2917
diff changeset
   511
        if self.current_state is None or self.current_workflow is None:
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2917
diff changeset
   512
            return
3406
e343f37f7013 use self._cw instead of self.req
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3405
diff changeset
   513
        rset = self._cw.execute(
3528
77a69de16709 support for automatic transition
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3038
diff changeset
   514
            'Any T,TT, TN WHERE S allowed_transition T, S eid %(x)s, '
77a69de16709 support for automatic transition
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3038
diff changeset
   515
            'T type TT, T type %(type)s, '
77a69de16709 support for automatic transition
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3038
diff changeset
   516
            'T name TN, T transition_of WF, WF eid %(wfeid)s',
77a69de16709 support for automatic transition
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3038
diff changeset
   517
            {'x': self.current_state.eid, 'type': type,
5174
78438ad513ca #759035: Automate addition of eid cachekey in RQL analysis
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4835
diff changeset
   518
             'wfeid': self.current_workflow.eid})
2920
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2917
diff changeset
   519
        for tr in rset.entities():
5556
9ab2b4c74baf [entity] introduce a new 'adapters' registry
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5426
diff changeset
   520
            if tr.may_be_fired(self.entity.eid):
2920
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2917
diff changeset
   521
                yield tr
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2917
diff changeset
   522
5556
9ab2b4c74baf [entity] introduce a new 'adapters' registry
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5426
diff changeset
   523
    def subworkflow_input_trinfo(self):
9ab2b4c74baf [entity] introduce a new 'adapters' registry
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5426
diff changeset
   524
        """return the TrInfo which has be recorded when this entity went into
9ab2b4c74baf [entity] introduce a new 'adapters' registry
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5426
diff changeset
   525
        the current sub-workflow
9ab2b4c74baf [entity] introduce a new 'adapters' registry
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5426
diff changeset
   526
        """
9ab2b4c74baf [entity] introduce a new 'adapters' registry
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5426
diff changeset
   527
        if self.main_workflow.eid == self.current_workflow.eid:
9ab2b4c74baf [entity] introduce a new 'adapters' registry
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5426
diff changeset
   528
            return # doesn't make sense
9ab2b4c74baf [entity] introduce a new 'adapters' registry
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5426
diff changeset
   529
        subwfentries = []
9ab2b4c74baf [entity] introduce a new 'adapters' registry
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5426
diff changeset
   530
        for trinfo in self.workflow_history:
9ab2b4c74baf [entity] introduce a new 'adapters' registry
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5426
diff changeset
   531
            if (trinfo.transition and
9ab2b4c74baf [entity] introduce a new 'adapters' registry
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5426
diff changeset
   532
                trinfo.previous_state.workflow.eid != trinfo.new_state.workflow.eid):
9ab2b4c74baf [entity] introduce a new 'adapters' registry
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5426
diff changeset
   533
                # entering or leaving a subworkflow
9ab2b4c74baf [entity] introduce a new 'adapters' registry
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5426
diff changeset
   534
                if (subwfentries and
9ab2b4c74baf [entity] introduce a new 'adapters' registry
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5426
diff changeset
   535
                    subwfentries[-1].new_state.workflow.eid == trinfo.previous_state.workflow.eid and
9ab2b4c74baf [entity] introduce a new 'adapters' registry
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5426
diff changeset
   536
                    subwfentries[-1].previous_state.workflow.eid == trinfo.new_state.workflow.eid):
9ab2b4c74baf [entity] introduce a new 'adapters' registry
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5426
diff changeset
   537
                    # leave
9ab2b4c74baf [entity] introduce a new 'adapters' registry
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5426
diff changeset
   538
                    del subwfentries[-1]
9ab2b4c74baf [entity] introduce a new 'adapters' registry
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5426
diff changeset
   539
                else:
9ab2b4c74baf [entity] introduce a new 'adapters' registry
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5426
diff changeset
   540
                    # enter
9ab2b4c74baf [entity] introduce a new 'adapters' registry
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5426
diff changeset
   541
                    subwfentries.append(trinfo)
9ab2b4c74baf [entity] introduce a new 'adapters' registry
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5426
diff changeset
   542
        if not subwfentries:
9ab2b4c74baf [entity] introduce a new 'adapters' registry
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5426
diff changeset
   543
            return None
9ab2b4c74baf [entity] introduce a new 'adapters' registry
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5426
diff changeset
   544
        return subwfentries[-1]
9ab2b4c74baf [entity] introduce a new 'adapters' registry
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5426
diff changeset
   545
9ab2b4c74baf [entity] introduce a new 'adapters' registry
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5426
diff changeset
   546
    def subworkflow_input_transition(self):
9ab2b4c74baf [entity] introduce a new 'adapters' registry
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5426
diff changeset
   547
        """return the transition which has went through the current sub-workflow
9ab2b4c74baf [entity] introduce a new 'adapters' registry
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5426
diff changeset
   548
        """
9ab2b4c74baf [entity] introduce a new 'adapters' registry
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5426
diff changeset
   549
        return getattr(self.subworkflow_input_trinfo(), 'transition', None)
9ab2b4c74baf [entity] introduce a new 'adapters' registry
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5426
diff changeset
   550
2989
dfb3506647e4 [wf] refactor change_state/fire_transition to share more code, change_state can also take an optional tr argument
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2988
diff changeset
   551
    def _add_trinfo(self, comment, commentformat, treid=None, tseid=None):
2920
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2917
diff changeset
   552
        kwargs = {}
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2917
diff changeset
   553
        if comment is not None:
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2917
diff changeset
   554
            kwargs['comment'] = comment
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2917
diff changeset
   555
            if commentformat is not None:
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2917
diff changeset
   556
                kwargs['comment_format'] = commentformat
5556
9ab2b4c74baf [entity] introduce a new 'adapters' registry
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5426
diff changeset
   557
        kwargs['wf_info_for'] = self.entity
2989
dfb3506647e4 [wf] refactor change_state/fire_transition to share more code, change_state can also take an optional tr argument
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2988
diff changeset
   558
        if treid is not None:
4024
6a14cff373c3 more api update
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4023
diff changeset
   559
            kwargs['by_transition'] = self._cw.entity_from_eid(treid)
2989
dfb3506647e4 [wf] refactor change_state/fire_transition to share more code, change_state can also take an optional tr argument
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2988
diff changeset
   560
        if tseid is not None:
4024
6a14cff373c3 more api update
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4023
diff changeset
   561
            kwargs['to_state'] = self._cw.entity_from_eid(tseid)
3720
5376aaadd16b backport stable
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3675 3698
diff changeset
   562
        return self._cw.create_entity('TrInfo', **kwargs)
2920
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2917
diff changeset
   563
7404
02a786d7ebce [workflow] new 'fire_transition_if_possible' method on IWorkflowable to fire a transition if it's possible
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7401
diff changeset
   564
    def _get_transition(self, tr):
2920
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2917
diff changeset
   565
        assert self.current_workflow
3528
77a69de16709 support for automatic transition
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3038
diff changeset
   566
        if isinstance(tr, basestring):
3628
440931181322 [wf engine] support for subwf exit point with no destination state: go back to state from which we entered into the subworkflow
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3621
diff changeset
   567
            _tr = self.current_workflow.transition_by_name(tr)
3629
559cad62c786 backport stable branch
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3589 3628
diff changeset
   568
            assert _tr is not None, 'not a %s transition: %s' % (
559cad62c786 backport stable branch
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3589 3628
diff changeset
   569
                self.__regid__, tr)
3628
440931181322 [wf engine] support for subwf exit point with no destination state: go back to state from which we entered into the subworkflow
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3621
diff changeset
   570
            tr = _tr
7404
02a786d7ebce [workflow] new 'fire_transition_if_possible' method on IWorkflowable to fire a transition if it's possible
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7401
diff changeset
   571
        return tr
02a786d7ebce [workflow] new 'fire_transition_if_possible' method on IWorkflowable to fire a transition if it's possible
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7401
diff changeset
   572
02a786d7ebce [workflow] new 'fire_transition_if_possible' method on IWorkflowable to fire a transition if it's possible
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7401
diff changeset
   573
    def fire_transition(self, tr, comment=None, commentformat=None):
02a786d7ebce [workflow] new 'fire_transition_if_possible' method on IWorkflowable to fire a transition if it's possible
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7401
diff changeset
   574
        """change the entity's state by firing given transition (name or entity)
02a786d7ebce [workflow] new 'fire_transition_if_possible' method on IWorkflowable to fire a transition if it's possible
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7401
diff changeset
   575
        in entity's workflow
02a786d7ebce [workflow] new 'fire_transition_if_possible' method on IWorkflowable to fire a transition if it's possible
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7401
diff changeset
   576
        """
02a786d7ebce [workflow] new 'fire_transition_if_possible' method on IWorkflowable to fire a transition if it's possible
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7401
diff changeset
   577
        tr = self._get_transition(tr)
2989
dfb3506647e4 [wf] refactor change_state/fire_transition to share more code, change_state can also take an optional tr argument
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2988
diff changeset
   578
        return self._add_trinfo(comment, commentformat, tr.eid)
2920
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2917
diff changeset
   579
7404
02a786d7ebce [workflow] new 'fire_transition_if_possible' method on IWorkflowable to fire a transition if it's possible
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7401
diff changeset
   580
    def fire_transition_if_possible(self, tr, comment=None, commentformat=None):
02a786d7ebce [workflow] new 'fire_transition_if_possible' method on IWorkflowable to fire a transition if it's possible
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7401
diff changeset
   581
        """change the entity's state by firing given transition (name or entity)
02a786d7ebce [workflow] new 'fire_transition_if_possible' method on IWorkflowable to fire a transition if it's possible
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7401
diff changeset
   582
        in entity's workflow if this transition is possible
02a786d7ebce [workflow] new 'fire_transition_if_possible' method on IWorkflowable to fire a transition if it's possible
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7401
diff changeset
   583
        """
02a786d7ebce [workflow] new 'fire_transition_if_possible' method on IWorkflowable to fire a transition if it's possible
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7401
diff changeset
   584
        tr = self._get_transition(tr)
02a786d7ebce [workflow] new 'fire_transition_if_possible' method on IWorkflowable to fire a transition if it's possible
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7401
diff changeset
   585
        if any(tr_ for tr_ in self.possible_transitions()
02a786d7ebce [workflow] new 'fire_transition_if_possible' method on IWorkflowable to fire a transition if it's possible
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7401
diff changeset
   586
               if tr_.eid == tr.eid):
02a786d7ebce [workflow] new 'fire_transition_if_possible' method on IWorkflowable to fire a transition if it's possible
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7401
diff changeset
   587
            self.fire_transition(tr)
02a786d7ebce [workflow] new 'fire_transition_if_possible' method on IWorkflowable to fire a transition if it's possible
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7401
diff changeset
   588
2989
dfb3506647e4 [wf] refactor change_state/fire_transition to share more code, change_state can also take an optional tr argument
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2988
diff changeset
   589
    def change_state(self, statename, comment=None, commentformat=None, tr=None):
2980
292387ed37f3 [wf] allow state entity as argument to change_state
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2978
diff changeset
   590
        """change the entity's state to the given state (name or entity) in
292387ed37f3 [wf] allow state entity as argument to change_state
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2978
diff changeset
   591
        entity's workflow. This method should only by used by manager to fix an
292387ed37f3 [wf] allow state entity as argument to change_state
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2978
diff changeset
   592
        entity's state when their is no matching transition, otherwise
292387ed37f3 [wf] allow state entity as argument to change_state
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2978
diff changeset
   593
        fire_transition should be used.
2920
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2917
diff changeset
   594
        """
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2917
diff changeset
   595
        assert self.current_workflow
2980
292387ed37f3 [wf] allow state entity as argument to change_state
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2978
diff changeset
   596
        if hasattr(statename, 'eid'):
292387ed37f3 [wf] allow state entity as argument to change_state
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2978
diff changeset
   597
            stateeid = statename.eid
2920
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2917
diff changeset
   598
        else:
7990
a673d1d9a738 [diet] drop pre 3.6 API compatibility (but attempt to keep data cmopatibility). Closes #2017916
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7894
diff changeset
   599
            state = self.current_workflow.state_by_name(statename)
2980
292387ed37f3 [wf] allow state entity as argument to change_state
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2978
diff changeset
   600
            if state is None:
3451
6b46d73823f5 [api] work in progress, use __regid__, cw_*, etc.
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 3406
diff changeset
   601
                raise WorkflowException('not a %s state: %s' % (self.__regid__,
2989
dfb3506647e4 [wf] refactor change_state/fire_transition to share more code, change_state can also take an optional tr argument
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2988
diff changeset
   602
                                                                statename))
2980
292387ed37f3 [wf] allow state entity as argument to change_state
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2978
diff changeset
   603
            stateeid = state.eid
2920
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2917
diff changeset
   604
        # XXX try to find matching transition?
2989
dfb3506647e4 [wf] refactor change_state/fire_transition to share more code, change_state can also take an optional tr argument
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2988
diff changeset
   605
        return self._add_trinfo(comment, commentformat, tr and tr.eid, stateeid)
7401
fded980bbd65 [workflow] add method on IWorkflowable to set initial state of an entity (closes #1686357)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6904
diff changeset
   606
fded980bbd65 [workflow] add method on IWorkflowable to set initial state of an entity (closes #1686357)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6904
diff changeset
   607
    def set_initial_state(self, statename):
fded980bbd65 [workflow] add method on IWorkflowable to set initial state of an entity (closes #1686357)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6904
diff changeset
   608
        """set a newly created entity's state to the given state (name or entity)
fded980bbd65 [workflow] add method on IWorkflowable to set initial state of an entity (closes #1686357)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6904
diff changeset
   609
        in entity's workflow. This is useful if you don't want it to be the
fded980bbd65 [workflow] add method on IWorkflowable to set initial state of an entity (closes #1686357)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6904
diff changeset
   610
        workflow's initial state.
fded980bbd65 [workflow] add method on IWorkflowable to set initial state of an entity (closes #1686357)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6904
diff changeset
   611
        """
fded980bbd65 [workflow] add method on IWorkflowable to set initial state of an entity (closes #1686357)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6904
diff changeset
   612
        assert self.current_workflow
fded980bbd65 [workflow] add method on IWorkflowable to set initial state of an entity (closes #1686357)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6904
diff changeset
   613
        if hasattr(statename, 'eid'):
fded980bbd65 [workflow] add method on IWorkflowable to set initial state of an entity (closes #1686357)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6904
diff changeset
   614
            stateeid = statename.eid
fded980bbd65 [workflow] add method on IWorkflowable to set initial state of an entity (closes #1686357)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6904
diff changeset
   615
        else:
fded980bbd65 [workflow] add method on IWorkflowable to set initial state of an entity (closes #1686357)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6904
diff changeset
   616
            state = self.current_workflow.state_by_name(statename)
fded980bbd65 [workflow] add method on IWorkflowable to set initial state of an entity (closes #1686357)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6904
diff changeset
   617
            if state is None:
fded980bbd65 [workflow] add method on IWorkflowable to set initial state of an entity (closes #1686357)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6904
diff changeset
   618
                raise WorkflowException('not a %s state: %s' % (self.__regid__,
fded980bbd65 [workflow] add method on IWorkflowable to set initial state of an entity (closes #1686357)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6904
diff changeset
   619
                                                                statename))
fded980bbd65 [workflow] add method on IWorkflowable to set initial state of an entity (closes #1686357)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6904
diff changeset
   620
            stateeid = state.eid
fded980bbd65 [workflow] add method on IWorkflowable to set initial state of an entity (closes #1686357)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6904
diff changeset
   621
        self._cw.execute('SET X in_state S WHERE X eid %(x)s, S eid %(s)s',
fded980bbd65 [workflow] add method on IWorkflowable to set initial state of an entity (closes #1686357)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6904
diff changeset
   622
                         {'x': self.entity.eid, 's': stateeid})