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

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

Rename contract property attribute to be more in line with documents.

  • Property svn:keywords set to Id
File size: 7.2 KB
Line 
1## $Id: export.py 12167 2014-12-08 05:14:58Z 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_by_customer',
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.