source: main/waeup.ikoba/trunk/src/waeup/ikoba/customers/vocabularies.py @ 12098

Last change on this file since 12098 was 12098, checked in by Henrik Bettermann, 10 years ago

Renaming batch 2

  • Property svn:keywords set to Id
File size: 5.1 KB
Line 
1## $Id: vocabularies.py 12098 2014-11-30 21:00:30Z henrik $
2##
3## Copyright (C) 2014 Uli Fouquet & Henrik Bettermann
4## This program is free software; you can redistribute it and/or modify
5## it under the terms of the GNU General Public License as published by
6## the Free Software Foundation; either version 2 of the License, or
7## (at your option) any later version.
8##
9## This program is distributed in the hope that it will be useful,
10## but WITHOUT ANY WARRANTY; without even the implied warranty of
11## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12## GNU General Public License for more details.
13##
14## You should have received a copy of the GNU General Public License
15## along with this program; if not, write to the Free Software
16## Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17##
18"""Vocabularies and sources for the customer section.
19"""
20import grok
21from zope.component import getUtility, queryUtility
22from zope.catalog.interfaces import ICatalog
23from zope.interface import implements, directlyProvides
24from zope.schema.interfaces import ISource, IContextSourceBinder
25from zope.schema.interfaces import ValidationError
26from zc.sourcefactory.basic import BasicSourceFactory
27from zc.sourcefactory.contextual import BasicContextualSourceFactory
28from waeup.ikoba.interfaces import SimpleIkobaVocabulary
29from waeup.ikoba.interfaces import MessageFactory as _
30from waeup.ikoba.utils.helpers import get_sorted_preferred
31from waeup.ikoba.utils.countries import COUNTRIES
32from waeup.ikoba.sourcefactory import SmartBasicContextualSourceFactory
33
34
35#: a tuple of tuples (<COUNTRY-NAME>, <ISO-CODE>) with Nigeria first.
36COUNTRIES = get_sorted_preferred(COUNTRIES, ['NG'])
37nats_vocab = SimpleIkobaVocabulary(*COUNTRIES)
38
39
40class GenderSource(BasicSourceFactory):
41    """A gender source delivers basically a mapping
42       ``{'m': 'Male', 'f': 'Female'}``
43
44       Using a source, we make sure that the tokens (which are
45       stored/expected for instance from CSV files) are something one
46       can expect and not cryptic IntIDs.
47    """
48    def getValues(self):
49        return ['m', 'f']
50
51    def getToken(self, value):
52        return value[0].lower()
53
54    def getTitle(self, value):
55        if value == 'm':
56            return _('male')
57        if value == 'f':
58            return _('female')
59
60
61class RegNumNotInSource(ValidationError):
62    """Registration number exists already
63    """
64    # The docstring of ValidationErrors is used as error description
65    # by zope.formlib.
66    pass
67
68
69class RegNumberSource(object):
70    """A source that accepts any entry for a certain field if not used
71    already.
72
73    Using this kind of source means a way of setting an invariant.
74
75    We accept a value iff:
76    - the value cannot be found in catalog or
77    - the value can be found as part of some item but the bound item
78      is the context object itself.
79    """
80    implements(ISource)
81    cat_name = 'customers_catalog'
82    field_name = 'reg_number'
83    validation_error = RegNumNotInSource
84    comp_field = 'customer_id'
85
86    def __init__(self, context):
87        self.context = context
88        return
89
90    def __contains__(self, value):
91        """We accept all values not already given to other customers.
92        """
93        cat = queryUtility(ICatalog, self.cat_name)
94        if cat is None:
95            return True
96        kw = {self.field_name: (value, value)}
97        results = cat.searchResults(**kw)
98        for entry in results:
99            if not hasattr(self.context, self.comp_field):
100                # we have no context with comp_field (most probably
101                # while adding a new object, where the container is
102                # the context) which means that the value was given
103                # already to another object (as _something_ was found in
104                # the catalog with that value). Fail on first round.
105                raise self.validation_error(value)
106            if getattr(entry, self.comp_field) != getattr(
107                self.context, self.comp_field):
108                # An entry already given to another customer is not in our
109                # range of acceptable values.
110                raise self.validation_error(value)
111                #return False
112        return True
113
114
115def contextual_reg_num_source(context):
116    source = RegNumberSource(context)
117    return source
118
119directlyProvides(contextual_reg_num_source, IContextSourceBinder)
120
121
122class ConCatProductSource(SmartBasicContextualSourceFactory):
123    """An contract category product delivers all products
124    which belong to a certain contract_category.
125    """
126    def contains(self, context, value):
127        concat = getattr(context, 'contract_category', None)
128        if value.contract_category == concat:
129            return True
130        return False
131
132    def getValues(self, context):
133        concat = getattr(context, 'contract_category', None)
134        products = grok.getSite()['products'].values()
135        if not concat:
136            return products
137        resultlist = [
138            value for value in products if value.contract_category == concat]
139        return resultlist
140
141    def getToken(self, context, value):
142        return value.product_id
143
144    def getTitle(self, context, value):
145        return "%s - %s" % (value.product_id, value.title)
Note: See TracBrowser for help on using the repository browser.