source: main/waeup.kofa/trunk/src/waeup/kofa/applicants/export.py @ 16065

Last change on this file since 16065 was 16065, checked in by Henrik Bettermann, 5 years ago

Change variable name.

  • Property svn:keywords set to Id
File size: 12.0 KB
Line 
1## $Id: export.py 16065 2020-04-21 08:09:33Z henrik $
2##
3## Copyright (C) 2012 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 applicant-related stuff.
19"""
20import grok
21from zope.catalog.interfaces import ICatalog
22from zope.component import queryUtility
23from waeup.kofa.applicants.interfaces import (
24    IApplicantBaseData, IApplicantsContainer, IApplicantOnlinePayment,
25    IApplicantRefereeReport)
26from waeup.kofa.interfaces import ICSVExporter
27from waeup.kofa.interfaces import MessageFactory as _
28from waeup.kofa.utils.batching import ExporterBase
29from waeup.kofa.utils.helpers import iface_names
30
31class ApplicantsContainerExporter(grok.GlobalUtility, ExporterBase):
32    """The Applicants Container Exporter exports container data. It does not
33    export applicants (application records) inside the container.
34    """
35    grok.implements(ICSVExporter)
36    grok.name('applicantscontainers')
37
38    fields = tuple(sorted(iface_names(IApplicantsContainer)))
39    title = _(u'Applicants Containers')
40
41    def mangle_value(self, value, name, context=None):
42        return super(
43            ApplicantsContainerExporter, self).mangle_value(
44            value, name, context=context)
45
46    def export(self, containers, filepath=None):
47        """Export `containers`, an iterable, as CSV file.
48
49        If `filepath` is ``None``, a raw string with CSV data is returned.
50        """
51        writer, outfile = self.get_csv_writer(filepath)
52        for container in containers:
53            self.write_item(container, writer)
54        return self.close_outfile(filepath, outfile)
55
56    def export_all(self, site, filepath=None):
57        """Export applicantscontainer into filepath as CSV data.
58
59        If `filepath` is ``None``, a raw string with CSV data is returned.
60        """
61        writer, outfile = self.get_csv_writer(filepath)
62        containers = site.get('applicants', {})
63        return self.export(containers.values(), filepath)
64
65
66class ApplicantExporter(grok.GlobalUtility, ExporterBase):
67    """The Applicant Exporter exports application records (= applicants)
68    stored in the database. In contrast to the exporters in the academic
69    section this exporter does not iterate over the items of containers
70    but searches the :class:`ApplicantsCatalog` instead.
71
72    The exporter exports all applicants if started in the Data Center
73    which means in the context of the `DataCenter` object. The exporter can also
74    be started 'locally' which means in the context of an `ApplicantsContainer`
75    container. Then the :meth:`export_filtered()` instead of the
76    :meth:`export_all()` method is applied which searches for applicants
77    in the respective container.
78    """
79    grok.implements(ICSVExporter)
80    grok.name('applicants')
81
82    fields = tuple(sorted(iface_names(IApplicantBaseData))) + (
83        'password', 'state', 'history', 'container_code', 'application_number',
84        'display_fullname', 'application_date')
85    title = _(u'Applicants')
86
87    def mangle_value(self, value, name, context=None):
88        """The mangler determines the codes of the atributes `course1`,
89        `course2` and `course_admitted`. It furthermore prepares the
90        history messages and adds a hash symbol at the end of the phone number
91        to avoid annoying automatic number transformation by Excel or Calc.
92        """
93        if name.startswith('course') and value is not None:
94            value = value.code
95        #elif name == 'school_grades':
96        #    value = [eval(entry.to_string()) for entry in value]
97        elif name == 'history':
98            value = getattr(value, 'messages', None)
99        elif name == 'phone' and value is not None:
100            # Append hash '#' to phone numbers to circumvent
101            # unwanted excel automatic
102            value = str('%s#' % value)
103        elif name == 'container_code':
104            value = value.strip('+')
105        return super(
106            ApplicantExporter, self).mangle_value(
107            value, name, context=context)
108
109    def export(self, applicants, filepath=None):
110        """Export `applicants`, an iterable, as CSV file.
111        If `filepath` is ``None``, a raw string with CSV data is returned.
112        """
113        writer, outfile = self.get_csv_writer(filepath)
114        for applicant in applicants:
115            self.write_item(applicant, writer)
116        return self.close_outfile(filepath, outfile)
117
118    def export_all(self, site, filepath=None):
119        """Export all applicants into filepath as CSV data.
120        If `filepath` is ``None``, a raw string with CSV data is returned.
121        Only used records are being exported.
122        """
123        catalog = queryUtility(
124            ICatalog, context=site, name='applicants_catalog', default=None)
125        if catalog is None:
126            return self.export([], filepath)
127        applicants = catalog.searchResults(
128            # reg_num might not be set and then would not be found.
129            # We therefore search for applicant_id.
130            applicant_id=(None, None))
131        used = [value for value in applicants
132                if value.container_code.endswith('+')]
133        return self.export(used, filepath=filepath)
134
135    def export_filtered(self, site, filepath=None, **kw):
136        """Export filtered applicants in container denoted by keywords (`kw`).
137        If `filepath` is ``None``, a raw string with CSV data should
138        be returned. Only used records are being exported.
139        """
140        container = grok.getSite()['applicants'][kw['container']]
141        container_values = container.values()
142        used = [value for value in container_values
143                if value.container_code.endswith('+')]
144        return self.export(used, filepath=filepath)
145
146
147class ApplicantPaymentExporter(grok.GlobalUtility, ExporterBase):
148    """The Applicant Payment Exporter exports all payments made by applicants.
149    In other words, it exports payment tickets in state 'paid'. The exporter
150    searches :class:`ApplicantsCatalog` and iterates over all payment tickets
151    which are stored in an applicant (container).
152
153    The exporter exports all applicant payments if started in the Data Center
154    which means in the context of the `DataCenter` object. The exporter can also
155    be started 'locally' which means in the context of an
156    `ApplicantsContainer` container, see `ApplicantExporter` above.
157    """
158    grok.implements(ICSVExporter)
159    grok.name('applicantpayments')
160
161    fields = tuple(sorted(iface_names(
162        IApplicantOnlinePayment,
163        exclude_attribs=False,
164        omit=['display_item']))) + (
165              'applicant_id',
166              'reg_number',
167              'display_fullname',)
168    title = _(u'Applicant Payments')
169
170    def mangle_value(self, value, name, context=None):
171        """The mangler determines the applicant's id.
172        """
173        if name in ('applicant_id', 'reg_number',
174            'display_fullname',) and context is not None:
175            applicant = context.__parent__
176            value = getattr(applicant, name, None)
177        return super(
178            ApplicantPaymentExporter, self).mangle_value(
179            value, name, context=context)
180
181    def export(self, payments, filepath=None):
182        """
183        """
184        writer, outfile = self.get_csv_writer(filepath)
185        for payment in payments:
186            self.write_item(payment, writer)
187        return self.close_outfile(filepath, outfile)
188
189    def export_all(self, site, filepath=None):
190        """
191        """
192        catalog = queryUtility(
193            ICatalog, context=site, name='applicants_catalog', default=None)
194        if catalog is None:
195            return self.export([], filepath)
196        applicants = catalog.searchResults(
197            # reg_num might not be set and then would not be found.
198            # We therefore search for applicant_id.
199            applicant_id=(None, None))
200        used = [value for value in applicants
201                if value.container_code.endswith('+')]
202        payments = []
203        for applicant in used:
204            for payment in applicant.payments:
205                if payment.p_state == 'paid':
206                    payments.append(payment)
207        return self.export(payments, filepath=filepath)
208
209    def export_filtered(self, site, filepath=None, **kw):
210        """
211        """
212        container = grok.getSite()['applicants'][kw['container']]
213        container_values = container.values()
214        used = [value for value in container_values
215                if value.container_code.endswith('+')]
216        payments = []
217        for applicant in used:
218            for payment in applicant.payments:
219                if payment.p_state == 'paid':
220                    payments.append(payment)
221        return self.export(payments, filepath=filepath)
222
223class ApplicantRefereeReportExporter(grok.GlobalUtility, ExporterBase):
224    """The Applicant Referee Report Exporter exports all referee reports.
225    The exportersearches :class:`ApplicantsCatalog` and iterates over all
226    referee reports which are stored in an applicant (container).
227
228    The exporter exports all referee reports if started in the Data Center
229    which means in the context of the `DataCenter` object. The exporter can also
230    be started 'locally' which means in the context of an
231    `ApplicantsContainer` container, see `ApplicantExporter` above.
232    """
233    grok.implements(ICSVExporter)
234    grok.name('applicantrefereereports')
235
236    fields = tuple(sorted(iface_names(
237        IApplicantRefereeReport,
238        exclude_attribs=False,
239        omit=['display_item']))) + (
240              'applicant_id',
241              'reg_number',
242              'display_fullname',)
243    title = _(u'Applicant Referee Reports')
244
245    def mangle_value(self, value, name, context=None):
246        """The mangler determines the applicant's id.
247        """
248        if name in ('applicant_id', 'reg_number',
249            'display_fullname',) and context is not None:
250            applicant = context.__parent__
251            value = getattr(applicant, name, None)
252        return super(
253            ApplicantRefereeReportExporter, self).mangle_value(
254            value, name, context=context)
255
256    def export(self, refereereports, filepath=None):
257        """
258        """
259        writer, outfile = self.get_csv_writer(filepath)
260        for refereereport in refereereports:
261            self.write_item(refereereport, writer)
262        return self.close_outfile(filepath, outfile)
263
264    def export_all(self, site, filepath=None):
265        """
266        """
267        catalog = queryUtility(
268            ICatalog, context=site, name='applicants_catalog', default=None)
269        if catalog is None:
270            return self.export([], filepath)
271        applicants = catalog.searchResults(
272            # reg_num might not be set and then would not be found.
273            # We therefore search for applicant_id.
274            applicant_id=(None, None))
275        refereereports = []
276        for applicant in applicants:
277            for refereereport in applicant.refereereports:
278                refereereports.append(refereereport)
279            return self.export(refereereports, filepath=filepath)
280
281    def export_filtered(self, site, filepath=None, **kw):
282        """
283        """
284        container = grok.getSite()['applicants'][kw['container']]
285        container_values = container.values()
286        refereereports = []
287        for applicant in container_values:
288            for refereereport in applicant.refereereports:
289                refereereports.append(refereereport)
290            return self.export(refereereports, filepath=filepath)
291        return self.export(refereereports, filepath=filepath)
Note: See TracBrowser for help on using the repository browser.