hooks/workflow.py
author Sylvain Thénault <sylvain.thenault@logilab.fr>
Tue, 21 Jun 2011 10:57:25 +0200
changeset 7543 570522300e22
parent 7294 2af1a4cecda5
child 7879 9aae456abab5
permissions -rw-r--r--
[ms, entity metas] add 'actual source' to entities table / base entity metadata cache. Closes #1767090 this is needed since for entities from 'copy based sources' such as datafeed, we want entity.cw_metainformation() to return as 'source' the datafeed source, not the system source (ie the source where the entity is actually stored). For both performance and bootstraping reasons, we should store this information in the `entities` table and in the _type_source cache.
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
5421
8167de96c523 proper licensing information (LGPL-2.1). Hope I get it right this time.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5164
diff changeset
     1
# copyright 2003-2010 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
8167de96c523 proper licensing information (LGPL-2.1). Hope I get it right this time.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5164
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: 5164
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: 5164
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: 5164
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: 5164
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: 5164
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: 5164
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: 5164
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: 5164
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: 5164
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: 5164
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: 5164
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: 5164
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: 5164
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: 5164
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: 5424
diff changeset
    18
"""Core hooks: workflow related hooks"""
2835
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    19
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    20
__docformat__ = "restructuredtext en"
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    21
2841
107ba1c45227 rewrite hooks in sobjects as new Hook style into hooks sub-package
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2835
diff changeset
    22
from datetime import datetime
107ba1c45227 rewrite hooks in sobjects as new Hook style into hooks sub-package
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2835
diff changeset
    23
5030
5238d9a8dfee [form] put qualified name on validation error, should fix #784299
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4835
diff changeset
    24
from yams.schema import role_name
5238d9a8dfee [form] put qualified name on validation error, should fix #784299
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4835
diff changeset
    25
2841
107ba1c45227 rewrite hooks in sobjects as new Hook style into hooks sub-package
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2835
diff changeset
    26
from cubicweb import RepositoryError, ValidationError
5877
0c7b7b76a84f [selectors] provide a new, optimized, is_instance selector that should at some point replace implements (along with the adaptable selector)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5685
diff changeset
    27
from cubicweb.selectors import is_instance, adaptable
2841
107ba1c45227 rewrite hooks in sobjects as new Hook style into hooks sub-package
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2835
diff changeset
    28
from cubicweb.server import hook
107ba1c45227 rewrite hooks in sobjects as new Hook style into hooks sub-package
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2835
diff changeset
    29
107ba1c45227 rewrite hooks in sobjects as new Hook style into hooks sub-package
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2835
diff changeset
    30
2968
0e3460341023 somewhat painful backport of 3.5 branch, should mostly be ok
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2880
diff changeset
    31
def _change_state(session, x, oldstate, newstate):
0e3460341023 somewhat painful backport of 3.5 branch, should mostly be ok
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2880
diff changeset
    32
    nocheck = session.transaction_data.setdefault('skip-security', set())
0e3460341023 somewhat painful backport of 3.5 branch, should mostly be ok
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2880
diff changeset
    33
    nocheck.add((x, 'in_state', oldstate))
0e3460341023 somewhat painful backport of 3.5 branch, should mostly be ok
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2880
diff changeset
    34
    nocheck.add((x, 'in_state', newstate))
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: 4719
diff changeset
    35
    # delete previous state first unless in_state isn't stored in the system
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: 4719
diff changeset
    36
    # source
3072
6fb42c53f6df backport 3.5 branch
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3024
diff changeset
    37
    fromsource = session.describe(x)[1]
6fb42c53f6df backport 3.5 branch
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3024
diff changeset
    38
    if fromsource == 'system' or \
6fb42c53f6df backport 3.5 branch
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3024
diff changeset
    39
           not session.repo.sources_by_uri[fromsource].support_relation('in_state'):
6fb42c53f6df backport 3.5 branch
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3024
diff changeset
    40
        session.delete_relation(x, 'in_state', oldstate)
2968
0e3460341023 somewhat painful backport of 3.5 branch, should mostly be ok
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2880
diff changeset
    41
    session.add_relation(x, 'in_state', newstate)
2835
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    42
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    43
3024
bfaf056f1029 backport 3.5 step 2, backport wf changes in hooks/workflow.py
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2968
diff changeset
    44
# operations ###################################################################
bfaf056f1029 backport 3.5 step 2, backport wf changes in hooks/workflow.py
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2968
diff changeset
    45
2841
107ba1c45227 rewrite hooks in sobjects as new Hook style into hooks sub-package
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2835
diff changeset
    46
class _SetInitialStateOp(hook.Operation):
2835
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    47
    """make initial state be a default state"""
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    48
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    49
    def precommit_event(self):
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    50
        session = self.session
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    51
        entity = self.entity
5556
9ab2b4c74baf [entity] introduce a new 'adapters' registry
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5424
diff changeset
    52
        iworkflowable = entity.cw_adapt_to('IWorkflowable')
2835
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    53
        # if there is an initial state and the entity's state is not set,
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    54
        # use the initial state as a default state
2968
0e3460341023 somewhat painful backport of 3.5 branch, should mostly be ok
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2880
diff changeset
    55
        if not (session.deleted_in_transaction(entity.eid) or entity.in_state) \
5556
9ab2b4c74baf [entity] introduce a new 'adapters' registry
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5424
diff changeset
    56
               and iworkflowable.current_workflow:
9ab2b4c74baf [entity] introduce a new 'adapters' registry
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5424
diff changeset
    57
            state = iworkflowable.current_workflow.initial
2968
0e3460341023 somewhat painful backport of 3.5 branch, should mostly be ok
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2880
diff changeset
    58
            if state:
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: 4719
diff changeset
    59
                session.add_relation(entity.eid, 'in_state', state.eid)
5056
5de07c77d73f [workflow] support for automatic transition starting from the initial state
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5030
diff changeset
    60
                _FireAutotransitionOp(session, entity=entity)
3536
f6c9a5df80fb backport stable branch
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3449
diff changeset
    61
3589
a5432f99f2d9 backport stable branch
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3536
diff changeset
    62
class _FireAutotransitionOp(hook.Operation):
3536
f6c9a5df80fb backport stable branch
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3449
diff changeset
    63
    """try to fire auto transition after state changes"""
f6c9a5df80fb backport stable branch
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3449
diff changeset
    64
f6c9a5df80fb backport stable branch
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3449
diff changeset
    65
    def precommit_event(self):
f6c9a5df80fb backport stable branch
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3449
diff changeset
    66
        entity = self.entity
5556
9ab2b4c74baf [entity] introduce a new 'adapters' registry
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5424
diff changeset
    67
        iworkflowable = entity.cw_adapt_to('IWorkflowable')
9ab2b4c74baf [entity] introduce a new 'adapters' registry
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5424
diff changeset
    68
        autotrs = list(iworkflowable.possible_transitions('auto'))
3536
f6c9a5df80fb backport stable branch
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3449
diff changeset
    69
        if autotrs:
f6c9a5df80fb backport stable branch
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3449
diff changeset
    70
            assert len(autotrs) == 1
5556
9ab2b4c74baf [entity] introduce a new 'adapters' registry
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5424
diff changeset
    71
            iworkflowable.fire_transition(autotrs[0])
3536
f6c9a5df80fb backport stable branch
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3449
diff changeset
    72
f6c9a5df80fb backport stable branch
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3449
diff changeset
    73
2968
0e3460341023 somewhat painful backport of 3.5 branch, should mostly be ok
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2880
diff changeset
    74
class _WorkflowChangedOp(hook.Operation):
0e3460341023 somewhat painful backport of 3.5 branch, should mostly be ok
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2880
diff changeset
    75
    """fix entity current state when changing its workflow"""
0e3460341023 somewhat painful backport of 3.5 branch, should mostly be ok
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2880
diff changeset
    76
0e3460341023 somewhat painful backport of 3.5 branch, should mostly be ok
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2880
diff changeset
    77
    def precommit_event(self):
3024
bfaf056f1029 backport 3.5 step 2, backport wf changes in hooks/workflow.py
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2968
diff changeset
    78
        # notice that enforcement that new workflow apply to the entity's type is
bfaf056f1029 backport 3.5 step 2, backport wf changes in hooks/workflow.py
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2968
diff changeset
    79
        # done by schema rule, no need to check it here
2968
0e3460341023 somewhat painful backport of 3.5 branch, should mostly be ok
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2880
diff changeset
    80
        session = self.session
3024
bfaf056f1029 backport 3.5 step 2, backport wf changes in hooks/workflow.py
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2968
diff changeset
    81
        pendingeids = session.transaction_data.get('pendingeids', ())
bfaf056f1029 backport 3.5 step 2, backport wf changes in hooks/workflow.py
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2968
diff changeset
    82
        if self.eid in pendingeids:
2968
0e3460341023 somewhat painful backport of 3.5 branch, should mostly be ok
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2880
diff changeset
    83
            return
0e3460341023 somewhat painful backport of 3.5 branch, should mostly be ok
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2880
diff changeset
    84
        entity = session.entity_from_eid(self.eid)
5556
9ab2b4c74baf [entity] introduce a new 'adapters' registry
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5424
diff changeset
    85
        iworkflowable = entity.cw_adapt_to('IWorkflowable')
3024
bfaf056f1029 backport 3.5 step 2, backport wf changes in hooks/workflow.py
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2968
diff changeset
    86
        # check custom workflow has not been rechanged to another one in the same
bfaf056f1029 backport 3.5 step 2, backport wf changes in hooks/workflow.py
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2968
diff changeset
    87
        # transaction
5556
9ab2b4c74baf [entity] introduce a new 'adapters' registry
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5424
diff changeset
    88
        mainwf = iworkflowable.main_workflow
3024
bfaf056f1029 backport 3.5 step 2, backport wf changes in hooks/workflow.py
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2968
diff changeset
    89
        if mainwf.eid == self.wfeid:
bfaf056f1029 backport 3.5 step 2, backport wf changes in hooks/workflow.py
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2968
diff changeset
    90
            deststate = mainwf.initial
2968
0e3460341023 somewhat painful backport of 3.5 branch, should mostly be ok
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2880
diff changeset
    91
            if not deststate:
5030
5238d9a8dfee [form] put qualified name on validation error, should fix #784299
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4835
diff changeset
    92
                qname = role_name('custom_workflow', 'subject')
2968
0e3460341023 somewhat painful backport of 3.5 branch, should mostly be ok
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2880
diff changeset
    93
                msg = session._('workflow has no initial state')
5030
5238d9a8dfee [form] put qualified name on validation error, should fix #784299
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4835
diff changeset
    94
                raise ValidationError(entity.eid, {qname: msg})
5556
9ab2b4c74baf [entity] introduce a new 'adapters' registry
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5424
diff changeset
    95
            if mainwf.state_by_eid(iworkflowable.current_state.eid):
2968
0e3460341023 somewhat painful backport of 3.5 branch, should mostly be ok
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2880
diff changeset
    96
                # nothing to do
0e3460341023 somewhat painful backport of 3.5 branch, should mostly be ok
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2880
diff changeset
    97
                return
0e3460341023 somewhat painful backport of 3.5 branch, should mostly be ok
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2880
diff changeset
    98
            # if there are no history, simply go to new workflow's initial state
5556
9ab2b4c74baf [entity] introduce a new 'adapters' registry
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5424
diff changeset
    99
            if not iworkflowable.workflow_history:
9ab2b4c74baf [entity] introduce a new 'adapters' registry
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5424
diff changeset
   100
                if iworkflowable.current_state.eid != deststate.eid:
2968
0e3460341023 somewhat painful backport of 3.5 branch, should mostly be ok
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2880
diff changeset
   101
                    _change_state(session, entity.eid,
5556
9ab2b4c74baf [entity] introduce a new 'adapters' registry
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5424
diff changeset
   102
                                  iworkflowable.current_state.eid, deststate.eid)
5056
5de07c77d73f [workflow] support for automatic transition starting from the initial state
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5030
diff changeset
   103
                    _FireAutotransitionOp(session, entity=entity)
2968
0e3460341023 somewhat painful backport of 3.5 branch, should mostly be ok
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2880
diff changeset
   104
                return
0e3460341023 somewhat painful backport of 3.5 branch, should mostly be ok
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2880
diff changeset
   105
            msg = session._('workflow changed to "%s"')
3024
bfaf056f1029 backport 3.5 step 2, backport wf changes in hooks/workflow.py
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2968
diff changeset
   106
            msg %= session._(mainwf.name)
bfaf056f1029 backport 3.5 step 2, backport wf changes in hooks/workflow.py
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2968
diff changeset
   107
            session.transaction_data[(entity.eid, 'customwf')] = self.wfeid
5556
9ab2b4c74baf [entity] introduce a new 'adapters' registry
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5424
diff changeset
   108
            iworkflowable.change_state(deststate, msg, u'text/plain')
2968
0e3460341023 somewhat painful backport of 3.5 branch, should mostly be ok
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2880
diff changeset
   109
0e3460341023 somewhat painful backport of 3.5 branch, should mostly be ok
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2880
diff changeset
   110
3024
bfaf056f1029 backport 3.5 step 2, backport wf changes in hooks/workflow.py
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2968
diff changeset
   111
class _CheckTrExitPoint(hook.Operation):
bfaf056f1029 backport 3.5 step 2, backport wf changes in hooks/workflow.py
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2968
diff changeset
   112
bfaf056f1029 backport 3.5 step 2, backport wf changes in hooks/workflow.py
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2968
diff changeset
   113
    def precommit_event(self):
bfaf056f1029 backport 3.5 step 2, backport wf changes in hooks/workflow.py
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2968
diff changeset
   114
        tr = self.session.entity_from_eid(self.treid)
bfaf056f1029 backport 3.5 step 2, backport wf changes in hooks/workflow.py
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2968
diff changeset
   115
        outputs = set()
bfaf056f1029 backport 3.5 step 2, backport wf changes in hooks/workflow.py
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2968
diff changeset
   116
        for ep in tr.subworkflow_exit:
bfaf056f1029 backport 3.5 step 2, backport wf changes in hooks/workflow.py
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2968
diff changeset
   117
            if ep.subwf_state.eid in outputs:
5030
5238d9a8dfee [form] put qualified name on validation error, should fix #784299
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4835
diff changeset
   118
                qname = role_name('subworkflow_exit', 'subject')
3024
bfaf056f1029 backport 3.5 step 2, backport wf changes in hooks/workflow.py
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2968
diff changeset
   119
                msg = self.session._("can't have multiple exits on the same state")
5030
5238d9a8dfee [form] put qualified name on validation error, should fix #784299
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4835
diff changeset
   120
                raise ValidationError(self.treid, {qname: msg})
3024
bfaf056f1029 backport 3.5 step 2, backport wf changes in hooks/workflow.py
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2968
diff changeset
   121
            outputs.add(ep.subwf_state.eid)
bfaf056f1029 backport 3.5 step 2, backport wf changes in hooks/workflow.py
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2968
diff changeset
   122
bfaf056f1029 backport 3.5 step 2, backport wf changes in hooks/workflow.py
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2968
diff changeset
   123
3675
5d143781a604 fix merge
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3674
diff changeset
   124
class _SubWorkflowExitOp(hook.Operation):
3674
387d51af966d backport stable branch
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3654
diff changeset
   125
387d51af966d backport stable branch
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3654
diff changeset
   126
    def precommit_event(self):
387d51af966d backport stable branch
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3654
diff changeset
   127
        session = self.session
387d51af966d backport stable branch
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3654
diff changeset
   128
        forentity = self.forentity
5556
9ab2b4c74baf [entity] introduce a new 'adapters' registry
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5424
diff changeset
   129
        iworkflowable = forentity.cw_adapt_to('IWorkflowable')
3674
387d51af966d backport stable branch
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3654
diff changeset
   130
        trinfo = self.trinfo
387d51af966d backport stable branch
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3654
diff changeset
   131
        # we're in a subworkflow, check if we've reached an exit point
5556
9ab2b4c74baf [entity] introduce a new 'adapters' registry
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5424
diff changeset
   132
        wftr = iworkflowable.subworkflow_input_transition()
3674
387d51af966d backport stable branch
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3654
diff changeset
   133
        if wftr is None:
387d51af966d backport stable branch
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3654
diff changeset
   134
            # inconsistency detected
5030
5238d9a8dfee [form] put qualified name on validation error, should fix #784299
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4835
diff changeset
   135
            qname = role_name('to_state', 'subject')
3674
387d51af966d backport stable branch
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3654
diff changeset
   136
            msg = session._("state doesn't belong to entity's current workflow")
387d51af966d backport stable branch
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3654
diff changeset
   137
            raise ValidationError(self.trinfo.eid, {'to_state': msg})
6142
8bc6eac1fac1 [session] cleanup hook / operation / entity edition api
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5877
diff changeset
   138
        tostate = wftr.get_exit_point(forentity, trinfo.cw_attr_cache['to_state'])
3674
387d51af966d backport stable branch
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3654
diff changeset
   139
        if tostate is not None:
387d51af966d backport stable branch
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3654
diff changeset
   140
            # reached an exit point
387d51af966d backport stable branch
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3654
diff changeset
   141
            msg = session._('exiting from subworkflow %s')
5556
9ab2b4c74baf [entity] introduce a new 'adapters' registry
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5424
diff changeset
   142
            msg %= session._(iworkflowable.current_workflow.name)
3674
387d51af966d backport stable branch
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3654
diff changeset
   143
            session.transaction_data[(forentity.eid, 'subwfentrytr')] = True
5556
9ab2b4c74baf [entity] introduce a new 'adapters' registry
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5424
diff changeset
   144
            iworkflowable.change_state(tostate, msg, u'text/plain', tr=wftr)
3674
387d51af966d backport stable branch
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3654
diff changeset
   145
387d51af966d backport stable branch
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3654
diff changeset
   146
3024
bfaf056f1029 backport 3.5 step 2, backport wf changes in hooks/workflow.py
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2968
diff changeset
   147
# hooks ########################################################################
2835
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   148
2841
107ba1c45227 rewrite hooks in sobjects as new Hook style into hooks sub-package
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2835
diff changeset
   149
class WorkflowHook(hook.Hook):
107ba1c45227 rewrite hooks in sobjects as new Hook style into hooks sub-package
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2835
diff changeset
   150
    __abstract__ = True
7294
2af1a4cecda5 [workflow hooks] reuse metadata/integrity categories instead of a new 'workflow' category and drop useless hook
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6757
diff changeset
   151
    category = 'metadata'
2835
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   152
2841
107ba1c45227 rewrite hooks in sobjects as new Hook style into hooks sub-package
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2835
diff changeset
   153
107ba1c45227 rewrite hooks in sobjects as new Hook style into hooks sub-package
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2835
diff changeset
   154
class SetInitialStateHook(WorkflowHook):
3376
f5c69485381f [appobjects] use __regid__ instead of __id__, more explicit
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3072
diff changeset
   155
    __regid__ = 'wfsetinitial'
5556
9ab2b4c74baf [entity] introduce a new 'adapters' registry
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5424
diff changeset
   156
    __select__ = WorkflowHook.__select__ & adaptable('IWorkflowable')
2835
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   157
    events = ('after_add_entity',)
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   158
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   159
    def __call__(self):
2847
c2ee28f4d4b1 use ._cw instead of .cw_req
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2841
diff changeset
   160
        _SetInitialStateOp(self._cw, entity=self.entity)
2835
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   161
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   162
7294
2af1a4cecda5 [workflow hooks] reuse metadata/integrity categories instead of a new 'workflow' category and drop useless hook
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6757
diff changeset
   163
class FireTransitionHook(WorkflowHook):
2af1a4cecda5 [workflow hooks] reuse metadata/integrity categories instead of a new 'workflow' category and drop useless hook
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6757
diff changeset
   164
    """check the transition is allowed and add missing information into the
2af1a4cecda5 [workflow hooks] reuse metadata/integrity categories instead of a new 'workflow' category and drop useless hook
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6757
diff changeset
   165
    TrInfo entity.
2835
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   166
7294
2af1a4cecda5 [workflow hooks] reuse metadata/integrity categories instead of a new 'workflow' category and drop useless hook
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6757
diff changeset
   167
    Expect that:
2968
0e3460341023 somewhat painful backport of 3.5 branch, should mostly be ok
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2880
diff changeset
   168
    * wf_info_for inlined relation is set
0e3460341023 somewhat painful backport of 3.5 branch, should mostly be ok
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2880
diff changeset
   169
    * by_transition or to_state (managers only) inlined relation is set
7294
2af1a4cecda5 [workflow hooks] reuse metadata/integrity categories instead of a new 'workflow' category and drop useless hook
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6757
diff changeset
   170
2af1a4cecda5 [workflow hooks] reuse metadata/integrity categories instead of a new 'workflow' category and drop useless hook
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6757
diff changeset
   171
    Check for automatic transition to be fired at the end
2968
0e3460341023 somewhat painful backport of 3.5 branch, should mostly be ok
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2880
diff changeset
   172
    """
3376
f5c69485381f [appobjects] use __regid__ instead of __id__, more explicit
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3072
diff changeset
   173
    __regid__ = 'wffiretransition'
5877
0c7b7b76a84f [selectors] provide a new, optimized, is_instance selector that should at some point replace implements (along with the adaptable selector)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5685
diff changeset
   174
    __select__ = WorkflowHook.__select__ & is_instance('TrInfo')
2968
0e3460341023 somewhat painful backport of 3.5 branch, should mostly be ok
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2880
diff changeset
   175
    events = ('before_add_entity',)
2835
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   176
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   177
    def __call__(self):
2847
c2ee28f4d4b1 use ._cw instead of .cw_req
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2841
diff changeset
   178
        session = self._cw
2968
0e3460341023 somewhat painful backport of 3.5 branch, should mostly be ok
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2880
diff changeset
   179
        entity = self.entity
0e3460341023 somewhat painful backport of 3.5 branch, should mostly be ok
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2880
diff changeset
   180
        # first retreive entity to which the state change apply
0e3460341023 somewhat painful backport of 3.5 branch, should mostly be ok
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2880
diff changeset
   181
        try:
6142
8bc6eac1fac1 [session] cleanup hook / operation / entity edition api
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5877
diff changeset
   182
            foreid = entity.cw_attr_cache['wf_info_for']
2968
0e3460341023 somewhat painful backport of 3.5 branch, should mostly be ok
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2880
diff changeset
   183
        except KeyError:
5030
5238d9a8dfee [form] put qualified name on validation error, should fix #784299
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4835
diff changeset
   184
            qname = role_name('wf_info_for', 'subject')
2968
0e3460341023 somewhat painful backport of 3.5 branch, should mostly be ok
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2880
diff changeset
   185
            msg = session._('mandatory relation')
5030
5238d9a8dfee [form] put qualified name on validation error, should fix #784299
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4835
diff changeset
   186
            raise ValidationError(entity.eid, {qname: msg})
2968
0e3460341023 somewhat painful backport of 3.5 branch, should mostly be ok
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2880
diff changeset
   187
        forentity = session.entity_from_eid(foreid)
6757
bc878ec35794 #1382705 forbid with sql level locking the simultaneous fireing of a transition on a given entity
Alexandre Fayolle <alexandre.fayolle@logilab.fr>
parents: 6142
diff changeset
   188
        # see comment in the TrInfo entity definition
bc878ec35794 #1382705 forbid with sql level locking the simultaneous fireing of a transition on a given entity
Alexandre Fayolle <alexandre.fayolle@logilab.fr>
parents: 6142
diff changeset
   189
        entity.cw_edited['tr_count']=len(forentity.reverse_wf_info_for)
5556
9ab2b4c74baf [entity] introduce a new 'adapters' registry
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5424
diff changeset
   190
        iworkflowable = forentity.cw_adapt_to('IWorkflowable')
3024
bfaf056f1029 backport 3.5 step 2, backport wf changes in hooks/workflow.py
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2968
diff changeset
   191
        # then check it has a workflow set, unless we're in the process of changing
bfaf056f1029 backport 3.5 step 2, backport wf changes in hooks/workflow.py
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2968
diff changeset
   192
        # entity's workflow
bfaf056f1029 backport 3.5 step 2, backport wf changes in hooks/workflow.py
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2968
diff changeset
   193
        if session.transaction_data.get((forentity.eid, 'customwf')):
bfaf056f1029 backport 3.5 step 2, backport wf changes in hooks/workflow.py
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2968
diff changeset
   194
            wfeid = session.transaction_data[(forentity.eid, 'customwf')]
bfaf056f1029 backport 3.5 step 2, backport wf changes in hooks/workflow.py
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2968
diff changeset
   195
            wf = session.entity_from_eid(wfeid)
bfaf056f1029 backport 3.5 step 2, backport wf changes in hooks/workflow.py
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2968
diff changeset
   196
        else:
5556
9ab2b4c74baf [entity] introduce a new 'adapters' registry
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5424
diff changeset
   197
            wf = iworkflowable.current_workflow
2968
0e3460341023 somewhat painful backport of 3.5 branch, should mostly be ok
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2880
diff changeset
   198
        if wf is None:
0e3460341023 somewhat painful backport of 3.5 branch, should mostly be ok
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2880
diff changeset
   199
            msg = session._('related entity has no workflow set')
0e3460341023 somewhat painful backport of 3.5 branch, should mostly be ok
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2880
diff changeset
   200
            raise ValidationError(entity.eid, {None: msg})
0e3460341023 somewhat painful backport of 3.5 branch, should mostly be ok
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2880
diff changeset
   201
        # then check it has a state set
5556
9ab2b4c74baf [entity] introduce a new 'adapters' registry
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5424
diff changeset
   202
        fromstate = iworkflowable.current_state
2968
0e3460341023 somewhat painful backport of 3.5 branch, should mostly be ok
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2880
diff changeset
   203
        if fromstate is None:
0e3460341023 somewhat painful backport of 3.5 branch, should mostly be ok
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2880
diff changeset
   204
            msg = session._('related entity has no state')
0e3460341023 somewhat painful backport of 3.5 branch, should mostly be ok
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2880
diff changeset
   205
            raise ValidationError(entity.eid, {None: msg})
3024
bfaf056f1029 backport 3.5 step 2, backport wf changes in hooks/workflow.py
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2968
diff changeset
   206
        # True if we are coming back from subworkflow
bfaf056f1029 backport 3.5 step 2, backport wf changes in hooks/workflow.py
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2968
diff changeset
   207
        swtr = session.transaction_data.pop((forentity.eid, 'subwfentrytr'), None)
5164
4d99cccffe36 [wf] should use is_in_group to avoid error with internal manager
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5056
diff changeset
   208
        cowpowers = (session.user.is_in_group('managers')
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: 4719
diff changeset
   209
                     or not session.write_security)
2968
0e3460341023 somewhat painful backport of 3.5 branch, should mostly be ok
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2880
diff changeset
   210
        # no investigate the requested state change...
0e3460341023 somewhat painful backport of 3.5 branch, should mostly be ok
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2880
diff changeset
   211
        try:
6142
8bc6eac1fac1 [session] cleanup hook / operation / entity edition api
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5877
diff changeset
   212
            treid = entity.cw_attr_cache['by_transition']
2968
0e3460341023 somewhat painful backport of 3.5 branch, should mostly be ok
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2880
diff changeset
   213
        except KeyError:
3894
27cbf98ad863 forgotten stuff
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3890
diff changeset
   214
            # no transition set, check user is a manager and destination state
27cbf98ad863 forgotten stuff
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3890
diff changeset
   215
            # is specified (and valid)
3024
bfaf056f1029 backport 3.5 step 2, backport wf changes in hooks/workflow.py
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2968
diff changeset
   216
            if not cowpowers:
5030
5238d9a8dfee [form] put qualified name on validation error, should fix #784299
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4835
diff changeset
   217
                qname = role_name('by_transition', 'subject')
2968
0e3460341023 somewhat painful backport of 3.5 branch, should mostly be ok
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2880
diff changeset
   218
                msg = session._('mandatory relation')
5030
5238d9a8dfee [form] put qualified name on validation error, should fix #784299
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4835
diff changeset
   219
                raise ValidationError(entity.eid, {qname: msg})
6142
8bc6eac1fac1 [session] cleanup hook / operation / entity edition api
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5877
diff changeset
   220
            deststateeid = entity.cw_attr_cache.get('to_state')
2968
0e3460341023 somewhat painful backport of 3.5 branch, should mostly be ok
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2880
diff changeset
   221
            if not deststateeid:
5030
5238d9a8dfee [form] put qualified name on validation error, should fix #784299
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4835
diff changeset
   222
                qname = role_name('by_transition', 'subject')
2968
0e3460341023 somewhat painful backport of 3.5 branch, should mostly be ok
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2880
diff changeset
   223
                msg = session._('mandatory relation')
5030
5238d9a8dfee [form] put qualified name on validation error, should fix #784299
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4835
diff changeset
   224
                raise ValidationError(entity.eid, {qname: msg})
2968
0e3460341023 somewhat painful backport of 3.5 branch, should mostly be ok
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2880
diff changeset
   225
            deststate = wf.state_by_eid(deststateeid)
3777
3ef8cdb5fb1c backport stable branch
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3739
diff changeset
   226
            if deststate is None:
5030
5238d9a8dfee [form] put qualified name on validation error, should fix #784299
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4835
diff changeset
   227
                qname = role_name('to_state', 'subject')
3449
063488f14a0f no need to access to _ through entity.req...
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3376
diff changeset
   228
                msg = session._("state doesn't belong to entity's workflow")
5030
5238d9a8dfee [form] put qualified name on validation error, should fix #784299
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4835
diff changeset
   229
                raise ValidationError(entity.eid, {qname: msg})
2968
0e3460341023 somewhat painful backport of 3.5 branch, should mostly be ok
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2880
diff changeset
   230
        else:
3894
27cbf98ad863 forgotten stuff
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3890
diff changeset
   231
            # check transition is valid and allowed, unless we're coming back
27cbf98ad863 forgotten stuff
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3890
diff changeset
   232
            # from subworkflow
3024
bfaf056f1029 backport 3.5 step 2, backport wf changes in hooks/workflow.py
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2968
diff changeset
   233
            tr = session.entity_from_eid(treid)
bfaf056f1029 backport 3.5 step 2, backport wf changes in hooks/workflow.py
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2968
diff changeset
   234
            if swtr is None:
5030
5238d9a8dfee [form] put qualified name on validation error, should fix #784299
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4835
diff changeset
   235
                qname = role_name('by_transition', 'subject')
3024
bfaf056f1029 backport 3.5 step 2, backport wf changes in hooks/workflow.py
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2968
diff changeset
   236
                if tr is None:
bfaf056f1029 backport 3.5 step 2, backport wf changes in hooks/workflow.py
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2968
diff changeset
   237
                    msg = session._("transition doesn't belong to entity's workflow")
5030
5238d9a8dfee [form] put qualified name on validation error, should fix #784299
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4835
diff changeset
   238
                    raise ValidationError(entity.eid, {qname: msg})
3024
bfaf056f1029 backport 3.5 step 2, backport wf changes in hooks/workflow.py
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2968
diff changeset
   239
                if not tr.has_input_state(fromstate):
4181
c79135c217df backport stable
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4088
diff changeset
   240
                    msg = session._("transition %(tr)s isn't allowed from %(st)s") % {
c79135c217df backport stable
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4088
diff changeset
   241
                        'tr': session._(tr.name), 'st': session._(fromstate.name)}
5030
5238d9a8dfee [form] put qualified name on validation error, should fix #784299
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4835
diff changeset
   242
                    raise ValidationError(entity.eid, {qname: msg})
4003
b9436fe77c9e fix bad merge
Sandrine Ribeau <sandrine.ribeau@logilab.fr>
parents: 3894
diff changeset
   243
                if not tr.may_be_fired(foreid):
3024
bfaf056f1029 backport 3.5 step 2, backport wf changes in hooks/workflow.py
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2968
diff changeset
   244
                    msg = session._("transition may not be fired")
5030
5238d9a8dfee [form] put qualified name on validation error, should fix #784299
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4835
diff changeset
   245
                    raise ValidationError(entity.eid, {qname: msg})
6142
8bc6eac1fac1 [session] cleanup hook / operation / entity edition api
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5877
diff changeset
   246
            deststateeid = entity.cw_attr_cache.get('to_state')
8bc6eac1fac1 [session] cleanup hook / operation / entity edition api
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5877
diff changeset
   247
            if deststateeid is not None:
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: 4307
diff changeset
   248
                if not cowpowers and deststateeid != tr.destination(forentity).eid:
5030
5238d9a8dfee [form] put qualified name on validation error, should fix #784299
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4835
diff changeset
   249
                    qname = role_name('by_transition', 'subject')
3024
bfaf056f1029 backport 3.5 step 2, backport wf changes in hooks/workflow.py
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2968
diff changeset
   250
                    msg = session._("transition isn't allowed")
5030
5238d9a8dfee [form] put qualified name on validation error, should fix #784299
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4835
diff changeset
   251
                    raise ValidationError(entity.eid, {qname: msg})
3024
bfaf056f1029 backport 3.5 step 2, backport wf changes in hooks/workflow.py
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2968
diff changeset
   252
                if swtr is None:
bfaf056f1029 backport 3.5 step 2, backport wf changes in hooks/workflow.py
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2968
diff changeset
   253
                    deststate = session.entity_from_eid(deststateeid)
bfaf056f1029 backport 3.5 step 2, backport wf changes in hooks/workflow.py
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2968
diff changeset
   254
                    if not cowpowers and deststate is None:
5030
5238d9a8dfee [form] put qualified name on validation error, should fix #784299
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4835
diff changeset
   255
                        qname = role_name('to_state', 'subject')
3449
063488f14a0f no need to access to _ through entity.req...
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3376
diff changeset
   256
                        msg = session._("state doesn't belong to entity's workflow")
5030
5238d9a8dfee [form] put qualified name on validation error, should fix #784299
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4835
diff changeset
   257
                        raise ValidationError(entity.eid, {qname: msg})
3024
bfaf056f1029 backport 3.5 step 2, backport wf changes in hooks/workflow.py
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2968
diff changeset
   258
            else:
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: 4307
diff changeset
   259
                deststateeid = tr.destination(forentity).eid
2968
0e3460341023 somewhat painful backport of 3.5 branch, should mostly be ok
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2880
diff changeset
   260
        # everything is ok, add missing information on the trinfo entity
6142
8bc6eac1fac1 [session] cleanup hook / operation / entity edition api
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5877
diff changeset
   261
        entity.cw_edited['from_state'] = fromstate.eid
8bc6eac1fac1 [session] cleanup hook / operation / entity edition api
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5877
diff changeset
   262
        entity.cw_edited['to_state'] = deststateeid
2968
0e3460341023 somewhat painful backport of 3.5 branch, should mostly be ok
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2880
diff changeset
   263
        nocheck = session.transaction_data.setdefault('skip-security', set())
0e3460341023 somewhat painful backport of 3.5 branch, should mostly be ok
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2880
diff changeset
   264
        nocheck.add((entity.eid, 'from_state', fromstate.eid))
0e3460341023 somewhat painful backport of 3.5 branch, should mostly be ok
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2880
diff changeset
   265
        nocheck.add((entity.eid, 'to_state', deststateeid))
3739
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3675
diff changeset
   266
        _FireAutotransitionOp(session, entity=forentity)
2968
0e3460341023 somewhat painful backport of 3.5 branch, should mostly be ok
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2880
diff changeset
   267
0e3460341023 somewhat painful backport of 3.5 branch, should mostly be ok
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2880
diff changeset
   268
0e3460341023 somewhat painful backport of 3.5 branch, should mostly be ok
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2880
diff changeset
   269
class FiredTransitionHook(WorkflowHook):
7294
2af1a4cecda5 [workflow hooks] reuse metadata/integrity categories instead of a new 'workflow' category and drop useless hook
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6757
diff changeset
   270
    """change related entity state and handle exit of subworkflow"""
3376
f5c69485381f [appobjects] use __regid__ instead of __id__, more explicit
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3072
diff changeset
   271
    __regid__ = 'wffiretransition'
5877
0c7b7b76a84f [selectors] provide a new, optimized, is_instance selector that should at some point replace implements (along with the adaptable selector)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5685
diff changeset
   272
    __select__ = WorkflowHook.__select__ & is_instance('TrInfo')
2968
0e3460341023 somewhat painful backport of 3.5 branch, should mostly be ok
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2880
diff changeset
   273
    events = ('after_add_entity',)
0e3460341023 somewhat painful backport of 3.5 branch, should mostly be ok
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2880
diff changeset
   274
0e3460341023 somewhat painful backport of 3.5 branch, should mostly be ok
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2880
diff changeset
   275
    def __call__(self):
3674
387d51af966d backport stable branch
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3654
diff changeset
   276
        trinfo = self.entity
6142
8bc6eac1fac1 [session] cleanup hook / operation / entity edition api
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5877
diff changeset
   277
        rcache = trinfo.cw_attr_cache
8bc6eac1fac1 [session] cleanup hook / operation / entity edition api
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5877
diff changeset
   278
        _change_state(self._cw, rcache['wf_info_for'], rcache['from_state'],
8bc6eac1fac1 [session] cleanup hook / operation / entity edition api
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5877
diff changeset
   279
                      rcache['to_state'])
8bc6eac1fac1 [session] cleanup hook / operation / entity edition api
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5877
diff changeset
   280
        forentity = self._cw.entity_from_eid(rcache['wf_info_for'])
5556
9ab2b4c74baf [entity] introduce a new 'adapters' registry
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5424
diff changeset
   281
        iworkflowable = forentity.cw_adapt_to('IWorkflowable')
6142
8bc6eac1fac1 [session] cleanup hook / operation / entity edition api
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5877
diff changeset
   282
        assert iworkflowable.current_state.eid == rcache['to_state']
5556
9ab2b4c74baf [entity] introduce a new 'adapters' registry
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5424
diff changeset
   283
        if iworkflowable.main_workflow.eid != iworkflowable.current_workflow.eid:
3674
387d51af966d backport stable branch
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3654
diff changeset
   284
            _SubWorkflowExitOp(self._cw, forentity=forentity, trinfo=trinfo)
3024
bfaf056f1029 backport 3.5 step 2, backport wf changes in hooks/workflow.py
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2968
diff changeset
   285
bfaf056f1029 backport 3.5 step 2, backport wf changes in hooks/workflow.py
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2968
diff changeset
   286
bfaf056f1029 backport 3.5 step 2, backport wf changes in hooks/workflow.py
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2968
diff changeset
   287
class CheckInStateChangeAllowed(WorkflowHook):
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: 4719
diff changeset
   288
    """check state apply, in case of direct in_state change using unsafe execute
3024
bfaf056f1029 backport 3.5 step 2, backport wf changes in hooks/workflow.py
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2968
diff changeset
   289
    """
3376
f5c69485381f [appobjects] use __regid__ instead of __id__, more explicit
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3072
diff changeset
   290
    __regid__ = 'wfcheckinstate'
3024
bfaf056f1029 backport 3.5 step 2, backport wf changes in hooks/workflow.py
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2968
diff changeset
   291
    __select__ = WorkflowHook.__select__ & hook.match_rtype('in_state')
bfaf056f1029 backport 3.5 step 2, backport wf changes in hooks/workflow.py
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2968
diff changeset
   292
    events = ('before_add_relation',)
7294
2af1a4cecda5 [workflow hooks] reuse metadata/integrity categories instead of a new 'workflow' category and drop useless hook
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6757
diff changeset
   293
    category = 'integrity'
3024
bfaf056f1029 backport 3.5 step 2, backport wf changes in hooks/workflow.py
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2968
diff changeset
   294
bfaf056f1029 backport 3.5 step 2, backport wf changes in hooks/workflow.py
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2968
diff changeset
   295
    def __call__(self):
bfaf056f1029 backport 3.5 step 2, backport wf changes in hooks/workflow.py
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2968
diff changeset
   296
        session = self._cw
4088
23ce2b3fb03d don't use setdefault with a tuple as value, a set is expected
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4075
diff changeset
   297
        nocheck = session.transaction_data.get('skip-security', ())
3024
bfaf056f1029 backport 3.5 step 2, backport wf changes in hooks/workflow.py
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2968
diff changeset
   298
        if (self.eidfrom, 'in_state', self.eidto) in nocheck:
bfaf056f1029 backport 3.5 step 2, backport wf changes in hooks/workflow.py
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2968
diff changeset
   299
            # state changed through TrInfo insertion, so we already know it's ok
bfaf056f1029 backport 3.5 step 2, backport wf changes in hooks/workflow.py
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2968
diff changeset
   300
            return
bfaf056f1029 backport 3.5 step 2, backport wf changes in hooks/workflow.py
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2968
diff changeset
   301
        entity = session.entity_from_eid(self.eidfrom)
5556
9ab2b4c74baf [entity] introduce a new 'adapters' registry
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5424
diff changeset
   302
        iworkflowable = entity.cw_adapt_to('IWorkflowable')
9ab2b4c74baf [entity] introduce a new 'adapters' registry
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5424
diff changeset
   303
        mainwf = iworkflowable.main_workflow
3024
bfaf056f1029 backport 3.5 step 2, backport wf changes in hooks/workflow.py
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2968
diff changeset
   304
        if mainwf is None:
bfaf056f1029 backport 3.5 step 2, backport wf changes in hooks/workflow.py
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2968
diff changeset
   305
            msg = session._('entity has no workflow set')
bfaf056f1029 backport 3.5 step 2, backport wf changes in hooks/workflow.py
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2968
diff changeset
   306
            raise ValidationError(entity.eid, {None: msg})
bfaf056f1029 backport 3.5 step 2, backport wf changes in hooks/workflow.py
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2968
diff changeset
   307
        for wf in mainwf.iter_workflows():
bfaf056f1029 backport 3.5 step 2, backport wf changes in hooks/workflow.py
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2968
diff changeset
   308
            if wf.state_by_eid(self.eidto):
bfaf056f1029 backport 3.5 step 2, backport wf changes in hooks/workflow.py
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2968
diff changeset
   309
                break
bfaf056f1029 backport 3.5 step 2, backport wf changes in hooks/workflow.py
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2968
diff changeset
   310
        else:
5030
5238d9a8dfee [form] put qualified name on validation error, should fix #784299
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4835
diff changeset
   311
            qname = role_name('in_state', 'subject')
3024
bfaf056f1029 backport 3.5 step 2, backport wf changes in hooks/workflow.py
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2968
diff changeset
   312
            msg = session._("state doesn't belong to entity's workflow. You may "
bfaf056f1029 backport 3.5 step 2, backport wf changes in hooks/workflow.py
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2968
diff changeset
   313
                            "want to set a custom workflow for this entity first.")
5030
5238d9a8dfee [form] put qualified name on validation error, should fix #784299
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4835
diff changeset
   314
            raise ValidationError(self.eidfrom, {qname: msg})
5556
9ab2b4c74baf [entity] introduce a new 'adapters' registry
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5424
diff changeset
   315
        if iworkflowable.current_workflow and wf.eid != iworkflowable.current_workflow.eid:
5030
5238d9a8dfee [form] put qualified name on validation error, should fix #784299
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4835
diff changeset
   316
            qname = role_name('in_state', 'subject')
3024
bfaf056f1029 backport 3.5 step 2, backport wf changes in hooks/workflow.py
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2968
diff changeset
   317
            msg = session._("state doesn't belong to entity's current workflow")
5030
5238d9a8dfee [form] put qualified name on validation error, should fix #784299
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4835
diff changeset
   318
            raise ValidationError(self.eidfrom, {qname: msg})
2841
107ba1c45227 rewrite hooks in sobjects as new Hook style into hooks sub-package
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2835
diff changeset
   319
107ba1c45227 rewrite hooks in sobjects as new Hook style into hooks sub-package
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2835
diff changeset
   320
107ba1c45227 rewrite hooks in sobjects as new Hook style into hooks sub-package
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2835
diff changeset
   321
class SetModificationDateOnStateChange(WorkflowHook):
107ba1c45227 rewrite hooks in sobjects as new Hook style into hooks sub-package
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2835
diff changeset
   322
    """update entity's modification date after changing its state"""
3376
f5c69485381f [appobjects] use __regid__ instead of __id__, more explicit
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3072
diff changeset
   323
    __regid__ = 'wfsyncmdate'
2841
107ba1c45227 rewrite hooks in sobjects as new Hook style into hooks sub-package
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2835
diff changeset
   324
    __select__ = WorkflowHook.__select__ & hook.match_rtype('in_state')
107ba1c45227 rewrite hooks in sobjects as new Hook style into hooks sub-package
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2835
diff changeset
   325
    events = ('after_add_relation',)
107ba1c45227 rewrite hooks in sobjects as new Hook style into hooks sub-package
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2835
diff changeset
   326
107ba1c45227 rewrite hooks in sobjects as new Hook style into hooks sub-package
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2835
diff changeset
   327
    def __call__(self):
2847
c2ee28f4d4b1 use ._cw instead of .cw_req
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2841
diff changeset
   328
        if self._cw.added_in_transaction(self.eidfrom):
2841
107ba1c45227 rewrite hooks in sobjects as new Hook style into hooks sub-package
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2835
diff changeset
   329
            # new entity, not needed
107ba1c45227 rewrite hooks in sobjects as new Hook style into hooks sub-package
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2835
diff changeset
   330
            return
2847
c2ee28f4d4b1 use ._cw instead of .cw_req
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2841
diff changeset
   331
        entity = self._cw.entity_from_eid(self.eidfrom)
2841
107ba1c45227 rewrite hooks in sobjects as new Hook style into hooks sub-package
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2835
diff changeset
   332
        try:
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: 4719
diff changeset
   333
            entity.set_attributes(modification_date=datetime.now())
2841
107ba1c45227 rewrite hooks in sobjects as new Hook style into hooks sub-package
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2835
diff changeset
   334
        except RepositoryError, ex:
107ba1c45227 rewrite hooks in sobjects as new Hook style into hooks sub-package
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2835
diff changeset
   335
            # usually occurs if entity is coming from a read-only source
107ba1c45227 rewrite hooks in sobjects as new Hook style into hooks sub-package
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2835
diff changeset
   336
            # (eg ldap user)
107ba1c45227 rewrite hooks in sobjects as new Hook style into hooks sub-package
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2835
diff changeset
   337
            self.warning('cant change modification date for %s: %s', entity, ex)
2968
0e3460341023 somewhat painful backport of 3.5 branch, should mostly be ok
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2880
diff changeset
   338
0e3460341023 somewhat painful backport of 3.5 branch, should mostly be ok
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2880
diff changeset
   339
3024
bfaf056f1029 backport 3.5 step 2, backport wf changes in hooks/workflow.py
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2968
diff changeset
   340
class CheckWorkflowTransitionExitPoint(WorkflowHook):
bfaf056f1029 backport 3.5 step 2, backport wf changes in hooks/workflow.py
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2968
diff changeset
   341
    """check that there is no multiple exits from the same state"""
3376
f5c69485381f [appobjects] use __regid__ instead of __id__, more explicit
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3072
diff changeset
   342
    __regid__ = 'wfcheckwftrexit'
3024
bfaf056f1029 backport 3.5 step 2, backport wf changes in hooks/workflow.py
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2968
diff changeset
   343
    __select__ = WorkflowHook.__select__ & hook.match_rtype('subworkflow_exit')
bfaf056f1029 backport 3.5 step 2, backport wf changes in hooks/workflow.py
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2968
diff changeset
   344
    events = ('after_add_relation',)
bfaf056f1029 backport 3.5 step 2, backport wf changes in hooks/workflow.py
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2968
diff changeset
   345
bfaf056f1029 backport 3.5 step 2, backport wf changes in hooks/workflow.py
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2968
diff changeset
   346
    def __call__(self):
bfaf056f1029 backport 3.5 step 2, backport wf changes in hooks/workflow.py
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2968
diff changeset
   347
        _CheckTrExitPoint(self._cw, treid=self.eidfrom)
bfaf056f1029 backport 3.5 step 2, backport wf changes in hooks/workflow.py
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2968
diff changeset
   348
bfaf056f1029 backport 3.5 step 2, backport wf changes in hooks/workflow.py
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2968
diff changeset
   349
2968
0e3460341023 somewhat painful backport of 3.5 branch, should mostly be ok
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2880
diff changeset
   350
class SetCustomWorkflow(WorkflowHook):
3376
f5c69485381f [appobjects] use __regid__ instead of __id__, more explicit
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3072
diff changeset
   351
    __regid__ = 'wfsetcustom'
2968
0e3460341023 somewhat painful backport of 3.5 branch, should mostly be ok
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2880
diff changeset
   352
    __select__ = WorkflowHook.__select__ & hook.match_rtype('custom_workflow')
0e3460341023 somewhat painful backport of 3.5 branch, should mostly be ok
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2880
diff changeset
   353
    events = ('after_add_relation',)
0e3460341023 somewhat painful backport of 3.5 branch, should mostly be ok
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2880
diff changeset
   354
0e3460341023 somewhat painful backport of 3.5 branch, should mostly be ok
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2880
diff changeset
   355
    def __call__(self):
0e3460341023 somewhat painful backport of 3.5 branch, should mostly be ok
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2880
diff changeset
   356
        _WorkflowChangedOp(self._cw, eid=self.eidfrom, wfeid=self.eidto)
0e3460341023 somewhat painful backport of 3.5 branch, should mostly be ok
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2880
diff changeset
   357
0e3460341023 somewhat painful backport of 3.5 branch, should mostly be ok
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2880
diff changeset
   358
0e3460341023 somewhat painful backport of 3.5 branch, should mostly be ok
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2880
diff changeset
   359
class DelCustomWorkflow(SetCustomWorkflow):
3376
f5c69485381f [appobjects] use __regid__ instead of __id__, more explicit
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3072
diff changeset
   360
    __regid__ = 'wfdelcustom'
2968
0e3460341023 somewhat painful backport of 3.5 branch, should mostly be ok
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2880
diff changeset
   361
    events = ('after_delete_relation',)
0e3460341023 somewhat painful backport of 3.5 branch, should mostly be ok
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2880
diff changeset
   362
0e3460341023 somewhat painful backport of 3.5 branch, should mostly be ok
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2880
diff changeset
   363
    def __call__(self):
0e3460341023 somewhat painful backport of 3.5 branch, should mostly be ok
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2880
diff changeset
   364
        entity = self._cw.entity_from_eid(self.eidfrom)
5556
9ab2b4c74baf [entity] introduce a new 'adapters' registry
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5424
diff changeset
   365
        typewf = entity.cw_adapt_to('IWorkflowable').cwetype_workflow()
2968
0e3460341023 somewhat painful backport of 3.5 branch, should mostly be ok
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2880
diff changeset
   366
        if typewf is not None:
0e3460341023 somewhat painful backport of 3.5 branch, should mostly be ok
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2880
diff changeset
   367
            _WorkflowChangedOp(self._cw, eid=self.eidfrom, wfeid=typewf.eid)
0e3460341023 somewhat painful backport of 3.5 branch, should mostly be ok
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2880
diff changeset
   368