## $Id: export.py 12741 2015-03-12 05:29:43Z uli $ ## ## 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, ICustomerSampleDocument, ISampleContractProcess) from waeup.ikoba.utils.batching import ExporterBase from waeup.ikoba.utils.helpers import iface_names, to_timezone def get_customers(site, cust_filter=CustomersQuery()): """Get all customers registered in catalog in `site`. """ return cust_filter.query() def get_documents(customers, class_name): """Get all documents of `customers`. """ documents = [] for customer in customers: for document in customer.get('documents', {}).values(): if document.class_name == class_name: documents.append(document) return documents def get_contracts(customers, class_name): """Get all contracts of `customers`. """ contracts = [] for customer in customers: for contract in customer.get('contracts', {}).values(): if getattr(contract, 'class_name', None) == class_name: 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') iface = ICustomer #: The title under which this exporter will be displayed title = _(u'Customers') #: Fieldnames considered by this exporter @property def fields(self): return tuple(sorted(iface_names(self.iface))) + ( 'password', 'state', 'history',) 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 CustomerDocumentExporterBase(grok.GlobalUtility, CustomerExporterBase): """Exporter for Customer Document instances. This is a baseclass. """ grok.baseclass() iface = None class_name = None title = None #: Fieldnames considered by this exporter @property def fields(self): return tuple( sorted(iface_names( self.iface, 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 ]))) def filter_func(self, x, **kw): return get_documents(x, self.class_name) def mangle_value(self, value, name, context=None): if name == 'history': value = value.messages return super( CustomerDocumentExporterBase, self).mangle_value( value, name, context=context) class CustomerSampleDocumentExporter(CustomerDocumentExporterBase): """Exporter for CustomerSampleDocument instances. """ grok.name('customersampledocuments') iface = ICustomerSampleDocument class_name = 'CustomerSampleDocument' title = _(u'Customer Sample Documents') class ContractExporterBase(grok.GlobalUtility, CustomerExporterBase): """Exporter for Contract instances. This is a baseclass. """ grok.baseclass() iface = None class_name = None title = None #: Fieldnames considered by this exporter @property def fields(self): return tuple( sorted(iface_names( self.iface, exclude_attribs=False, omit=['translated_state', 'formatted_transition_date', 'translated_class_name', 'is_editable', 'is_approvable', 'customer']))) def filter_func(self, x, **kw): return get_contracts(x, self.class_name) 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 if name == 'product_options' and value is not None: value = [eval(entry.to_string()) for entry in value] return super( ContractExporterBase, self).mangle_value( value, name, context=context) class SampleContractExporter(ContractExporterBase): """Exporter for sample contracts. """ grok.name('samplecontracts') iface = ISampleContractProcess class_name = 'SampleContract' title = _(u'Customer Sample Contracts')