source: main/waeup.ikoba/trunk/src/waeup/ikoba/customers/export.py @ 12166

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

We need to protect also the manage form page of documents. Officers are only allowed to edit documents in state created.

  • Property svn:keywords set to Id
File size: 7.2 KB
Line 
1## $Id: export.py 12166 2014-12-07 22:24:03Z 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"""Exporters for customer related stuff.
19"""
20import os
21import grok
22from datetime import datetime
23from zope.component import getUtility
24from waeup.ikoba.interfaces import (
25    IExtFileStore, IFileStoreNameChooser)
26from waeup.ikoba.interfaces import MessageFactory as _
27from waeup.ikoba.customers.catalog import CustomersQuery
28from waeup.ikoba.customers.interfaces import (
29    ICustomer, ICSVCustomerExporter, ICustomerDocument,
30    ISampleContract)
31from waeup.ikoba.utils.batching import ExporterBase
32from waeup.ikoba.utils.helpers import iface_names, to_timezone
33
34#: A tuple containing all exporter names referring to customers or
35#: subobjects thereof.
36EXPORTER_NAMES = ('customers', 'customerdocuments')
37
38
39def get_customers(site, cust_filter=CustomersQuery()):
40    """Get all customers registered in catalog in `site`.
41    """
42    return cust_filter.query()
43
44def get_documents(customers):
45    """Get all documents of `customers`.
46    """
47    documents = []
48    for customer in customers:
49        for document in customer.get('documents', {}).values():
50            documents.append(document)
51    return documents
52
53def get_contracts(customers):
54    """Get all contracts of `customers`.
55    """
56    contracts = []
57    for customer in customers:
58        for contract in customer.get('contracts', {}).values():
59            contracts.append(contract)
60    return contracts
61
62class CustomerExporterBase(ExporterBase):
63    """Exporter for customers or related objects.
64
65    This is a baseclass.
66    """
67    grok.baseclass()
68    grok.implements(ICSVCustomerExporter)
69    grok.provides(ICSVCustomerExporter)
70
71    def filter_func(self, x, **kw):
72        return x
73
74    def get_filtered(self, site, **kw):
75        """Get customers from a catalog filtered by keywords.
76
77        customers_catalog is the default catalog. The keys must be valid
78        catalog index names.
79        Returns a simple empty list, a list with `Customer`
80        objects or a catalog result set with `Customer`
81        objects.
82
83        .. seealso:: `waeup.ikoba.customers.catalog.CustomersCatalog`
84
85        """
86        # Pass only given keywords to create FilteredCatalogQuery objects.
87        # This way we avoid
88        # trouble with `None` value ambivalences and queries are also
89        # faster (normally less indexes to ask). Drawback is, that
90        # developers must look into catalog to see what keywords are
91        # valid.
92        query = CustomersQuery(**kw)
93        return query.query()
94
95    def export(self, values, filepath=None):
96        """Export `values`, an iterable, as CSV file.
97
98        If `filepath` is ``None``, a raw string with CSV data is returned.
99        """
100        writer, outfile = self.get_csv_writer(filepath)
101        for value in values:
102            self.write_item(value, writer)
103        return self.close_outfile(filepath, outfile)
104
105    def export_all(self, site, filepath=None):
106        """Export customers into filepath as CSV data.
107
108        If `filepath` is ``None``, a raw string with CSV data is returned.
109        """
110        return self.export(self.filter_func(get_customers(site)), filepath)
111
112    def export_customer(self, customer, filepath=None):
113        return self.export(self.filter_func([customer]), filepath=filepath)
114
115    def export_filtered(self, site, filepath=None, **kw):
116        """Export items denoted by `kw`.
117
118        If `filepath` is ``None``, a raw string with CSV data should
119        be returned.
120        """
121        data = self.get_filtered(site, **kw)
122        return self.export(self.filter_func(data, **kw), filepath=filepath)
123
124
125class CustomerExporter(grok.GlobalUtility, CustomerExporterBase):
126    """Exporter for Customers.
127    """
128    grok.name('customers')
129
130    #: Fieldnames considered by this exporter
131    fields = tuple(sorted(iface_names(ICustomer))) + (
132        'password', 'state', 'history',)
133
134    #: The title under which this exporter will be displayed
135    title = _(u'Customers')
136
137    def mangle_value(self, value, name, context=None):
138        if name == 'history':
139            value = value.messages
140        if name == 'phone' and value is not None:
141            # Append hash '#' to phone numbers to circumvent
142            # unwanted excel automatic
143            value = str('%s#' % value)
144        return super(
145            CustomerExporter, self).mangle_value(
146            value, name, context=context)
147
148
149class CustomerDocumentExporter(grok.GlobalUtility, CustomerExporterBase):
150    """Exporter for CustomerDocument instances.
151    """
152    grok.name('customerdocuments')
153
154    #: Fieldnames considered by this exporter
155    fields = tuple(
156        sorted(iface_names(
157            ICustomerDocument,
158            exclude_attribs=False,
159            omit=['is_editable_by_customer',
160                  'is_editable_by_manager',
161                  'translated_state',
162                  'formatted_transition_date',
163                  'translated_class_name',
164                  'connected_files',   # Could be used to export file URLs
165                  ])))
166
167    #: The title under which this exporter will be displayed
168    title = _(u'Customer Documents')
169
170    def filter_func(self, x, **kw):
171        return get_documents(x)
172
173    def mangle_value(self, value, name, context=None):
174
175        if name == 'history':
176            value = value.messages
177        return super(
178            CustomerDocumentExporter, self).mangle_value(
179            value, name, context=context)
180
181
182class ContractExporter(grok.GlobalUtility, CustomerExporterBase):
183    """Exporter for Contract instances.
184    """
185    grok.name('contracts')
186
187    #: Fieldnames considered by this exporter
188    fields = tuple(
189        sorted(iface_names(
190            ISampleContract,
191            exclude_attribs=False,
192            omit=['translated_state',
193                  'formatted_transition_date',
194                  'translated_class_name',
195                  'is_editable',
196                  'is_approvable'])))
197
198    #: The title under which this exporter will be displayed
199    title = _(u'Contracts')
200
201    def filter_func(self, x, **kw):
202        return get_contracts(x)
203
204    def mangle_value(self, value, name, context=None):
205
206        if name == 'history':
207            value = value.messages
208        if name.endswith('_object'):
209            mangled_value = getattr(value, 'document_id', None)
210            if mangled_value:
211                return mangled_value
212            mangled_value = getattr(value, 'product_id', None)
213            if mangled_value:
214                return mangled_value
215        return super(
216            ContractExporter, self).mangle_value(
217            value, name, context=context)
Note: See TracBrowser for help on using the repository browser.