Source code for mep.accounts.management.commands.export_events

'''
Manage command to export event data for use by others.

Generates a CSV and JSON file including details on every event in the
database with summary details and URIs for associated library member(s)
and book (for events linked to books).

'''

from collections import OrderedDict

from django.core.exceptions import ObjectDoesNotExist
from django.db.models.functions import Coalesce

from mep.accounts.models import Event
from mep.common.management.export import BaseExport
from mep.common.utils import absolutize_url


[docs]class Command(BaseExport): '''Export event data.''' help = __doc__ model = Event csv_fields = [ 'event_type', 'start_date', 'end_date', 'member_URIs', 'member_names', 'member_sort_names', # subscription specific 'subscription_price_paid', 'subscription_deposit', 'subscription_duration', 'subscription_duration_days', 'subscription_volumes', 'subscription_category', 'subscription_purchase_date', # reimbursement specific 'reimbursement_refund', # borrow specific 'borrow_status', # purchase specific 'purchase_price', # related book/item 'item_uri', 'item_title', 'item_volume', 'item_authors', 'item_year', 'item_notes', # footnote/citation 'source_citation', 'source_manifest', 'source_image' ]
[docs] def get_queryset(self): '''get event objects to be exported''' # Order events by date. Order on precision first so unknown dates # will be last, then sort by first known date of start/end. return Event.objects.all() \ .order_by(Coalesce('start_date_precision', 'end_date_precision'), Coalesce('start_date', 'end_date').asc(nulls_last=True))
[docs] def get_object_data(self, obj): '''Generate a dictionary of data to export for a single :class:`~mep.accounts.models.Event`''' event_type = obj.event_type data = OrderedDict([ # use event label instead of type for more detail on some generics ('event_type', obj.event_label), ('start_date', obj.partial_start_date or ''), ('end_date', obj.partial_end_date or ''), ('member', OrderedDict()), ]) member_info = self.member_info(obj) if member_info: data['member'] = member_info # variable to store footnote reference, if any footnote = None # subscription-specific data if event_type in ['Subscription', 'Supplement', 'Renewal']: data['subscription'] = self.subscription_info(obj) # reimbursement data elif event_type in 'Reimbursement' and obj.reimbursement.refund: data['reimbursement'] = { 'refund': '%s%.2f' % (obj.reimbursement.currency_symbol(), obj.reimbursement.refund) } # borrow data elif event_type == 'Borrow': data['borrow'] = { 'status': obj.borrow.get_item_status_display() } # purchase data elif event_type == 'Purchase' and obj.purchase.price: data['purchase'] = { 'price': '%s%.2f' % (obj.purchase.currency_symbol(), obj.purchase.price) } # footnote should always be attached to the base event footnote = obj.footnotes.first() item_info = self.item_info(obj) if item_info: data['item'] = item_info if footnote: data['source'] = self.source_info(footnote) return data
[docs] def member_info(self, event): '''Event about member(s) for the account associated with an event.''' members = event.account.persons.all() # return if no member attached if not members: return return OrderedDict([ ('URIs', [absolutize_url(m.get_absolute_url()) for m in members]), ('names', [m.name for m in members]), ('sort_names', [m.sort_name for m in members]) ])
[docs] def subscription_info(self, event): '''subscription details for an event''' # bail out if this event is not a subscription try: subs = event.subscription except ObjectDoesNotExist: return info = OrderedDict([ ('price_paid', '%s%.2f' % (subs.currency_symbol(), subs.price_paid or 0)), ('deposit', '%s%.2f' % (subs.currency_symbol(), subs.deposit or 0)) ]) if subs.duration: info['duration'] = subs.readable_duration() info['duration_days'] = subs.duration if subs.volumes: info['volumes'] = int(subs.volumes) if subs.category: info['category'] = subs.category.name if subs.purchase_date: info['purchase_date'] = subs.partial_purchase_date return info
[docs] def item_info(self, event): '''associated work details for an event''' if event.work: item_info = OrderedDict([ ('uri', absolutize_url(event.work.get_absolute_url())), ('title', event.work.title), ]) if event.edition: item_info['volume'] = event.edition.display_text() if event.work.authors: item_info['authors'] = [a.sort_name for a in event.work.authors] if event.work.year: item_info['year'] = event.work.year if event.work.public_notes: item_info['notes'] = event.work.public_notes return item_info
[docs] def source_info(self, footnote): '''source details from a footnote''' source_info = OrderedDict([ ('citation', footnote.bibliography.bibliographic_note) ]) if footnote.bibliography.manifest: source_info['manifest'] = footnote.bibliography.manifest.uri if footnote.image: # default iiif image source_info['image'] = str(footnote.image.image) return source_info