Passed
Push — master ( 70be41...e1228c )
by Ramon
11:12
created

AttachAnalyses.__init__()   A

Complexity

Conditions 1

Size

Total Lines 3
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 3
dl 0
loc 3
rs 10
c 0
b 0
f 0
cc 1
nop 3
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-2019 by it's authors.
19
# Some rights reserved, see README and LICENSE.
20
21
import json
22
from operator import itemgetter
23
24
import plone
25
import plone.protect
26
from Products.Archetypes.config import REFERENCE_CATALOG
27
from Products.CMFCore.utils import getToolByName
28
29
from bika.lims.workflow import getCurrentState
30
31
32
class AttachAnalyses():
33
    """ In attachment add form,
34
        the analyses dropdown combo uses this as source.
35
        Form is handled by the worksheet ManageResults code
36
    """
37
    def __init__(self, context, request):
38
        self.context = context
39
        self.request = request
40
        
41
    def __call__(self):
42
        plone.protect.CheckAuthenticator(self.request)
43
        searchTerm = 'searchTerm' in self.request and self.request['searchTerm'].lower() or ''
44
        page = self.request['page']
45
        nr_rows = self.request['rows']
46
        sord = self.request['sord']
47
        sidx = self.request['sidx']
48
        attachable_states = ('assigned', 'unassigned', 'to_be_verified')
49
        analysis_to_slot = {}
50
        for s in self.context.getLayout():
51
            analysis_to_slot[s['analysis_uid']] = int(s['position'])
52
        analyses = list(self.context.getAnalyses(full_objects=True))
53
        # Duplicates belong to the worksheet, so we must add them individually
54
        for i in self.context.objectValues():
55
            if i.portal_type == 'DuplicateAnalysis':
56
                analyses.append(i)
57
        rows = []
58
        for analysis in analyses:
59
            review_state = getCurrentState(analysis)
60
            if review_state not in attachable_states:
61
                continue
62
            parent = analysis.getParentTitle()
63
            rows.append({'analysis_uid': analysis.UID(),
64
                         'slot': analysis_to_slot[analysis.UID()],
65
                         'service': analysis.Title(),
66
                         'parent': parent,
67
                         'type': analysis.portal_type})
68
69
        # if there's a searchTerm supplied, restrict rows to those
70
        # who contain at least one field that starts with the chars from
71
        # searchTerm.
72
        if searchTerm:
73
            orig_rows = rows
74
            rows = []
75
            for row in orig_rows:
76
                matches = [v for v in row.values()
77
                           if str(v).lower().startswith(searchTerm)]
78
                if matches:
79
                    rows.append(row)
80
81
        rows = sorted(rows, cmp=lambda x, y: cmp(x, y), key=itemgetter(sidx and sidx or 'slot'))
82
        if sord == 'desc':
83
            rows.reverse()
84
        pages = len(rows) / int(nr_rows)
85
        pages += divmod(len(rows), int(nr_rows))[1] and 1 or 0
86
        start = (int(page)-1) * int(nr_rows)
87
        end = int(page) * int(nr_rows)
88
        ret = {'page': page,
89
               'total': pages,
90
               'records': len(rows),
91
               'rows': rows[start:end]}
92
93
        return json.dumps(ret)
94
95
96
class SetAnalyst():
97
    """The Analysis dropdown sets worksheet.Analyst immediately
98
    """
99
100
    def __init__(self, context, request):
101
        self.context = context
102
        self.request = request
103
104
    def __call__(self):
105
        rc = getToolByName(self.context, REFERENCE_CATALOG)
106
        mtool = getToolByName(self, 'portal_membership')
107
        plone.protect.CheckAuthenticator(self.request)
108
        plone.protect.PostOnly(self.request)
109
        value = self.request.get('value', '')
110
        if not value:
111
            return
112
        if not mtool.getMemberById(value):
113
            return
114
        self.context.setAnalyst(value)
115
116
117
class SetInstrument():
118
    """The Instrument dropdown sets worksheet.Instrument immediately
119
    """
120
121
    def __init__(self, context, request):
122
        self.context = context
123
        self.request = request
124
125
    def __call__(self):
126
        rc = getToolByName(self.context, REFERENCE_CATALOG)
127
        plone.protect.CheckAuthenticator(self.request)
128
        plone.protect.PostOnly(self.request)
129
        value = self.request.get('value', '')
130
        if not value:
131
            raise Exception("Invalid instrument")
132
        instrument = rc.lookupObject(value)
133
        if not instrument:
134
            raise Exception("Unable to lookup instrument")
135
        self.context.setInstrument(instrument)
136