Passed
Push — 2.x ( 710010...e013a9 )
by Jordi
10:50 queued 05:13
created

senaite.core.browser.modals.sample   A

Complexity

Total Complexity 20

Size/Duplication

Total Lines 119
Duplicated Lines 0 %

Importance

Changes 0
Metric Value
wmc 20
eloc 66
dl 0
loc 119
rs 10
c 0
b 0
f 0

10 Methods

Rating   Name   Duplication   Size   Complexity  
B CreateWorksheetModal.get_analysis_categories() 0 20 6
A CreateWorksheetModal.create_worksheet_for() 0 24 4
A CreateWorksheetModal.get_category_info() 0 9 1
A CreateWorksheetModal.handle_submit() 0 13 2
A CreateWorksheetModal.__call__() 0 4 2
A CreateWorksheetModal.add_status_message() 0 4 1
A CreateWorksheetModal.__init__() 0 2 1
A CreateWorksheetModal.get_selected_samples() 0 6 1
A CreateWorksheetModal.worksheet_layout() 0 6 1
A CreateWorksheetModal.worksheet_folder() 0 6 1
1
# -*- coding: utf-8 -*-
2
3
from six import string_types
4
5
from bika.lims import api
6
from bika.lims import senaiteMessageFactory as _
7
from Products.Five.browser.pagetemplatefile import ViewPageTemplateFile
8
from senaite.core.browser.modals import Modal
9
10
11
class CreateWorksheetModal(Modal):
12
    """Modal form handler that allows to assign all analyses to a new worksheet
13
    """
14
    template = ViewPageTemplateFile("templates/create_worksheet.pt")
15
16
    def __init__(self, context, request):
17
        super(CreateWorksheetModal, self).__init__(context, request)
18
19
    def __call__(self):
20
        if self.request.form.get("submitted", False):
21
            return self.handle_submit(REQUEST=self.request)
22
        return self.template()
23
24
    def add_status_message(self, message, level="info"):
25
        """Set a portal status message
26
        """
27
        return self.context.plone_utils.addPortalMessage(message, level)
28
29
    def get_selected_samples(self):
30
        """Return selected samples
31
32
        :returns: selected Samples
33
        """
34
        return map(api.get_object, self.uids)
35
36
    def handle_submit(self, REQUEST=None):
37
        """Extract categories from request and create worksheet
38
        """
39
        categories = self.request.form.get("categories")
40
        if isinstance(categories, string_types):
41
            categories = [categories]
42
        # filter out non-UIDs
43
        categories = filter(api.is_uid, categories)
44
        worksheet = self.create_worksheet_for(self.uids, categories)
45
        self.add_status_message(
46
            _("Created worksheet %s" % api.get_id(worksheet)), level="info")
47
        # redirect to the new worksheet
48
        return api.get_url(worksheet)
49
50
    def create_worksheet_for(self, samples, categories):
51
        """Create a new worksheet
52
53
        The new worksheet contains the analyses of all samples which match the
54
        are in the given categories
55
56
        :param samples: Sample obejects or UIDs
57
        :param categories: Category objects or UIDs
58
        :returns: new created Workshett
59
        """
60
        samples = map(api.get_object, samples)
61
        categories = map(api.get_object, categories)
62
        analyses = []
63
        for sample in samples:
64
            for analysis in sample.getAnalyses(full_objects=True):
65
                if analysis.getCategory() not in categories:
66
                    continue
67
                analyses.append(analysis)
68
69
        # create the new worksheet
70
        ws = api.create(self.worksheet_folder, "Worksheet")
71
        ws.setResultsLayout(self.worksheet_layout)
72
        ws.addAnalyses(analyses)
73
        return ws
74
75
    @property
76
    def worksheet_folder(self):
77
        """Return the worksheet root folder
78
        """
79
        portal = api.get_portal()
80
        return portal.restrictedTraverse("worksheets")
81
82
    @property
83
    def worksheet_layout(self):
84
        """Return the configured workheet layout
85
        """
86
        setup = api.get_setup()
87
        return setup.getWorksheetLayout()
88
89
    def get_analysis_categories(self):
90
        """Return analysis categories of the selected samples
91
92
        :returns: List available categories for the selected samples
93
        """
94
        categories = []
95
        for sample in self.get_selected_samples():
96
            for analysis in sample.getAnalyses(full_objects=True):
97
                # only consider unassigned analyses
98
                if api.get_workflow_status_of(analysis) != "unassigned":
99
                    continue
100
                # get the category of the analysis
101
                category = analysis.getCategory()
102
                if category in categories:
103
                    continue
104
                categories.append(category)
105
106
        categories = list(map(self.get_category_info,
107
                          sorted(categories, key=lambda c: c.getSortKey())))
108
        return categories
109
110
    def get_category_info(self, category):
111
        """Extract category information for template
112
113
        :returns: Dictionary of category information for the page template
114
        """
115
        return {
116
            "title": api.get_title(category),
117
            "uid": api.get_uid(category),
118
            "obj": category,
119
        }
120