Passed
Push — 2.x ( 380493...9aebce )
by Jordi
06:51
created

senaite.core.datamanagers.content.analysisservice   A

Complexity

Total Complexity 14

Size/Duplication

Total Lines 115
Duplicated Lines 29.57 %

Importance

Changes 0
Metric Value
wmc 14
eloc 49
dl 34
loc 115
rs 10
c 0
b 0
f 0

6 Methods

Rating   Name   Duplication   Size   Complexity  
A AnalysisServiceDataManager.is_field_readable() 0 4 1
A AnalysisServiceDataManager.is_field_writeable() 0 6 2
A AnalysisServiceDataManager.get_field_by_name() 13 13 2
A AnalysisServiceDataManager.fields() 0 3 1
A AnalysisServiceDataManager.set() 0 28 4
A AnalysisServiceDataManager.get() 21 21 4

How to fix   Duplicated Code   

Duplicated Code

Duplicate code is one of the most pungent code smells. A rule that is often used is to re-structure code once it is duplicated in three or more places.

Common duplication problems, and corresponding solutions are:

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-2024 by it's authors.
19
# Some rights reserved, see README and LICENSE.
20
21
from AccessControl import Unauthorized
22
from bika.lims import api
23
from bika.lims.interfaces import IAnalysisService
24
from Products.Archetypes.utils import mapply
25
from senaite.core import logger
26
from senaite.core.datamanagers.base import DataManager
27
from zope.component import adapter
28
29
30
@adapter(IAnalysisService)
31
class AnalysisServiceDataManager(DataManager):
32
    """Data Manager for Analysis Services
33
    """
34
35
    @property
36
    def fields(self):
37
        return api.get_fields(self.context)
38
39
    def is_field_readable(self, field):
40
        """Checks if the field is readable
41
        """
42
        return field.checkPermission("get", self.context)
43
44
    def is_field_writeable(self, field, context=None):
45
        """Checks if the field is writeable
46
        """
47
        if context is None:
48
            context = self.context
49
        return field.checkPermission("set", context)
50
51 View Code Duplication
    def get_field_by_name(self, name):
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
52
        """Get the field by name
53
        """
54
        field = self.fields.get(name)
55
56
        # try to fetch the field w/o the `get` prefix
57
        # this might be the case is some listings
58
        if field is None:
59
            # ensure we do not have the field setter as column
60
            name = name.split("get", 1)[-1]
61
            field = self.fields.get(name)
62
63
        return field
64
65 View Code Duplication
    def get(self, name):
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
66
        """Get sample field
67
        """
68
        # get the schema field
69
        field = self.get_field_by_name(name)
70
71
        # check if the field exists
72
        if field is None:
73
            raise AttributeError("Field '{}' not found".format(name))
74
75
        # Check the permission of the field
76
        if not self.is_field_readable(field):
77
            raise Unauthorized("Field '{}' not readable!".format(name))
78
79
        # return the value with the field accessor
80
        if hasattr(field, "getAccessor"):
81
            accessor = field.getAccessor(self.context)
82
            return accessor()
83
        else:
84
            # Set the value on the field directly
85
            return field.get(self.context)
86
87
    def set(self, name, value):
88
        """Set sample field or analysis result
89
        """
90
        # set of updated objects
91
        updated_objects = set()
92
93
        # get the schema field
94
        field = self.get_field_by_name(name)
95
96
        if field is None:
97
            raise AttributeError("Field '{}' not found".format(name))
98
99
        # Check the permission of the field
100
        if not self.is_field_writeable(field):
101
            logger.error("Field '{}' not writeable!".format(name))
102
            return []
103
        # get the field mutator (works only for AT content types)
104
        if hasattr(field, "getMutator"):
105
            mutator = field.getMutator(self.context)
106
            mapply(mutator, value)
107
        else:
108
            # Set the value on the field directly
109
            field.set(self.context, value)
110
111
        updated_objects.add(self.context)
112
113
        # return a unified list of the updated objects
114
        return list(updated_objects)
115