## $Id: export.py 12168 2014-12-08 06:17:30Z henrik $ ## ## Copyright (C) 2014 Uli Fouquet & Henrik Bettermann ## This program is free software; you can redistribute it and/or modify ## it under the terms of the GNU General Public License as published by ## the Free Software Foundation; either version 2 of the License, or ## (at your option) any later version. ## ## This program is distributed in the hope that it will be useful, ## but WITHOUT ANY WARRANTY; without even the implied warranty of ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ## GNU General Public License for more details. ## ## You should have received a copy of the GNU General Public License ## along with this program; if not, write to the Free Software ## Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA ## """Exporters for customer related stuff. """ import os import grok from datetime import datetime from zope.component import getUtility from waeup.ikoba.interfaces import ( IExtFileStore, IFileStoreNameChooser) from waeup.ikoba.interfaces import MessageFactory as _ from waeup.ikoba.customers.catalog import CustomersQuery from waeup.ikoba.customers.interfaces import ( ICustomer, ICSVCustomerExporter, ICustomerDocument, ISampleContract) from waeup.ikoba.utils.batching import ExporterBase from waeup.ikoba.utils.helpers import iface_names, to_timezone #: A tuple containing all exporter names referring to customers or #: subobjects thereof. EXPORTER_NAMES = ('customers', 'customerdocuments') def get_customers(site, cust_filter=CustomersQuery()): """Get all customers registered in catalog in `site`. """ return cust_filter.query() def get_documents(customers): """Get all documents of `customers`. """ documents = [] for customer in customers: for document in customer.get('documents', {}).values(): documents.append(document) return documents def get_contracts(customers): """Get all contracts of `customers`. """ contracts = [] for customer in customers: for contract in customer.get('contracts', {}).values(): contracts.append(contract) return contracts class CustomerExporterBase(ExporterBase): """Exporter for customers or related objects. This is a baseclass. """ grok.baseclass() grok.implements(ICSVCustomerExporter) grok.provides(ICSVCustomerExporter) def filter_func(self, x, **kw): return x def get_filtered(self, site, **kw): """Get customers from a catalog filtered by keywords. customers_catalog is the default catalog. The keys must be valid catalog index names. Returns a simple empty list, a list with `Customer` objects or a catalog result set with `Customer` objects. .. seealso:: `waeup.ikoba.customers.catalog.CustomersCatalog` """ # Pass only given keywords to create FilteredCatalogQuery objects. # This way we avoid # trouble with `None` value ambivalences and queries are also # faster (normally less indexes to ask). Drawback is, that # developers must look into catalog to see what keywords are # valid. query = CustomersQuery(**kw) return query.query() def export(self, values, filepath=None): """Export `values`, an iterable, as CSV file. If `filepath` is ``None``, a raw string with CSV data is returned. """ writer, outfile = self.get_csv_writer(filepath) for value in values: self.write_item(value, writer) return self.close_outfile(filepath, outfile) def export_all(self, site, filepath=None): """Export customers into filepath as CSV data. If `filepath` is ``None``, a raw string with CSV data is returned. """ return self.export(self.filter_func(get_customers(site)), filepath) def export_customer(self, customer, filepath=None): return self.export(self.filter_func([customer]), filepath=filepath) def export_filtered(self, site, filepath=None, **kw): """Export items denoted by `kw`. If `filepath` is ``None``, a raw string with CSV data should be returned. """ data = self.get_filtered(site, **kw) return self.export(self.filter_func(data, **kw), filepath=filepath) class CustomerExporter(grok.GlobalUtility, CustomerExporterBase): """Exporter for Customers. """ grok.name('customers') #: Fieldnames considered by this exporter fields = tuple(sorted(iface_names(ICustomer))) + ( 'password', 'state', 'history',) #: The title under which this exporter will be displayed title = _(u'Customers') def mangle_value(self, value, name, context=None): if name == 'history': value = value.messages if name == 'phone' and value is not None: # Append hash '#' to phone numbers to circumvent # unwanted excel automatic value = str('%s#' % value) return super( CustomerExporter, self).mangle_value( value, name, context=context) class CustomerDocumentExporter(grok.GlobalUtility, CustomerExporterBase): """Exporter for CustomerDocument instances. """ grok.name('customerdocuments') #: Fieldnames considered by this exporter fields = tuple( sorted(iface_names( ICustomerDocument, exclude_attribs=False, omit=['is_editable_by_customer', 'is_editable_by_manager', 'is_verifiable', 'translated_state', 'formatted_transition_date', 'translated_class_name', 'connected_files', # Could be used to export file URLs ]))) #: The title under which this exporter will be displayed title = _(u'Customer Documents') def filter_func(self, x, **kw): return get_documents(x) def mangle_value(self, value, name, context=None): if name == 'history': value = value.messages return super( CustomerDocumentExporter, self).mangle_value( value, name, context=context) class ContractExporter(grok.GlobalUtility, CustomerExporterBase): """Exporter for Contract instances. """ grok.name('contracts') #: Fieldnames considered by this exporter fields = tuple( sorted(iface_names( ISampleContract, exclude_attribs=False, omit=['translated_state', 'formatted_transition_date', 'translated_class_name', 'is_editable_by_customer', 'is_approvable']))) #: The title under which this exporter will be displayed title = _(u'Contracts') def filter_func(self, x, **kw): return get_contracts(x) def mangle_value(self, value, name, context=None): if name == 'history': value = value.messages if name.endswith('_object'): mangled_value = getattr(value, 'document_id', None) if mangled_value: return mangled_value mangled_value = getattr(value, 'product_id', None) if mangled_value: return mangled_value return super( ContractExporter, self).mangle_value( value, name, context=context)