Completed
Branch master (9edffc)
by Jordi
04:36
created

bika.lims.monkey.Widget   A

Complexity

Total Complexity 16

Size/Duplication

Total Lines 72
Duplicated Lines 0 %

Importance

Changes 0
Metric Value
wmc 16
eloc 49
dl 0
loc 72
rs 10
c 0
b 0
f 0

2 Functions

Rating   Name   Duplication   Size   Complexity  
B editableFields() 0 13 6
C isVisible() 0 37 10
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
from Products.CMFCore.utils import getToolByName
9
from bika.lims import logger
10
from bika.lims.interfaces import IATWidgetVisibility
11
from types import DictType
12
from plone import api
13
from Acquisition import aq_base
14
from zope.component import getAdapters
15
16
_marker = []
17
18
# Products.Archetypes.Schema.Schemata#editableFields
19
def editableFields(self, instance, visible_only=False):
20
    """Returns a list of editable fields for the given instance
21
    """
22
    ret = []
23
    portal = getToolByName(instance, 'portal_url').getPortalObject()
24
    for field in self.fields():
25
        if field.writeable(instance, debug=False) and    \
26
               (not visible_only or
27
                field.widget.isVisible(
28
                    instance, mode='edit', field=field) != 'invisible') and \
29
                field.widget.testCondition(instance.aq_parent, portal, instance):
30
            ret.append(field)
31
    return ret
32
33
34
# Products.Archetypes.Widget.TypesWidget#isVisible
35
def isVisible(self, instance, mode='view', default="visible", field=None):
36
    """decide if a field is visible in a given mode -> 'state'.
37
    """
38
    # Emulate Products.Archetypes.Widget.TypesWidget#isVisible first
39
    vis_dic = getattr(aq_base(self), 'visible', _marker)
40
    state = default
41
    if vis_dic is _marker:
42
        return state
43
    if type(vis_dic) is DictType:
44
        state = vis_dic.get(mode, state)
45
    elif not vis_dic:
46
        state = 'invisible'
47
    elif vis_dic < 0:
48
        state = 'hidden'
49
50
    # Our custom code starts here
51
    if not field:
52
        return state
53
54
    # Look for visibility from the adapters provided by IATWidgetVisibility
55
    adapters = sorted(getAdapters([instance], IATWidgetVisibility),
56
                      key=lambda adapter: getattr(adapter[1], "sort", 1000),
57
                      reverse=True)
58
    for adapter_name, adapter in adapters:
59
        if field.getName() not in getattr(adapter, "field_names", []):
60
            # Omit those adapters that are not suitable for this field
61
            continue
62
        adapter_state = adapter(instance, mode, field, state)
63
        adapter_name = adapter.__class__.__name__
64
        logger.info("IATWidgetVisibility rule {} for {}.{} ({}): {} -> {}"
65
            .format(adapter_name, instance.id, field.getName(), mode, state,
66
                    adapter_state))
67
        if adapter_state == state:
68
            continue
69
        return adapter_state
70
71
    return state
72