Passed
Push — master ( 043018...55c541 )
by Ramon
03:52
created

bika.lims.content.samplepoint.SamplePoints()   A

Complexity

Conditions 4

Size

Total Lines 21
Code Lines 20

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 20
dl 0
loc 21
rs 9.4
c 0
b 0
f 0
cc 4
nop 4
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
import sys
22
23
from AccessControl import ClassSecurityInfo
24
from Products.ATContentTypes.lib.historyaware import HistoryAwareMixin
25
from Products.Archetypes.public import BaseContent
26
from Products.Archetypes.public import BooleanField
27
from Products.Archetypes.public import BooleanWidget
28
from Products.Archetypes.public import FileWidget
29
from Products.Archetypes.public import ReferenceField
30
from Products.Archetypes.public import Schema
31
from Products.Archetypes.public import StringField
32
from Products.Archetypes.public import StringWidget
33
from Products.Archetypes.public import registerType
34
from Products.CMFCore.utils import getToolByName
35
from Products.CMFPlone.utils import safe_unicode
36
from plone.app.blob.field import FileField as BlobFileField
37
from zope.interface import implements
38
39
from bika.lims import bikaMessageFactory as _
40
from bika.lims.browser.fields import CoordinateField
41
from bika.lims.browser.fields import DurationField
42
from bika.lims.browser.widgets import CoordinateWidget
43
from bika.lims.browser.widgets import DurationWidget
44
from bika.lims.browser.widgets.referencewidget import \
45
    ReferenceWidget as BikaReferenceWidget
46
from bika.lims.config import PROJECTNAME
47
from bika.lims.content.bikaschema import BikaSchema
48
from bika.lims.content.clientawaremixin import ClientAwareMixin
49
from bika.lims.content.sampletype import SampleTypeAwareMixin
50
from bika.lims.interfaces import IDeactivable
51
52
schema = BikaSchema.copy() + Schema((
53
    CoordinateField(
54
        'Latitude',
55
        schemata='Location',
56
        widget=CoordinateWidget(
57
            label=_("Latitude"),
58
            description=_("Enter the Sample Point's latitude in degrees 0-90, minutes 0-59, seconds 0-59 and N/S indicator"),
59
        ),
60
    ),
61
62
    CoordinateField(
63
        'Longitude',
64
        schemata='Location',
65
        widget=CoordinateWidget(
66
            label=_("Longitude"),
67
            description=_("Enter the Sample Point's longitude in degrees 0-180, minutes 0-59, seconds 0-59 and E/W indicator"),
68
        ),
69
    ),
70
71
    StringField(
72
        'Elevation',
73
        schemata='Location',
74
        widget=StringWidget(
75
            label=_("Elevation"),
76
            description=_("The height or depth at which the sample has to be taken"),
77
        ),
78
    ),
79
80
    DurationField(
81
        'SamplingFrequency',
82
        vocabulary_display_path_bound=sys.maxint,
83
        widget=DurationWidget(
84
            label=_("Sampling Frequency"),
85
            description=_("If a sample is taken periodically at this sample point, enter frequency here, e.g. weekly"),
86
        ),
87
    ),
88
89
    ReferenceField(
90
        'SampleTypes',
91
        required=0,
92
        multiValued=1,
93
        allowed_types=('SampleType',),
94
        relationship='SamplePointSampleType',
95
        widget=BikaReferenceWidget(
96
            label=_("Sample Types"),
97
            description=_("The list of sample types that can be collected "
98
                          "at this sample point.  If no sample types are "
99
                          "selected, then all sample types are available."),
100
            catalog_name='bika_setup_catalog',
101
            base_query={"is_active": True,
102
                        "sort_on": "sortable_title",
103
                        "sort_order": "ascending"},
104
            showOn=True,
105
        ),
106
    ),
107
108
    BooleanField(
109
        'Composite',
110
        default=False,
111
        widget=BooleanWidget(
112
            label=_("Composite"),
113
            description=_(
114
                "Check this box if the samples taken at this point are 'composite' "
115
                "and put together from more than one sub sample, e.g. several surface "
116
                "samples from a dam mixed together to be a representative sample for the dam. "
117
                "The default, unchecked, indicates 'grab' samples"),
118
        ),
119
    ),
120
121
    BlobFileField(
122
        'AttachmentFile',
123
        widget=FileWidget(
124
            label=_("Attachment"),
125
        ),
126
    ),
127
))
128
129
schema['description'].widget.visible = True
130
schema['description'].schemata = 'default'
131
132
133
class SamplePoint(BaseContent, HistoryAwareMixin, ClientAwareMixin,
134
                  SampleTypeAwareMixin):
135
    implements(IDeactivable)
136
    security = ClassSecurityInfo()
137
    displayContentsTab = False
138
    schema = schema
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable schema does not seem to be defined.
Loading history...
139
140
    _at_rename_after_creation = True
141
142
    def _renameAfterCreation(self, check_auto_id=False):
143
        from bika.lims.idserver import renameAfterCreation
144
        renameAfterCreation(self)
145
146
    def Title(self):
147
        return safe_unicode(self.getField('title').get(self)).encode('utf-8')
148
149 View Code Duplication
    def setSampleTypes(self, value, **kw):
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
150
        """ For the moment, we're manually trimming the sampletype<>samplepoint
151
            relation to be equal on both sides, here.
152
            It's done strangely, because it may be required to behave strangely.
153
        """
154
        bsc = getToolByName(self, 'bika_setup_catalog')
155
        # convert value to objects
156
        if value and type(value) == str:
157
            value = [bsc(UID=value)[0].getObject(), ]
158
        elif value and type(value) in (list, tuple) and type(value[0]) == str:
159
            value = [bsc(UID=uid)[0].getObject() for uid in value if uid]
160
        if not type(value) in (list, tuple):
161
            value = [value, ]
162
        # Find all SampleTypes that were removed
163
        existing = self.Schema()['SampleTypes'].get(self)
164
        removed = existing and [s for s in existing if s not in value] or []
165
        added = value and [s for s in value if s not in existing] or []
166
        ret = self.Schema()['SampleTypes'].set(self, value)
167
168
        # finally be sure that we aren't trying to set None values here.
169
        removed = [x for x in removed if x]
170
        added = [x for x in added if x]
171
172
        for st in removed:
173
            samplepoints = st.getSamplePoints()
174
            if self in samplepoints:
175
                samplepoints.remove(self)
176
                st.setSamplePoints(samplepoints)
177
178
        for st in added:
179
            st.setSamplePoints(list(st.getSamplePoints()) + [self, ])
180
181
        return ret
182
183
184
registerType(SamplePoint, PROJECTNAME)
185