Passed
Push — master ( d6b140...72cad7 )
by Ramon
05:21
created

guard_verify()   B

Complexity

Conditions 6

Size

Total Lines 32
Code Lines 14

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 14
dl 0
loc 32
rs 8.6666
c 0
b 0
f 0
cc 6
nop 1
1
# -*- coding: utf-8 -*-
2
#
3
# This file is part of SENAITE.CORE.
4
#
5
# SENAITE.CORE is free software: you can redistribute it and/or modify it under
6
# the terms of the GNU General Public License as published by the Free Software
7
# Foundation, version 2.
8
#
9
# This program is distributed in the hope that it will be useful, but WITHOUT
10
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
11
# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
12
# details.
13
#
14
# You should have received a copy of the GNU General Public License along with
15
# this program; if not, write to the Free Software Foundation, Inc., 51
16
# Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
17
#
18
# Copyright 2018-2019 by it's authors.
19
# Some rights reserved, see README and LICENSE.
20
21
from bika.lims import api
22
from bika.lims.interfaces import ISubmitted, IVerified
23
from bika.lims.workflow import isTransitionAllowed
24
25
26
def guard_submit(obj):
27
    """Returns if 'submit' transition can be applied to the worksheet passed in.
28
    By default, the target state for the 'submit' transition for a worksheet is
29
    'to_be_verified', so this guard returns true if all the analyses assigned
30
    to the worksheet have already been submitted. Those analyses that are in a
31
    non-valid state (cancelled, inactive) are dismissed in the evaluation, but
32
    at least one analysis must be in an active state (and submitted) for this
33
    guard to return True. Otherwise, always returns False.
34
    Note this guard depends entirely on the current status of the children.
35
    """
36
    analyses = obj.getAnalyses()
37
    if not analyses:
38
        # An empty worksheet cannot be submitted
39
        return False
40
41
    can_submit = False
42
    for analysis in obj.getAnalyses():
43
        # Dismiss analyses that are not active
44
        if not api.is_active(analysis):
45
            continue
46
        # Dismiss analyses that have been rejected or retracted
47
        if api.get_workflow_status_of(analysis) in ["rejected", "retracted"]:
48
            continue
49
        # Worksheet cannot be submitted if there is one analysis not submitted
50
        can_submit = ISubmitted.providedBy(analysis)
51
        if not can_submit:
52
            # No need to look further
53
            return False
54
55
    # This prevents the submission of the worksheet if all its analyses are in
56
    # a detached status (rejected, retracted or cancelled)
57
    return can_submit
58
59
60
def guard_retract(worksheet):
61
    """Return whether the transition retract can be performed or not to the
62
    worksheet passed in. Since the retract transition from worksheet is a
63
    shortcut to retract transitions from all analyses the worksheet contains,
64
    this guard only returns True if retract transition is allowed for all
65
    analyses the worksheet contains
66
    """
67
    analyses = worksheet.getAnalyses()
68
    detached = ['rejected', 'retracted']
69
    num_detached = 0
70
    for analysis in analyses:
71
        if api.get_workflow_status_of(analysis) in detached:
72
            num_detached += 1
73
        elif not isTransitionAllowed(analysis, "retract"):
74
            return False
75
    return analyses and num_detached < len(analyses) or False
76
77
78
def guard_verify(obj):
79
    """Returns True if 'verify' transition can be applied to the Worksheet
80
    passed in. This is, returns true if all the analyses assigned
81
    have already been verified. Those analyses that are in an inactive state
82
    (cancelled, inactive) are dismissed, but at least one analysis must be in
83
    an active state (and verified), otherwise always return False.
84
    Note this guard depends entirely on the current status of the children
85
    :returns: true or false
86
    """
87
88
    analyses = obj.getAnalyses()
89
    if not analyses:
90
        # An empty worksheet cannot be verified
91
        return False
92
93
    can_verify = False
94
    for analysis in obj.getAnalyses():
95
        # Dismiss analyses that are not active
96
        if not api.is_active(analysis):
97
            continue
98
        # Dismiss analyses that have been rejected or retracted
99
        if api.get_workflow_status_of(analysis) in ["rejected", "retracted"]:
100
            continue
101
        # Worksheet cannot be verified if there is one analysis not verified
102
        can_verify = IVerified.providedBy(analysis)
103
        if not can_verify:
104
            # No need to look further
105
            return False
106
107
    # This prevents the verification of the worksheet if all its analyses are in
108
    # a detached status (rejected, retracted or cancelled)
109
    return can_verify
110
111
112
def guard_rollback_to_open(worksheet):
113
    """Return whether 'rollback_to_receive' transition can be performed or not
114
    """
115
    for analysis in worksheet.getAnalyses():
116
        if api.get_review_status(analysis) in ["assigned"]:
117
            return True
118
    return False
119
120
121
def guard_remove(worksheet):
122
    """Return whether the workflow can be removed. Returns true if the worksheet
123
    does not contain any analysis
124
    """
125
    if worksheet.getAnalyses():
126
        return False
127
    return True
128