Passed
Push — 2.x ( a93928...ced756 )
by Jordi
08:02 queued 01:02
created

bika.lims.vocabularies.getTemplates()   B

Complexity

Conditions 6

Size

Total Lines 59
Code Lines 25

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 25
dl 0
loc 59
rs 8.3466
c 0
b 0
f 0
cc 6
nop 3

How to fix   Long Method   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

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-2025 by it's authors.
19
# Some rights reserved, see README and LICENSE.
20
21
from bika.lims import bikaMessageFactory as _
22
from bika.lims.api import is_active
23
from senaite.core.i18n import translate as t
24
from bika.lims.interfaces import IDisplayListVocabulary
25
from bika.lims.utils import to_utf8
26
from Products.Archetypes.public import DisplayList
27
from Products.CMFCore.utils import getToolByName
28
from zope.interface import implements
29
from senaite.core.p3compat import cmp
30
from zope.schema.interfaces import IVocabularyFactory
31
from zope.schema.vocabulary import SimpleTerm
32
from zope.schema.vocabulary import SimpleVocabulary
33
from zope.site.hooks import getSite
34
35
36
class CatalogVocabulary(object):
37
    """Make vocabulary from catalog query.
38
39
    """
40
    implements(IDisplayListVocabulary)
41
42
    catalog = 'uid_catalog'
43
    contentFilter = {}
44
    key = 'UID'
45
    value = 'Title'
46
47
    def __init__(self, context, key=None, value=None, contentFilter=None):
48
        self.context = context
49
        self.key = key if key else self.key
50
        self.value = value if value else self.value
51
        self.contentFilter = \
52
            contentFilter if contentFilter else self.contentFilter
53
54
    def __call__(self, **kwargs):
55
        site = getSite()
56
        catalog = getToolByName(site, self.catalog)
57
        allow_blank = False
58
        if 'allow_blank' in kwargs:
59
            allow_blank = kwargs.get('allow_blank')
60
            del (kwargs['allow_blank'])
61
62
        self.contentFilter.update(**kwargs)
63
64
        # If a secondary deactivation/cancellation workflow is anbled,
65
        # Be sure and select only active objects, unless other instructions
66
        # are explicitly specified:
67
        if "is_active" not in self.contentFilter:
68
            self.contentFilter["is_active"] = True
69
70
        brains = catalog(self.contentFilter)
71
72
        items = [('', '')] if allow_blank else []
73
        for brain in brains:
74
            if self.key in brain and self.value in brain:
75
                key = getattr(brain, self.key)
76
                value = getattr(brain, self.value)
77
            else:
78
                obj = brain.getObjec()
79
                key = obj[self.key]
80
                key = callable(key) and key() or key
81
                value = obj[self.value]
82
                value = callable(value) and value() or value
83
            items.append((key, t(value)))
84
85
        return DisplayList(items)
86
87
88
class BikaContentVocabulary(object):
89
    """Vocabulary factory for Bika Setup objects.  We find them by listing
90
    folder contents directly.
91
    """
92
    implements(IVocabularyFactory)
93
94
    def __init__(self, folders, portal_types):
95
        self.folders = isinstance(folders, (tuple, list)) and \
96
                       folders or [folders, ]
97
        self.portal_types = isinstance(portal_types, (tuple, list)) and \
98
                            portal_types or [portal_types, ]
99
100
    def __call__(self, context):
101
        site = getSite()
102
        items = []
103
        for folder in self.folders:
104
            folder = site.restrictedTraverse(folder)
105
            for portal_type in self.portal_types:
106
                objects = list(folder.objectValues(portal_type))
107
                objects = filter(is_active, objects)
108
                if not objects:
109
                    continue
110
                objects.sort(lambda x, y: cmp(x.Title().lower(),
111
                                              y.Title().lower()))
112
                xitems = [(t(item.Title()), item.Title()) for item in objects]
113
                xitems = [SimpleTerm(i[1], i[1], i[0]) for i in xitems]
114
                items += xitems
115
        return SimpleVocabulary(items)
116
117
118
class BikaCatalogTypesVocabulary(object):
119
    """Vocabulary factory for really user friendly portal types,
120
    filtered to return only types listed as indexed by senaite_catalog
121
    """
122
    implements(IVocabularyFactory)
123
124
    def __call__(self, context):
125
        translate = context.translate
126
        types = (
127
            ('AnalysisRequest', translate(to_utf8(_('Sample')))),
128
            ('Batch', translate(to_utf8(_('Batch')))),
129
            # TODO Remove in >v1.3.0
130
            ('Sample', translate(to_utf8(_('Sample')))),
131
            ('ReferenceSample', translate(to_utf8(_('Reference Sample')))),
132
            ('Worksheet', translate(to_utf8(_('Worksheet'))))
133
        )
134
        items = [SimpleTerm(i[0], i[0], i[1]) for i in types]
135
        return SimpleVocabulary(items)
136
137
138
BikaCatalogTypesVocabularyFactory = BikaCatalogTypesVocabulary()
139
140
141
class AnalysisCategoryVocabulary(BikaContentVocabulary):
142
    """" AnalysisCategories
143
144
    >>> portal = layer['portal']
145
146
    >>> from plone.app.testing import TEST_USER_NAME
147
    >>> from plone.app.testing import TEST_USER_ID
148
    >>> from plone.app.testing import setRoles
149
    >>> from plone.app.testing import login
150
    >>> login(portal, TEST_USER_NAME)
151
    >>> setRoles(portal, TEST_USER_ID, ['Manager',])
152
153
    >>> from zope.component import queryUtility
154
    >>> name = 'bika.lims.vocabularies.AnalysisCategories'
155
    >>> util = queryUtility(IVocabularyFactory, name)
156
    >>> folder = portal.bika_setup.bika_analysiscategories
157
    >>> objects = folder.objectValues()
158
    >>> len(objects)
159
    3
160
161
    >>> source = util(portal)
162
    >>> source
163
    <zope.schema.vocabulary.SimpleVocabulary object at ...>
164
165
    >>> 'Water Chemistry' in source.by_token
166
    True
167
    """
168
169
    def __init__(self):
170
        BikaContentVocabulary.__init__(self,
171
                                       ['bika_setup/bika_analysiscategories', ],
172
                                       ['AnalysisCategory', ])
173
174
175
AnalysisCategoryVocabularyFactory = AnalysisCategoryVocabulary()
176
177
178
class AnalysisProfileVocabulary(BikaContentVocabulary):
179
    def __init__(self):
180
        BikaContentVocabulary.__init__(self,
181
                                       ['bika_setup/bika_analysisprofiles', ],
182
                                       ['AnalysisProfile', ])
183
184
185
AnalysisProfileVocabularyFactory = AnalysisProfileVocabulary()
186
187
188
class StorageLocationVocabulary(BikaContentVocabulary):
189
    def __init__(self):
190
        BikaContentVocabulary.__init__(self,
191
                                       ['bika_setup/bika_storagelocations', ],
192
                                       ['StorageLocation', ])
193
194
195
StorageLocationVocabularyFactory = StorageLocationVocabulary()
196
197
198
class AnalysisServiceVocabulary(BikaContentVocabulary):
199
    def __init__(self):
200
        BikaContentVocabulary.__init__(self,
201
                                       ['bika_setup/bika_analysisservices', ],
202
                                       ['AnalysisService', ])
203
204
205
AnalysisServiceVocabularyFactory = AnalysisServiceVocabulary()
206
207
208
class ClientVocabulary(BikaContentVocabulary):
209
    def __init__(self):
210
        BikaContentVocabulary.__init__(self,
211
                                       ['clients', ],
212
                                       ['Client', ])
213
214
215
ClientVocabularyFactory = ClientVocabulary()
216
217
218
class UserVocabulary(object):
219
    """ Present a vocabulary containing users in the specified
220
    list of roles
221
222
    >>> from zope.component import queryUtility
223
224
    >>> portal = layer['portal']
225
    >>> name = 'bika.lims.vocabularies.Users'
226
    >>> util = queryUtility(IVocabularyFactory, name)
227
228
    >>> tool = portal.portal_registration
229
    >>> tool.addMember('user1', 'user1',
230
    ...     properties = {
231
    ...         'username': 'user1',
232
    ...         'email': '[email protected]',
233
    ...         'fullname': 'user1'}
234
    ... )
235
    <MemberData at /plone/portal_memberdata/user1 used for /plone/acl_users>
236
237
    >>> source = util(portal)
238
    >>> source
239
    <zope.schema.vocabulary.SimpleVocabulary object at ...>
240
241
    >>> 'test_user_1_' in source.by_value
242
    True
243
    >>> 'user1' in source.by_value
244
    True
245
    """
246
    implements(IVocabularyFactory)
247
248
    def __init__(self, roles=[]):
249
        self.roles = roles if isinstance(roles, (tuple, list)) else [roles, ]
250
251
    def __call__(self, context):
252
        site = getSite()
253
        mtool = getToolByName(site, 'portal_membership')
254
        users = mtool.searchForMembers(roles=self.roles)
255
        items = [(item.getProperty('fullname'), item.getId())
256
                 for item in users]
257
        items.sort(lambda x, y: cmp(x[0].lower(), y[0].lower()))
258
        items = [SimpleTerm(i[1], i[1], i[0]) for i in items]
259
        return SimpleVocabulary(items)
260
261
262
UserVocabularyFactory = UserVocabulary()
263
264
ClientVocabularyFactory = ClientVocabulary()
265
266
267
class ClientContactVocabulary(object):
268
    """ Present Client Contacts
269
270
    >>> from zope.component import queryUtility
271
272
    >>> portal = layer['portal']
273
    >>> name = 'bika.lims.vocabularies.ClientContacts'
274
    >>> util = queryUtility(IVocabularyFactory, name)
275
276
    >>> from plone.app.testing import TEST_USER_NAME
277
    >>> from plone.app.testing import TEST_USER_ID
278
    >>> from plone.app.testing import setRoles
279
    >>> from plone.app.testing import login
280
    >>> login(portal, TEST_USER_NAME)
281
    >>> setRoles(portal, TEST_USER_ID, ['Manager',])
282
283
    >>> portal.clients.invokeFactory('Client', id='client1')
284
    'client1'
285
    >>> client1 = portal.clients.client1
286
    >>> client1.processForm()
287
    >>> client1.invokeFactory('Contact', id='contact1')
288
    'contact1'
289
    >>> contact1 = client1.contact1
290
    >>> contact1.processForm()
291
    >>> contact1.edit(Firstname='Contact', Surname='One')
292
    >>> contact1.reindexObject()
293
294
    >>> source = util(portal)
295
    >>> source
296
    <zope.schema.vocabulary.SimpleVocabulary object at ...>
297
298
    >>> 'Contact One' in source.by_value
299
    True
300
    """
301
    implements(IVocabularyFactory)
302
303
    def __call__(self, context):
304
        site = getSite()
305
        items = []
306
        for client in site.clients.objectValues('Client'):
307
            objects = list(client.objectValues('Contact'))
308
            objects.sort(lambda x, y: cmp(x.getFullname().lower(),
309
                                          y.getFullname().lower()))
310
            xitems = [(to_utf8(item.getFullname()), item.getFullname())
311
                      for item in objects]
312
            xitems = [SimpleTerm(i[1], i[1], i[0]) for i in xitems]
313
            items += xitems
314
        return SimpleVocabulary(items)
315
316
317
ClientContactVocabularyFactory = ClientContactVocabulary()
318
319
320
class AnalystVocabulary(UserVocabulary):
321
    def __init__(self):
322
        UserVocabulary.__init__(self, roles=['Analyst', ])
323
324
325
AnalystVocabularyFactory = AnalystVocabulary()
326