Passed
Push — 2.x ( 387b1f...1586f5 )
by Ramon
06:16
created

SampleContainer.accessor()   A

Complexity

Conditions 2

Size

Total Lines 8
Code Lines 6

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 6
dl 0
loc 8
rs 10
c 0
b 0
f 0
cc 2
nop 2
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-2024 by it's authors.
19
# Some rights reserved, see README and LICENSE.
20
21
from AccessControl import ClassSecurityInfo
22
from bika.lims import api
23
from bika.lims import senaiteMessageFactory as _
24
from bika.lims.interfaces import IDeactivable
25
from plone.autoform import directives
26
from plone.supermodel import model
27
from Products.CMFCore import permissions
28
from senaite.core.catalog import SETUP_CATALOG
29
from senaite.core.content.base import Container
30
from senaite.core.interfaces import ISampleContainer
31
from senaite.core.schema import UIDReferenceField
32
from senaite.core.z3cform.widgets.uidreference import UIDReferenceWidgetFactory
33
from zope import schema
34
from zope.interface import implementer
35
from zope.interface import Invalid
36
from zope.interface import invariant
37
38
39
class ISampleContainerSchema(model.Schema):
40
    """Schema interface
41
    """
42
43
    title = schema.TextLine(
44
        title=_(
45
            u"title_samplecontainer_title",
46
            default=u"Name"
47
        ),
48
        required=True,
49
    )
50
51
    description = schema.Text(
52
        title=_(
53
            u"title_samplecontainer_description",
54
            default=u"Description"
55
        ),
56
        required=False,
57
    )
58
59
    # Container type reference
60
    directives.widget(
61
        "containertype",
62
        UIDReferenceWidgetFactory,
63
        catalog=SETUP_CATALOG,
64
        query="get_containertype_query",
65
        display_template="<a href='${url}'>${title}</a>",
66
        columns="get_default_columns",
67
        limit=5,
68
    )
69
    containertype = UIDReferenceField(
70
        title=_(u"Container Type"),
71
        allowed_types=("ContainerType", ),
72
        multi_valued=False,
73
        description=_(u"Type of the container"),
74
        required=False,
75
    )
76
77
    capacity = schema.TextLine(
78
        title=_("Capacity"),
79
        description=_("Maximum possible size or volume of samples"),
80
        default=u"0 ml",
81
        required=True,
82
    )
83
84
    pre_preserved = schema.Bool(
85
        title=_("Pre-preserved"),
86
        description=_(
87
            "Check this box if this container is already preserved."
88
            "Setting this will short-circuit the preservation workflow "
89
            "for sample partitions stored in this container."),
90
        required=True,
91
    )
92
93
    @invariant
94
    def validate_pre_preserved(data):
95
        """Checks if a preservation is selected
96
        """
97
        if data.pre_preserved is False:
98
            return
99
        if not data.preservation:
100
            raise Invalid(_(
101
                "Pre-preserved containers must have a preservation selected"))
102
103
    # Preservation reference
104
    directives.widget(
105
        "preservation",
106
        UIDReferenceWidgetFactory,
107
        catalog=SETUP_CATALOG,
108
        query="get_preservation_query",
109
        display_template="<a href='${url}'>${title}</a>",
110
        columns="get_default_columns",
111
        limit=5,
112
    )
113
    preservation = UIDReferenceField(
114
        title=_(u"Preservation"),
115
        allowed_types=("SamplePreservation", ),
116
        multi_valued=False,
117
        description=_(u"Preservation method of this container"),
118
        required=False,
119
    )
120
121
    security_seal_intact = schema.Bool(
122
        title=_("Security seal intact"),
123
        description=_(""),
124
        required=False,
125
    )
126
127
128
@implementer(ISampleContainer, ISampleContainerSchema, IDeactivable)
129
class SampleContainer(Container):
130
    """Sample container type
131
    """
132
    # Catalogs where this type will be catalogued
133
    _catalogs = [SETUP_CATALOG]
134
135
    security = ClassSecurityInfo()
136
137
    @security.protected(permissions.View)
138
    def getContainerType(self):
139
        accessor = self.accessor("containertype")
140
        return accessor(self)
141
142
    @security.protected(permissions.ModifyPortalContent)
143
    def setContainerType(self, value):
144
        mutator = self.mutator("containertype")
145
        return mutator(self, value)
146
147
    @security.protected(permissions.View)
148
    def getCapacity(self):
149
        accessor = self.accessor("capacity")
150
        value = accessor(self) or ""
151
        return value.encode("utf-8")
152
153
    @security.protected(permissions.ModifyPortalContent)
154
    def setCapacity(self, value):
155
        mutator = self.mutator("capacity")
156
        return mutator(self, api.safe_unicode(value))
157
158
    @security.protected(permissions.View)
159
    def getPrePreserved(self):
160
        accessor = self.accessor("pre_preserved")
161
        return accessor(self)
162
163
    @security.protected(permissions.ModifyPortalContent)
164
    def setPrePreserved(self, value):
165
        mutator = self.mutator("pre_preserved")
166
        return mutator(self, value)
167
168
    @security.protected(permissions.View)
169
    def getPreservation(self):
170
        accessor = self.accessor("preservation")
171
        return accessor(self)
172
173
    @security.protected(permissions.ModifyPortalContent)
174
    def setPreservation(self, value):
175
        mutator = self.mutator("preservation")
176
        return mutator(self, value)
177
178
    @security.protected(permissions.View)
179
    def getSecuritySealIntact(self):
180
        accessor = self.accessor("security_seal_intact")
181
        return accessor(self)
182
183
    @security.protected(permissions.ModifyPortalContent)
184
    def setSecuritySealIntact(self, value):
185
        mutator = self.mutator("security_seal_intact")
186
        return mutator(self, bool(value))
187
188
    @security.private
189
    def get_containertype_query(self):
190
        """Return the query for the containertype field
191
        """
192
        return {
193
            "portal_type": "ContainerType",
194
            "is_active": True,
195
            "sort_on": "title",
196
            "sort_order": "ascending",
197
        }
198
199
    @security.private
200
    def get_preservation_query(self):
201
        """Return the query for the preservation field
202
        """
203
        return {
204
            "portal_type": "SamplePreservation",
205
            "is_active": True,
206
            "sort_on": "title",
207
            "sort_order": "ascending",
208
        }
209
210
    @security.private
211
    def get_default_columns(self):
212
        """Returns the default columns for the reference dropdown
213
        """
214
        return [
215
            {
216
                "name": "title",
217
                "width": "30",
218
                "align": "left",
219
                "label": _(u"Title"),
220
            }, {
221
                "name": "description",
222
                "width": "70",
223
                "align": "left",
224
                "label": _(u"Description"),
225
            },
226
        ]
227