Completed
Branch master (9edffc)
by Jordi
04:36
created

AccountancyFieldsVisibility.isVisible()   A

Complexity

Conditions 2

Size

Total Lines 4
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 4
dl 0
loc 4
rs 10
c 0
b 0
f 0
cc 2
nop 4
1
# -*- coding: utf-8 -*-
2
#
3
# This file is part of SENAITE.CORE
4
#
5
# Copyright 2018 by it's authors.
6
# Some rights reserved. See LICENSE.rst, CONTRIBUTORS.rst.
7
8
from bika.lims import logger
9
from bika.lims.interfaces import IATWidgetVisibility
10
from bika.lims.interfaces import IBatch, IClient
11
from bika.lims.utils import getHiddenAttributesForClass
12
from zope.interface import implements
13
14
_marker = []
15
16
17
class SenaiteATWidgetVisibility(object):
18
    implements(IATWidgetVisibility)
19
20
    def __init__(self, context, sort=1000, field_names=None):
21
        self.context = context
22
        self.sort = sort
23
        self.field_names = field_names or list()
24
25
    def __call__(self, context, mode, field, default):
26
        state = default if default else "visible"
27
        if not field or field.getName() not in self.field_names:
28
            return state
29
        return self.isVisible(field, mode, default)
30
31
    def isVisible(self, field, mode="view", default="visible"):
32
        """Returns if the field is visible in a given mode
33
        """
34
        raise NotImplementedError("Must be implemented by subclass")
35
36
37
class ClientFieldVisibility(SenaiteATWidgetVisibility):
38
    """The Client field is editable by default in ar_add.  This adapter
39
    will force the Client field to be hidden when it should not be set
40
    by the user.
41
    """
42
    def __init__(self, context):
43
        super(ClientFieldVisibility, self).__init__(
44
            context=context, sort=10, field_names=["Client"])
45
46
    def isVisible(self, field, mode="view", default="visible"):
47
        if mode == "add":
48
            parent = self.context.aq_parent
49
            if IClient.providedBy(parent):
50
                # Note we return "hidden" here instead of "invisible": we want
51
                # the field to be auto-filled and processed on submit
52
                return "hidden"
53
            if IBatch.providedBy(parent) and parent.getClient():
54
                # The Batch has a Client assigned already!
55
                # Note we can have Batches without a client assigned
56
                return "hidden"
57
        elif mode == "edit":
58
            # This is already managed by wf permission, but is **never** a good
59
            # idea to allow the user to change the Client from an AR (basically
60
            # because otherwise, we'd need to move the object from one client
61
            # folder to another!).
62
            return "invisible"
63
        return default
64
65
66
class BatchFieldVisibility(SenaiteATWidgetVisibility):
67
    """This will force the 'Batch' field to 'hidden' in ar_add when the parent
68
    context is a Batch.
69
    """
70
    def __init__(self, context):
71
        super(BatchFieldVisibility, self).__init__(
72
            context=context, sort=10, field_names=["Batch"])
73
74
    def isVisible(self, field, mode="view", default="visible"):
75
        if IBatch.providedBy(self.context.aq_parent):
76
            return "hidden"
77
        return default
78
79
80
class PreservationFieldsVisibility(SenaiteATWidgetVisibility):
81
    """Display/Hide fields related with Preservation Workflow
82
    """
83
    def __init__(self, context):
84
        super(PreservationFieldsVisibility, self).__init__(
85
            context=context, sort=10,
86
            field_names=["DatePreserved", "Preservation", "Preserver"])
87
88
    def isVisible(self, field, mode="view", default="visible"):
89
        if not self.context.bika_setup.getSamplePreservationEnabled():
90
            return "invisible"
91
        return default
92
93
94
class ScheduledSamplingFieldsVisibility(SenaiteATWidgetVisibility):
95
    """Display/Hide fields related with ScheduledSampling Workflow
96
    """
97
    def __init__(self, context):
98
        super(ScheduledSamplingFieldsVisibility, self).__init__(
99
            context=context, sort=10,
100
            field_names=["ScheduledSamplingSampler", "SamplingRound"])
101
102
    def isVisible(self, field, mode="view", default="visible"):
103
        if not self.context.bika_setup.getScheduleSamplingEnabled():
104
            return "invisible"
105
        return default
106
107
108
class SamplingFieldsVisibility(SenaiteATWidgetVisibility):
109
    """
110
    This will handle Handling 'DateSampled' and 'SamplingDate' fields'
111
    visibilities based on Sampling Workflow (SWF)status. We must check the
112
    attribute saved on the sample, not the bika_setup value though. See the
113
    internal comments how it enables/disables WidgetVisibility depending on SWF.
114
    """
115
    def __init__(self, context):
116
        super(SamplingFieldsVisibility, self).__init__(
117
            context=context, sort=10,
118
            field_names=["Sampler", "DateSampled", "SamplingDate"])
119
120
    def isVisible(self, field, mode="view", default="visible"):
121
        # If object has been already created, get SWF statues from it.
122
        sw_enabled = False
123
        if hasattr(self.context, 'getSamplingWorkflowEnabled') and \
124
                self.context.getSamplingWorkflowEnabled() is not '':
125
            swf_enabled = self.context.getSamplingWorkflowEnabled()
126
        else:
127
            swf_enabled = self.context.bika_setup.getSamplingWorkflowEnabled()
128
129
        if mode == "add":
130
            if field.getName() == "DateSampled":
131
                field.required = not swf_enabled
132
                return swf_enabled and "invisible" or "edit"
133
            elif field.getName() == "SamplingDate":
134
                field.required = swf_enabled
135
                return swf_enabled and "edit" or "invisible"
136
            elif field.getName() == "Sampler":
137
                return swf_enabled and "edit" or "invisible"
138
139
        elif not swf_enabled:
140
            if field.getName() != "DateSampled":
141
                return "invisible"
142
143
        return default
144
145
146
class RegistryHiddenFieldsVisibility(SenaiteATWidgetVisibility):
147
    """Do not display fields declared in bika.lims.hiddenattributes registry key
148
    """
149
    def __init__(self, context):
150
        field_names = getHiddenAttributesForClass(context.portal_type)
151
        super(RegistryHiddenFieldsVisibility, self).__init__(
152
            context=context, sort=-1, field_names=[field_names,])
153
154
    def isVisible(self, field, mode="view", default="visible"):
155
        return "invisible"
156
157
158
class AccountancyFieldsVisibility(SenaiteATWidgetVisibility):
159
    """Display/Hide fields related with Accountancy (Discount, prices, invoice)
160
    """
161
    def __init__(self, context):
162
        super(AccountancyFieldsVisibility, self).__init__(
163
            context=context, sort=3,
164
            field_names=["BulkDiscount", "MemberDiscountApplies",
165
                         "InvoiceExclude", "MemberDiscount"])
166
167
    def isVisible(self, field, mode="view", default="visible"):
168
        if not self.context.bika_setup.getShowPrices():
169
            return "invisible"
170
        return default
171
172
173
class DateReceivedFieldVisibility(SenaiteATWidgetVisibility):
174
    """DateReceived is editable in sample context, only if all related analyses
175
    are not yet submitted.
176
    """
177
    def __init__(self, context):
178
        super(DateReceivedFieldVisibility, self).__init__(
179
            context=context, sort=3, field_names=["DateReceived"])
180
181
    def isVisible(self, field, mode="view", default="visible"):
182
        """Returns whether the field is visible in a given mode
183
        """
184
        if mode != "edit":
185
            return default
186
        if not hasattr(self.context, "isOpen"):
187
            logger.warn("Object {}  does not have 'isOpen' method defined".
188
                        format(self.context.__class__.__name__))
189
            return default
190
        return self.context.isOpen() and "visible" or "invisible"
191