Passed
Push — master ( 87984f...d34ace )
by Jordi
06:01 queued 01:26
created

LabContact.getDefaultDepartmentUID()   A

Complexity

Conditions 2

Size

Total Lines 14
Code Lines 6

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 6
dl 0
loc 14
rs 10
c 0
b 0
f 0
cc 2
nop 1
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 sys
9
10
from AccessControl import ClassSecurityInfo
11
from bika.lims import api
12
from bika.lims import bikaMessageFactory as _
13
from bika.lims.browser.fields import UIDReferenceField
14
from bika.lims.config import PROJECTNAME
15
from bika.lims.content.contact import Contact
16
from bika.lims.content.person import Person
17
from bika.lims.interfaces import IDeactivable
18
from bika.lims.interfaces import ILabContact
19
from Products.Archetypes import atapi
20
from Products.Archetypes.Field import ImageField
21
from Products.Archetypes.Field import ImageWidget
22
from Products.Archetypes.Field import ReferenceField
23
from Products.Archetypes.Field import ReferenceWidget
24
from Products.Archetypes.public import SelectionWidget
25
from Products.Archetypes.public import registerType
26
from Products.Archetypes.references import HoldingReference
27
from Products.CMFPlone.utils import safe_unicode
28
from zope.interface import implements
29
30
31
schema = Person.schema.copy() + atapi.Schema((
32
33
    ImageField(
34
        "Signature",
35
        widget=ImageWidget(
36
            label=_("Signature"),
37
            description=_(
38
                "Upload a scanned signature to be used on printed "
39
                "analysis results reports. Ideal size is 250 pixels "
40
                "wide by 150 high"),
41
        ),
42
    ),
43
44
    ReferenceField(
45
        "Departments",
46
        required=0,
47
        vocabulary_display_path_bound=sys.maxint,
48
        allowed_types=("Department",),
49
        relationship="LabContactDepartment",
50
        vocabulary="_departmentsVoc",
51
        referenceClass=HoldingReference,
52
        multiValued=1,
53
        widget=ReferenceWidget(
54
            checkbox_bound=0,
55
            label=_("Departments"),
56
            description=_("The laboratory departments"),
57
        ),
58
    ),
59
60
    UIDReferenceField(
61
        "DefaultDepartment",
62
        required=0,
63
        vocabulary_display_path_bound=sys.maxint,
64
        vocabulary="_defaultDepsVoc",
65
        accessor="getDefaultDepartmentUID",
66
        widget=SelectionWidget(
67
            visible=True,
68
            format="select",
69
            label=_("Default Department"),
70
            description=_("Default Department"),
71
        ),
72
    ),
73
))
74
75
schema["JobTitle"].schemata = "default"
76
# Don't make title required - it will be computed from the Person's Fullname
77
schema["title"].required = 0
78
schema["title"].widget.visible = False
79
schema["Department"].required = 0
80
schema["Department"].widget.visible = False
81
82
83
class LabContact(Contact):
84
    """A Lab Contact, which can be linked to a System User
85
    """
86
    implements(ILabContact, IDeactivable)
87
88
    schema = schema
89
    displayContentsTab = False
90
    security = ClassSecurityInfo()
91
    _at_rename_after_creation = True
92
93
    def _renameAfterCreation(self, check_auto_id=False):
94
        from bika.lims.idserver import renameAfterCreation
95
        renameAfterCreation(self)
96
97
    def Title(self):
98
        """Return the contact's Fullname as title
99
        """
100
        return safe_unicode(self.getFullname()).encode("utf-8")
101
102
    @security.public
103
    def getDefaultDepartment(self):
104
        """Returns the assigned default department
105
106
        :returns: Department object
107
        """
108
        return self.getField("DefaultDepartment").get(self)
109
110
    @security.public
111
    def getDefaultDepartmentUID(self):
112
        """Returns the UID of the assigned default department
113
114
        NOTE: This is the default accessor of the `DefaultDepartment` schema
115
        field and needed for the selection widget to render the selected value
116
        properly in _view_ mode.
117
118
        :returns: Default Department UID
119
        """
120
        department = self.getDefaultDepartment()
121
        if not department:
122
            return None
123
        return api.get_uid(department)
124
125
    def hasUser(self):
126
        """Check if contact has user
127
        """
128
        username = self.getUsername()
129
        if not username:
130
            return False
131
        user = api.get_user(username)
132
        return user is not None
133
134
    def _departmentsVoc(self):
135
        """Vocabulary of available departments
136
        """
137
        query = {
138
            "portal_type": "Department",
139
            "is_active": True
140
        }
141
        results = api.search(query, "bika_setup_catalog")
142
        items = map(lambda dept: (api.get_uid(dept), api.get_title(dept)),
143
                    results)
144
        dept_uids = map(api.get_uid, results)
145
        # Currently assigned departments
146
        depts = self.getDepartments()
147
        # If one department assigned to the Lab Contact is disabled, it will
148
        # be shown in the list until the department has been unassigned.
149
        for dept in depts:
150
            uid = api.get_uid(dept)
151
            if uid in dept_uids:
152
                continue
153
            items.append((uid, api.get_title(dept)))
154
155
        return api.to_display_list(items, sort_by="value", allow_empty=False)
156
157
    def _defaultDepsVoc(self):
158
        """Vocabulary of all departments
159
        """
160
        # Getting the assigned departments
161
        deps = self.getDepartments()
162
        items = []
163
        for d in deps:
164
            items.append((api.get_uid(d), api.get_title(d)))
165
        return api.to_display_list(items, sort_by="value", allow_empty=True)
166
167
    def addDepartment(self, dep):
168
        """Adds a department
169
170
        :param dep: UID or department object
171
        :returns: True when the department was added
172
        """
173
        if api.is_uid(dep):
174
            dep = api.get_object_by_uid(dep)
175
        deps = self.getDepartments()
176
        if dep not in deps:
177
            return False
178
        deps.append(dep)
179
        self.setDepartments(deps)
180
        return True
181
182
    def removeDepartment(self, dep):
183
        """Removes a department
184
185
        :param dep: UID or department object
186
        :returns: True when the department was removed
187
        """
188
        if api.is_uid(dep):
189
            dep = api.get_object_by_uid(dep)
190
        deps = self.getDepartments()
191
        if dep not in deps:
192
            return False
193
        deps.remove(dep)
194
        self.setDepartments(deps)
195
        return True
196
197
198
registerType(LabContact, PROJECTNAME)
199