Passed
Push — 2.x ( 829bc3...5135ed )
by Ramon
07:04 queued 01:19
created

Setup.getMaxNumberOfSamplesAdd()   A

Complexity

Conditions 1

Size

Total Lines 8
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 4
dl 0
loc 8
rs 10
c 0
b 0
f 0
cc 1
nop 1
1
# -*- coding: utf-8 -*-
2
3
from AccessControl import ClassSecurityInfo
4
from bika.lims import api
5
from plone.app.textfield import IRichTextValue
6
from plone.app.textfield.widget import RichTextFieldWidget  # TBD: port to core
7
from plone.autoform import directives
8
from plone.formwidget.namedfile.widget import NamedFileFieldWidget
9
from plone.supermodel import model
10
from Products.CMFCore import permissions
11
from Products.Five.browser.pagetemplatefile import ViewPageTemplateFile
12
from senaite.core.catalog import AUDITLOG_CATALOG
13
from senaite.core.content.base import Container
14
from senaite.core.interfaces import IHideActionsMenu
15
from senaite.core.interfaces import ISetup
16
from senaite.core.schema import RichTextField
17
from senaite.impress import senaiteMessageFactory as _
18
from zope import schema
19
from zope.interface import implementer
20
from zope.interface import provider
21
from zope.schema.interfaces import IContextAwareDefaultFactory
22
23
24
@provider(IContextAwareDefaultFactory)
25
def default_email_body_sample_publication(context):
26
    """Returns the default body text for publication emails
27
    """
28
    view = api.get_view("senaite_view", context=api.get_setup())
29
    if view is None:
30
        # Test fixture
31
        return u""
32
    tpl = ViewPageTemplateFile(
33
        "../browser/setup/templates/email_body_sample_publication.pt")
34
    return tpl(view)
35
36
37
class ISetupSchema(model.Schema):
38
    """Schema and marker interface
39
    """
40
41
    directives.widget("email_body_sample_publication", RichTextFieldWidget)
42
    email_body_sample_publication = RichTextField(
43
        title=_("title_senaitesetup_publication_email_text",
44
                default=u"Publication Email Text"),
45
        description=_(
46
            "description_senaitesetup_publication_email_text",
47
            default=u"Set the email body text to be used by default "
48
            "when sending out result reports to the selected recipients. "
49
            "You can use reserved keywords: "
50
            "$client_name, $recipients, $lab_name, $lab_address"),
51
        defaultFactory=default_email_body_sample_publication,
52
        required=False,
53
    )
54
55
    always_cc_responsibles_in_report_emails = schema.Bool(
56
        title=_(
57
            "title_senaitesetup_always_cc_responsibles_in_report_emails",
58
            default=u"Always send publication email to responsibles"),
59
        description=_(
60
            "description_senaitesetup_always_cc_responsibles_in_report_emails",
61
            default="When selected, the responsible persons of all involved "
62
            "lab departments will receive publication emails."
63
        ),
64
        default=True,
65
    )
66
67
    enable_global_auditlog = schema.Bool(
68
        title=_(u"Enable global Auditlog"),
69
        description=_(
70
            "The global Auditlog shows all modifications of the system. "
71
            "When enabled, all entities will be indexed in a separate "
72
            "catalog. This will increase the time when objects are "
73
            "created or modified."
74
        ),
75
        default=False,
76
    )
77
78
    # NOTE:
79
    # We use the `NamedFileFieldWidget` instead of `NamedImageFieldWidget`
80
    # by purpose! Using the latter rises this PIL error (appears only in log):
81
    # IOError: cannot identify image file <cStringIO.StringI object at ...>
82
    directives.widget("site_logo", NamedFileFieldWidget)
83
    site_logo = schema.Bytes(
84
        title=_(u"Site Logo"),
85
        description=_(u"This shows a custom logo on your SENAITE site."),
86
        required=False,
87
    )
88
89
    site_logo_css = schema.ASCII(
90
        title=_(u"Site Logo CSS"),
91
        description=_(
92
            u"Add custom CSS rules for the Logo, "
93
            u"e.g. height:15px; width:150px;"
94
        ),
95
        required=False,
96
    )
97
98
    immediate_results_entry = schema.Bool(
99
        title=_(u"Immediate results entry"),
100
        description=_(
101
            "description_senaitesetup_immediateresultsentry",
102
            default=u"Allow the user to directly enter results after sample "
103
            "creation, e.g. to enter field results immediately, or lab "
104
            "results, when the automatic sample reception is activated."
105
        ),
106
    )
107
108
    categorize_sample_analyses = schema.Bool(
109
        title=_("title_senaitesetup_categorizesampleanalyses",
110
                default=u"Categorize sample analyses"),
111
        description=_(
112
            "description_senaitesetup_categorizesampleanalyses",
113
            default=u"Group analyses by category for samples"
114
        ),
115
        default=False,
116
    )
117
118
    sample_analyses_required = schema.Bool(
119
        title=_("title_senaitesetup_sampleanalysesrequired",
120
                default=u"Require sample analyses"),
121
        description=_(
122
            "description_senaitesetup_sampleanalysesrequired",
123
            default=u"Analyses are required for sample registration"
124
        ),
125
        default=True,
126
    )
127
    max_number_of_samples_add = schema.Int(
128
        title=_(
129
            u"label_senaitesetup_maxnumberofsamplesadd",
130
            default=u"Maximum value for 'Number of samples' field on "
131
                    u"registration"
132
        ),
133
        description=_(
134
            u"description_senaitesetup_maxnumberofsamplesadd",
135
            default=u"Maximum number of samples that can be created in "
136
                    u"accordance with the value set for the field 'Number of "
137
                    u"samples' on the sample registration form"
138
        ),
139
        default=10
140
    )
141
142
    ###
143
    # Fieldsets
144
    ###
145
    model.fieldset(
146
        "samples",
147
        label=_("label_senaitesetup_fieldset_samples", default=u"Samples"),
148
        fields=[
149
            "max_number_of_samples_add",
150
        ]
151
    )
152
    model.fieldset(
153
        "analyses",
154
        label=_("label_senaitesetup_fieldset_analyses", default=u"Analyses"),
155
        fields=[
156
            "immediate_results_entry",
157
            "categorize_sample_analyses",
158
            "sample_analyses_required",
159
        ]
160
    )
161
162
    model.fieldset(
163
        "notifications",
164
        label=_(u"Notifications"),
165
        fields=[
166
            "email_body_sample_publication",
167
            "always_cc_responsibles_in_report_emails",
168
        ]
169
    )
170
171
    model.fieldset(
172
        "appearance",
173
        label=_(u"Appearance"),
174
        fields=[
175
            "site_logo",
176
            "site_logo_css",
177
        ]
178
    )
179
180
181
@implementer(ISetup, ISetupSchema, IHideActionsMenu)
182
class Setup(Container):
183
    """SENAITE Setup Folder
184
    """
185
    security = ClassSecurityInfo()
186
187
    @security.protected(permissions.View)
188
    def getEmailBodySamplePublication(self):
189
        """Returns the transformed email body text for publication emails
190
        """
191
        accessor = self.accessor("email_body_sample_publication")
192
        value = accessor(self)
193
        if IRichTextValue.providedBy(value):
194
            # Transforms the raw value to the output mimetype
195
            value = value.output_relative_to(self)
196
        if not value:
197
            # Always fallback to default value
198
            value = default_email_body_sample_publication(self)
199
        return value
200
201
    @security.protected(permissions.ModifyPortalContent)
202
    def setEmailBodySamplePublication(self, value):
203
        """Set email body text for publication emails
204
        """
205
        mutator = self.mutator("email_body_sample_publication")
206
        return mutator(self, value)
207
208
    @security.protected(permissions.View)
209
    def getAlwaysCCResponsiblesInReportEmail(self):
210
        """Returns if responsibles should always receive publication emails
211
        """
212
        accessor = self.accessor("always_cc_responsibles_in_report_emails")
213
        return accessor(self)
214
215
    @security.protected(permissions.View)
216
    def setAlwaysCCResponsiblesInReportEmail(self, value):
217
        """Set if responsibles should always receive publication emails
218
        """
219
        mutator = self.mutator("always_cc_responsibles_in_report_emails")
220
        return mutator(self, value)
221
222
    @security.protected(permissions.View)
223
    def getEnableGlobalAuditlog(self):
224
        """Returns if the global Auditlog is enabled
225
        """
226
        accessor = self.accessor("enable_global_auditlog")
227
        return accessor(self)
228
229
    @security.protected(permissions.ModifyPortalContent)
230
    def setEnableGlobalAuditlog(self, value):
231
        """Enable/Disable global Auditlogging
232
        """
233
        if value is False:
234
            # clear the auditlog catalog
235
            catalog = api.get_tool(AUDITLOG_CATALOG)
236
            catalog.manage_catalogClear()
237
        mutator = self.mutator("enable_global_auditlog")
238
        return mutator(self, value)
239
240
    @security.protected(permissions.View)
241
    def getSiteLogo(self):
242
        """Returns the global site logo
243
        """
244
        accessor = self.accessor("site_logo")
245
        return accessor(self)
246
247
    @security.protected(permissions.ModifyPortalContent)
248
    def setSiteLogo(self, value):
249
        """Set the site logo
250
        """
251
        mutator = self.mutator("site_logo")
252
        return mutator(self, value)
253
254
    @security.protected(permissions.View)
255
    def getSiteLogoCSS(self):
256
        """Returns the global site logo
257
        """
258
        accessor = self.accessor("site_logo_css")
259
        return accessor(self)
260
261
    @security.protected(permissions.ModifyPortalContent)
262
    def setSiteLogoCSS(self, value):
263
        """Set the site logo
264
        """
265
        mutator = self.mutator("site_logo_css")
266
        return mutator(self, value)
267
268
    @security.protected(permissions.View)
269
    def getImmediateResultsEntry(self):
270
        """Returns if immediate results entry is enabled or not
271
        """
272
        accessor = self.accessor("immediate_results_entry")
273
        return accessor(self)
274
275
    @security.protected(permissions.ModifyPortalContent)
276
    def setImmediateResultsEntry(self, value):
277
        """Enable/Disable global Auditlogging
278
        """
279
        mutator = self.mutator("immediate_results_entry")
280
        return mutator(self, value)
281
282
    @security.protected(permissions.View)
283
    def getCategorizeSampleAnalyses(self):
284
        """Returns if analyses should be grouped by category for samples
285
        """
286
        accessor = self.accessor("categorize_sample_analyses")
287
        return accessor(self)
288
289
    @security.protected(permissions.ModifyPortalContent)
290
    def setCategorizeSampleAnalyses(self, value):
291
        """Enable/Disable grouping of analyses by category for samples
292
        """
293
        mutator = self.mutator("categorize_sample_analyses")
294
        return mutator(self, value)
295
296
    @security.protected(permissions.View)
297
    def getSampleAnalysesRequired(self):
298
        """Returns if analyses are required in sample add form
299
        """
300
        accessor = self.accessor("sample_analyses_required")
301
        return accessor(self)
302
303
    @security.protected(permissions.ModifyPortalContent)
304
    def setSampleAnalysesRequired(self, value):
305
        """Allow/Disallow to create samples without analyses
306
        """
307
        mutator = self.mutator("sample_analyses_required")
308
        return mutator(self, value)
309
310
    @security.protected(permissions.View)
311
    def getMaxNumberOfSamplesAdd(self):
312
        """Returns the maximum number of samples that can be created for each
313
        column in sample add form in accordance with the value set for the
314
        field 'Number of samples'
315
        """
316
        accessor = self.accessor("max_number_of_samples_add")
317
        return api.to_int(accessor(self))
318
319
    @security.protected(permissions.ModifyPortalContent)
320
    def setMaxNumberOfSamplesAdd(self, value):
321
        """Sets the maximum number of samples that can be created for each
322
        column in sample add form in accordance with the value set for the
323
        field 'Number of samples'
324
        """
325
        mutator = self.mutator("max_number_of_samples_add")
326
        return mutator(self, value)
327