Passed
Push — 2.x ( 041ff6...87c3c9 )
by Jordi
08:54
created

LabContact.getRawDefaultDepartment()   A

Complexity

Conditions 1

Size

Total Lines 12
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 4
dl 0
loc 12
rs 10
c 0
b 0
f 0
cc 1
nop 1
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-2021 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 bikaMessageFactory as _
24
from bika.lims.browser.fields import UIDReferenceField
25
from bika.lims.catalog.bikasetup_catalog import SETUP_CATALOG
26
from bika.lims.config import PROJECTNAME
27
from bika.lims.content.contact import Contact
28
from bika.lims.content.person import Person
29
from bika.lims.interfaces import IDeactivable
30
from bika.lims.interfaces import IHaveDepartment
31
from bika.lims.interfaces import ILabContact
32
from Products.Archetypes import atapi
33
from Products.Archetypes.Field import ImageField
34
from Products.Archetypes.Field import ImageWidget
35
from Products.Archetypes.public import registerType
36
from Products.CMFPlone.utils import safe_unicode
37
from Products.Archetypes.public import SelectionWidget
38
from senaite.core.browser.widgets.referencewidget import ReferenceWidget
39
from zope.interface import implements
40
41
schema = Person.schema.copy() + atapi.Schema((
42
43
    ImageField(
44
        "Signature",
45
        widget=ImageWidget(
46
            label=_("Signature"),
47
            description=_(
48
                "Upload a scanned signature to be used on printed "
49
                "analysis results reports. Ideal size is 250 pixels "
50
                "wide by 150 high"),
51
        ),
52
    ),
53
54
    UIDReferenceField(
55
        "Departments",
56
        multiValued=1,
57
        allowed_types=("Department",),
58
        widget=ReferenceWidget(
59
            label=_(
60
                "label_labcontact_departments",
61
                default="Departments"),
62
            description=_(
63
                "description_labcontact_departments",
64
                default="Assigned laboratory departments"),
65
            catalog=SETUP_CATALOG,
66
            query={
67
                "is_active": True,
68
                "sort_on": "sortable_title",
69
                "sort_order": "ascending"
70
            },
71
        ),
72
    ),
73
74
    # NOTE: This field is dynamically modified by
75
    #       `senaite.core.browser.form.adapters.labcontact.EditForm`
76
    #
77
    #       Please leave it as a `SelectionWidget` to allow selection only from
78
    #       the dependent selected departments field!
79
    UIDReferenceField(
80
        "DefaultDepartment",
81
        allowed_types=("Department",),
82
        vocabulary="default_department_vocabulary",
83
        accessor="getRawDefaultDepartment",
84
        widget=SelectionWidget(
85
            format="select",
86
            label=_(
87
                "label_labcontact_default_department",
88
                default="Default Department"),
89
            description=_(
90
                "description_labcontact_default_department",
91
                default="Select a default department for this contact "
92
                        "from one of the selected departments."),
93
        ),
94
    ),
95
))
96
97
schema["JobTitle"].schemata = "default"
98
# Don't make title required - it will be computed from the Person's Fullname
99
schema["title"].required = 0
100
schema["title"].widget.visible = False
101
schema["Department"].required = 0
102
schema["Department"].widget.visible = False
103
104
105
class LabContact(Contact):
106
    """A Lab Contact, which can be linked to a System User
107
    """
108
    implements(ILabContact, IHaveDepartment, IDeactivable)
109
110
    schema = schema
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable schema does not seem to be defined.
Loading history...
111
    displayContentsTab = False
112
    security = ClassSecurityInfo()
113
    _at_rename_after_creation = True
114
115
    def _renameAfterCreation(self, check_auto_id=False):
116
        from senaite.core.idserver import renameAfterCreation
117
        renameAfterCreation(self)
118
119
    def Title(self):
120
        """Return the contact's Fullname as title
121
        """
122
        return safe_unicode(self.getFullname()).encode("utf-8")
123
124
    @security.public
125
    def getDepartment(self):
126
        """Required by IHaveDepartment. Returns the list of departments this
127
        laboratory contact is assigned to plus the default department
128
        """
129
        departments = self.getDepartments() + [self.getDefaultDepartment()]
130
        return filter(None, list(set(departments)))
131
132
    @security.public
133
    def getDefaultDepartment(self):
134
        """Returns the assigned default department
135
136
        :returns: Department object
137
        """
138
        return self.getField("DefaultDepartment").get(self)
139
140
    @security.public
141
    def getRawDefaultDepartment(self):
142
        """Returns the UID of the assigned default department
143
144
        NOTE: This is the default accessor of the `DefaultDepartment` schema
145
        field and needed for the selection widget to render the selected value
146
        properly in _view_ mode.
147
148
        :returns: Default Department UID
149
        """
150
        field = self.getField("DefaultDepartment")
151
        return field.getRaw(self)
152
153
    def default_department_vocabulary(self):
154
        """Returns only selected departments
155
        """
156
        # Getting the assigned departments
157
        deps = self.getDepartments()
158
        items = []
159
        for d in deps:
160
            items.append((api.get_uid(d), api.get_title(d)))
161
        return api.to_display_list(items, sort_by="value", allow_empty=True)
162
163
    def hasUser(self):
164
        """Check if contact has user
165
        """
166
        username = self.getUsername()
167
        if not username:
168
            return False
169
        user = api.get_user(username)
170
        return user is not None
171
172
    def addDepartment(self, dep):
173
        """Adds a department
174
175
        :param dep: UID or department object
176
        :returns: True when the department was added
177
        """
178
        if api.is_uid(dep):
179
            dep = api.get_object_by_uid(dep)
180
        deps = self.getDepartments()
181
        if dep not in deps:
182
            return False
183
        deps.append(dep)
184
        self.setDepartments(deps)
185
        return True
186
187
    def removeDepartment(self, dep):
188
        """Removes a department
189
190
        :param dep: UID or department object
191
        :returns: True when the department was removed
192
        """
193
        if api.is_uid(dep):
194
            dep = api.get_object_by_uid(dep)
195
        deps = self.getDepartments()
196
        if dep not in deps:
197
            return False
198
        deps.remove(dep)
199
        self.setDepartments(deps)
200
        return True
201
202
203
registerType(LabContact, PROJECTNAME)
204