Passed
Pull Request — 2.x (#1960)
by Jordi
09:44 queued 03:35
created

senaite.core.schema.addressfield   A

Complexity

Total Complexity 12

Size/Duplication

Total Lines 96
Duplicated Lines 0 %

Importance

Changes 0
Metric Value
wmc 12
eloc 42
dl 0
loc 96
rs 10
c 0
b 0
f 0

6 Methods

Rating   Name   Duplication   Size   Complexity  
A AddressField._validate() 0 4 1
A AddressField.get_address_types() 0 10 3
A AddressField.get() 0 6 1
A AddressField.__init__() 0 6 2
A AddressField.set() 0 15 2
A AddressField.to_list() 0 8 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-2022 by it's authors.
19
# Some rights reserved, see README and LICENSE.
20
21
import six
22
23
from senaite.core.schema.fields import BaseField
24
from senaite.core.schema.interfaces import IAddressField
25
from zope.interface import implementer
26
from zope.schema import List
27
from zope.schema.interfaces import IFromUnicode
28
29
NAIVE_ADDRESS = "Address"
30
PHYSICAL_ADDRESS = "Physical Address"
31
POSTAL_ADDRESS = "Postal Address"
32
BILLING_ADDRESS = "Billing Address"
33
BUSINESS_ADDRESS = "Business Address"
34
OTHER_ADDRESS = "Other Address"
35
36
37
@implementer(IAddressField, IFromUnicode)
38
class AddressField(List, BaseField):
39
    """A field that handles a single or multiple physical addresses
40
    """
41
42
    def __init__(self, address_types=None, **kw):
43
        if address_types is None:
44
            # Single address
45
            address_types = (NAIVE_ADDRESS,)
46
        self.address_types = address_types
47
        super(AddressField, self).__init__(**kw)
48
49
    def get_address_types(self):
50
        """Returns a tuple with the types of address handled by this field
51
        (e.g. address, postal-address, etc.)
52
        """
53
        address_types = self.address_types
54
        if not address_types:
55
            address_types = ()
56
        elif isinstance(address_types, six.string_types):
57
            address_types = (address_types, )
58
        return address_types
59
60
    def to_list(self, value, filter_empty=True):
61
        """Ensure the value is a list
62
        """
63
        if not isinstance(value, list):
64
            value = [value]
65
        if filter_empty:
66
            value = filter(None, value)
67
        return value
68
69
    def set(self, object, value):
70
        """Set an address record or records
71
        :param object: the instance of the field
72
        :param value: dict with address information or list of dicts
73
        :type value: list/tuple/dict
74
        """
75
        # Value is a list of dicts
76
        value = self.to_list(value)
77
78
        # Bail out non-supported address types
79
        address_types = self.get_address_types()
80
        value = filter(lambda ad: ad["type"] in address_types, value)
81
82
        # Set the value
83
        super(AddressField, self).set(object, value)
84
85
    def get(self, object):
86
        """Returns the address records
87
        :param object: the instance of this field
88
        :returns: list of dicts with address information for each address type
89
        """
90
        return super(AddressField, self).get(object) or []
91
92
    def _validate(self, value):
93
        """Validator called on form submit
94
        """
95
        super(AddressField, self)._validate(value)
96