Passed
Push — master ( cd3c58...e71d5a )
by Jordi
04:38
created

ServicesView.folderitem()   C

Complexity

Conditions 10

Size

Total Lines 62
Code Lines 41

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 41
dl 0
loc 62
rs 5.9999
c 0
b 0
f 0
cc 10
nop 4

How to fix   Long Method    Complexity   

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:

Complexity

Complex classes like bika.lims.browser.widgets.serviceswidget.ServicesView.folderitem() often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

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
import collections
9
10
from AccessControl import ClassSecurityInfo
11
from bika.lims import api
12
from bika.lims import bikaMessageFactory as _
13
from bika.lims.browser.bika_listing import BikaListingView
14
from bika.lims.utils import get_image
15
from bika.lims.utils import get_link
16
from plone.memoize import view
17
from Products.Archetypes.Registry import registerWidget
18
from Products.Archetypes.Widget import TypesWidget
19
20
21
class ServicesView(BikaListingView):
22
    """Listing table to display Analyses Services
23
    """
24
25
    def __init__(self, context, request):
26
        super(ServicesView, self).__init__(context, request)
27
28
        self.catalog = "bika_setup_catalog"
29
        self.contentFilter = {
30
            "portal_type": "AnalysisService",
31
            "sort_on": "sortable_title",
32
            "sort_order": "ascending",
33
        }
34
35
        if context.getRestrictToMethod():
36
            method_uid = context.getMethodUID()
37
            if method_uid:
38
                self.contentFilter.update({
39
                    "getAvailableMethodUIDs": method_uid
40
                })
41
42
        self.context_actions = {}
43
44
        # selected services UIDs
45
        self.selected_services_uids = self.get_assigned_services_uids()
46
47
        self.show_sort_column = False
48
        self.show_column_toggles = False
49
        self.show_select_column = True
50
        self.show_select_all_checkbox = False
51
        self.pagesize = 999999
52
        self.allow_edit = True
53
        # remove the searchbox
54
        self.show_search = False
55
        # omit the outer form
56
        self.omit_form = True
57
        # no need to fetch the allowed transitions on select
58
        self.fetch_transitions_on_select = False
59
60
        # Categories
61
        if self.show_categories_enabled():
62
            self.categories = []
63
            self.show_categories = True
64
            self.expand_all_categories = False
65
            self.category_index = "getCategoryTitle"
66
67
        self.columns = collections.OrderedDict((
68
            ("Title", {
69
                "title": _("Service")}),
70
            ("Keyword", {
71
                "title": _("Keyword"),
72
                "index": "getKeyword"}),
73
            ("Methods", {
74
                "title": _("Methods")}),
75
            ("Calculation", {
76
                "title": _("Calculation")}),
77
        ))
78
79
        self.review_states = [
80
            {
81
                "id": "default",
82
                "title": _("All"),
83
                "contentFilter": {"inactive_state": "active"},
84
                "transitions": [{"id": "disallow-all-possible-transitions"}],
85
                "columns": self.columns.keys(),
86
            }
87
        ]
88
89
    def update(self):
90
        """Update hook
91
        """
92
        super(ServicesView, self).update()
93
94
    @view.memoize
95
    def show_categories_enabled(self):
96
        """Check in the setup if categories are enabled
97
        """
98
        return self.context.bika_setup.getCategoriseAnalysisServices()
99
100
    @view.memoize
101
    def get_assigned_services(self):
102
        """Return the assigned services
103
        """
104
        return self.context.getService()
105
106
    @view.memoize
107
    def get_assigned_services_uids(self):
108
        """Return the UIDs of the assigned services
109
        """
110
        return map(api.get_uid, self.get_assigned_services())
111
112
    def folderitems(self):
113
        """TODO: Refactor to non-classic mode
114
        """
115
        items = super(ServicesView, self).folderitems()
116
        self.categories.sort()
117
        return items
118
119
    def folderitem(self, obj, item, index):
120
        """Service triggered each time an item is iterated in folderitems.
121
122
        The use of this service prevents the extra-loops in child objects.
123
124
        :obj: the instance of the class to be foldered
125
        :item: dict containing the properties of the object to be used by
126
            the template
127
        :index: current index of the item
128
        """
129
        # ensure we have an object and not a brain
130
        obj = api.get_object(obj)
131
        uid = api.get_uid(obj)
132
        url = api.get_url(obj)
133
        title = api.get_title(obj)
134
135
        # get the category
136
        if self.show_categories_enabled():
137
            category = obj.getCategoryTitle()
138
            if category not in self.categories:
139
                self.categories.append(category)
140
            item["category"] = category
141
142
        item["replace"]["Title"] = get_link(url, value=title)
143
        item["selected"] = False
144
        item["selected"] = uid in self.selected_services_uids
145
146
        # Add methods
147
        methods = obj.getMethods()
148
        if methods:
149
            links = map(
150
                lambda m: get_link(
151
                    m.absolute_url(), value=m.Title(), css_class="link"),
152
                methods)
153
            item["replace"]["Methods"] = ", ".join(links)
154
        else:
155
            item["methods"] = ""
156
157
        calculation = obj.getCalculation()
158
        if calculation:
159
            title = calculation.Title()
160
            url = calculation.absolute_url()
161
            item["Calculation"] = title
162
            item["replace"]["Calculation"] = get_link(url, value=title)
163
        else:
164
            item["Calculation"] = ""
165
166
        # Icons
167
        after_icons = ""
168
        if obj.getAccredited():
169
            after_icons += get_image(
170
                "accredited.png", title=_("Accredited"))
171
        if obj.getAttachmentOption() == "r":
172
            after_icons += get_image(
173
                "attach_reqd.png", title=_("Attachment required"))
174
        if obj.getAttachmentOption() == "n":
175
            after_icons += get_image(
176
                "attach_no.png", title=_("Attachment not permitted"))
177
        if after_icons:
178
            item["after"]["Title"] = after_icons
179
180
        return item
181
182
183
class ServicesWidget(TypesWidget):
184
    """Analyses Services Widget
185
    """
186
    _properties = TypesWidget._properties.copy()
187
    _properties.update({
188
        "macro": "bika_widgets/serviceswidget",
189
    })
190
191
    security = ClassSecurityInfo()
192
193
    security.declarePublic("process_form")
194
195
    def process_form(self, instance, field, form, empty_marker=None,
196
                     emptyReturnsMarker=False, validating=True):
197
        """Return UIDs of the selected services
198
        """
199
        service_uids = form.get("uids", [])
200
        return service_uids, {}
201
202
    security.declarePublic("Services")
203
204
    def Services(self, field, show_select_column=True):
205
        """Render Analyses Services Listing Table
206
        """
207
208
        instance = getattr(self, "instance", field.aq_parent)
209
        table = api.get_view("table_analyses_services",
210
                             context=instance,
211
                             request=self.REQUEST)
212
        # Call listing hooks
213
        table.update()
214
        table.before_render()
215
        return table.ajax_contents_table()
216
217
218
registerWidget(ServicesWidget,
219
               title="Analysis Services",
220
               description=("Categorised AnalysisService selector."),)
221