class DataTableReturnsCustomerView(base.DataTableBaseView): model = Return columns = [ 'lodgement_number', 'licence.licence_type', 'lodgement_date', 'due_date', 'status', 'licence', 'action' ] order_columns = [ 'lodgement_number', ['licence.licence_type.short_name', 'licence.licence_type.name'], 'lodgement_date', 'due_date', 'status', '', '' ] columns_helpers = { 'lodgement_number': { 'render': lambda self, instance: instance.lodgement_number }, 'licence.licence_type': { 'render': lambda self, instance: instance.licence.licence_type.display_name, 'search': lambda self, search: base.build_field_query([ 'licence__licence_type__short_name', 'licence__licence_type__name', 'licence__licence_type__version' ], search) }, 'lodgement_date': { 'render': lambda self, instance: base.render_date(instance.lodgement_date) }, 'due_date': { 'render': lambda self, instance: base.render_date(instance.due_date) }, 'licence': { 'render': lambda self, instance: base.render_licence_number(instance.licence ), 'search': lambda self, search: DataTableReturnsCustomerView. _search_licence_number(search) }, 'action': { 'render': lambda self, instance: self._render_action(instance) }, 'status': { 'render': lambda self, instance: self._render_status(instance) } } @staticmethod def _render_action(instance): if instance.status == 'current': url = reverse('wl_returns:enter_return', args=(instance.pk, )) return '<a href="{0}">Enter Return</a>'.format(url) elif instance.status == 'draft': url = reverse('wl_returns:enter_return', args=(instance.pk, )) return '<a href="{0}">Edit Return</a>'.format(url) elif instance.status == 'amendment_required': url = reverse('wl_returns:enter_return', args=(instance.pk, )) return '<a href="{0}">Amend Return</a>'.format(url) else: url = reverse('wl_returns:view_return', args=(instance.pk, )) return '<a href="{0}">View Return (read-only)</a>'.format(url) @staticmethod def _render_status(instance): status = instance.status if status == 'current': if is_return_overdue(instance): return '<span class="label label-danger">Overdue</span>' elif is_return_due_soon(instance): return '<span class="label label-warning">Due soon</span>' else: return 'Current' else: suffix = ' (Nil)' if status == 'submitted' and instance.nil_return else '' return dict(Return.STATUS_CHOICES)[status] + suffix @staticmethod def _search_licence_number(search): # testing to see if search term contains no spaces and two hyphens, # meaning it's a lodgement number with a sequence if search and search.count(' ') == 0 and search.count('-') == 2: components = search.split('-') licence_number, licence_sequence = '-'.join( components[:2]), '-'.join(components[2:]) return Q(licence__licence_number__icontains=licence_number) & Q( licence__licence_sequence__icontains=licence_sequence) else: return Q(licence__licence_number__icontains=search) def get_initial_queryset(self): return Return.objects.filter( licence__holder=self.request.user).exclude(status='future')
class DataTableLicencesCustomerView(base.DataTableBaseView): model = WildlifeLicence columns = [ 'licence_number', 'licence_type', 'issue_date', 'start_date', 'end_date', 'licence', 'status', 'action' ] order_columns = [ 'licence_number', ['licence_type.short_name', 'licence_type.name'], 'issue_date', 'start_date', 'end_date', '', '' ] columns_helpers = dict( base.DataTableBaseView.columns_helpers.items(), **{ 'licence_number': { 'search': lambda self, search: DataTableLicencesCustomerView. _search_licence_number(search), 'render': lambda self, instance: base.render_licence_number(instance) }, 'issue_date': { 'render': lambda self, instance: base.render_date(instance.issue_date) }, 'start_date': { 'render': lambda self, instance: base.render_date(instance.start_date) }, 'end_date': { 'render': lambda self, instance: base.render_date(instance.end_date) }, 'licence': { 'render': lambda self, instance: base.render_licence_document(instance) }, 'status': { 'render': lambda self, instance: self._render_status(instance) }, 'action': { 'render': lambda self, instance: self._render_action(instance) } }) @staticmethod def _render_status(instance): try: application = Application.objects.get(licence=instance) replacing_application = Application.objects.get( previous_application=application) if replacing_application.licence is not None and replacing_application.licence.is_issued: if replacing_application.application_type == 'amendment': return 'Amended' else: return 'Renewed' except Application.DoesNotExist: pass if instance.end_date is not None: expiry_days = (instance.end_date - datetime.date.today()).days if instance.end_date < datetime.date.today(): return '<span class="label label-danger">Expired</span>' elif expiry_days <= 30 and instance.is_renewable: return '<span class="label label-warning">Due for renewal</span>' else: return 'Current' else: # should not happen message = "The licence ref:{ref} pk:{pk} has no end date!".format( ref=instance.reference, pk=instance.pk) logger.exception(Exception(message)) return 'Current' @staticmethod def _render_action(instance): try: application = Application.objects.get(licence=instance) replacing_application = Application.objects.get( previous_application=application) if replacing_application.licence is None or not replacing_application.licence.is_issued: if replacing_application.application_type == 'amendment': return 'Amendment Pending' else: return 'Renewal Pending' else: return 'N/A' except Application.DoesNotExist: pass renew_url = reverse('wl_applications:renew_licence', args=(instance.pk, )) amend_url = reverse('wl_applications:amend_licence', args=(instance.pk, )) if instance.end_date is not None: expiry_days = (instance.end_date - datetime.date.today()).days if instance.is_renewable: if 30 >= expiry_days > 0: return '<a href="{0}">Amend</a> / <a href="{1}">Renew</a>'.format( amend_url, renew_url) elif expiry_days <= 0: return '<a href="{0}">Renew</a>'.format(renew_url) if instance.end_date >= datetime.date.today(): return '<a href="{0}">Amend</a>'.format(amend_url) else: return 'N/A' else: # should not happen message = "The licence ref:{ref} pk:{pk} has no end date!".format( ref=instance.reference, pk=instance.pk) logger.exception(Exception(message)) return 'N/A' @staticmethod def _search_licence_number(search): # testing to see if search term contains no spaces and two hyphens, # meaning it's a lodgement number with a sequence if search and search.count(' ') == 0 and search.count('-') == 2: components = search.split('-') licence_number, licence_sequence = '-'.join( components[:2]), '-'.join(components[2:]) return Q(licence_number__icontains=licence_number) & Q( licence_sequence__icontains=licence_sequence) else: return Q(licence_number__icontains=search) def get_initial_queryset(self): # should only see the issued customer's licence return WildlifeLicence.objects.filter(holder=self.request.user).filter( licence_number__isnull=False)
class DataTableLicencesCustomerView(base.DataTableBaseView): model = WildlifeLicence columns = [ 'licence_number', 'licence_type', 'issue_date', 'start_date', 'end_date', 'licence', 'status', 'action'] order_columns = [ 'licence_number', ['licence_type.short_name', 'licence_type.name'], 'issue_date', 'start_date', 'end_date', '', ''] columns_helpers = dict(base.DataTableBaseView.columns_helpers.items(), **{ 'licence_number': { 'search': lambda self, search: DataTableLicencesCustomerView._search_licence_number(search), 'render': lambda self, instance: base.render_licence_number(instance) }, 'issue_date': { 'render': lambda self, instance: base.render_date(instance.issue_date) }, 'start_date': { 'render': lambda self, instance: base.render_date(instance.start_date) }, 'end_date': { 'render': lambda self, instance: base.render_date(instance.end_date) }, 'licence': { 'render': lambda self, instance: base.render_licence_document(instance) }, 'status': { 'render': lambda self, instance: self._render_status(instance) }, 'action': { 'render': lambda self, instance: self._render_action(instance) } }) @staticmethod def _render_status(instance): try: application = Application.objects.get(licence=instance) replacing_application = Application.objects.get(previous_application=application) if replacing_application.is_licence_amendment: return 'Amended' else: return 'Renewed' except Application.DoesNotExist: pass expiry_days = (instance.end_date - datetime.date.today()).days if expiry_days <= 30 and instance.is_renewable: return '<span class="label label-warning">Due for renewal</span>' elif instance.end_date < datetime.date.today(): return 'Expired' else: return 'Current' @staticmethod def _render_action(instance): try: application = Application.objects.get(licence=instance) if Application.objects.filter(previous_application=application).exists(): return 'N/A' except Application.DoesNotExist: pass expiry_days = (instance.end_date - datetime.date.today()).days if expiry_days <= 30 and instance.is_renewable: url = reverse('wl_applications:renew_licence', args=(instance.pk,)) return '<a href="{0}">Renew</a>'.format(url) elif instance.end_date >= datetime.date.today(): url = reverse('wl_applications:amend_licence', args=(instance.pk,)) return '<a href="{0}">Amend</a>'.format(url) else: return 'N/A' @staticmethod def _search_licence_number(search): # testing to see if search term contains no spaces and two hyphens, meaning it's a lodgement number with a sequence if search and search.count(' ') == 0 and search.count('-') == 2: components = search.split('-') licence_number, licence_sequence = '-'.join(components[:2]), '-'.join(components[2:]) return Q(licence_number__icontains=licence_number) & Q(licence_sequence__icontains=licence_sequence) else: return Q(licence_number__icontains=search) def get_initial_queryset(self): return WildlifeLicence.objects.filter(holder=self.request.user)
class DataTableReturnsOfficerView(OfficerRequiredMixin, base.DataTableBaseView): model = Return columns = [ 'lodgement_number', 'licence.licence_type', 'licence.profile.user', 'lodgement_date', 'due_date', 'status', 'licence_number', 'action', ] order_columns = [ 'lodgement_number', 'licence.licence_type', ['licence.profile.user.last_name', 'licence.profile.user.first_name'], 'lodgement_date', 'due_date', 'status', '', '' ] columns_helpers = dict( base.DataTableBaseView.columns_helpers.items(), **{ 'licence.licence_type': { 'render': lambda self, instance: instance.licence.licence_type. display_name, 'search': lambda self, search: base.build_field_query([ 'licence__licence_type__short_name', 'licence__licence_type__name', 'licence__licence_type__version' ], search) }, 'lodgement_number': { 'render': lambda self, instance: instance.lodgement_number }, 'lodgement_date': { 'render': lambda self, instance: base.render_date(instance.lodgement_date ) }, 'licence.profile.user': { 'render': lambda self, instance: base.render_user_name( instance.licence.profile.user, first_name_first=False), 'search': lambda self, search: base.build_field_query([ 'licence__profile__user__last_name', 'licence__profile__user__first_name' ], search), }, 'due_date': { 'render': lambda self, instance: base.render_date(instance.due_date) }, 'status': { 'render': lambda self, instance: self._render_status(instance) }, 'licence_number': { 'render': lambda self, instance: base.render_licence_number(instance. licence), 'search': lambda self, search: DataTableReturnsOfficerView. _search_licence_number(search), }, 'action': { 'render': lambda self, instance: self._render_action(instance) } }) @staticmethod def _render_status(instance): status = instance.status if status == 'current': if is_return_overdue(instance): return '<span class="label label-danger">Overdue</span>' elif is_return_due_soon(instance): return '<span class="label label-warning">Due soon</span>' else: return 'Current' else: suffix = ' (Nil)' if status == 'submitted' and instance.nil_return else '' return dict(Return.STATUS_CHOICES)[status] + suffix @staticmethod def _render_action(instance): if instance.status == 'current' or instance.status == 'future': url = reverse('wl_returns:enter_return', args=(instance.pk, )) return '<a href="{0}">Enter Return</a>'.format(url) elif instance.status == 'draft': url = reverse('wl_returns:enter_return', args=(instance.pk, )) return '<a href="{0}">Edit Return</a>'.format(url) elif instance.status in ['submitted', 'amended', 'amendment_required']: text = 'Curate Return' url = reverse('wl_returns:curate_return', args=(instance.pk, )) return '<a href="{0}">{1}</a>'.format(url, text) else: url = reverse('wl_returns:view_return', args=(instance.pk, )) return '<a href="{0}">View Return (read-only)</a>'.format(url) @staticmethod def filter_licence_type(value): if value.lower() != 'all': return Q(return_type__licence_type__pk=value) else: return None @staticmethod def filter_status(value): if value == TablesReturnsOfficerView.STATUS_FILTER_ALL_BUT_DRAFT_OR_FUTURE: return ~Q(status__in=['draft', 'future']) elif value == TablesReturnsOfficerView.OVERDUE_FILTER: return Q(due_date__lt=datetime.date.today()) & ~Q( status__in=['future', 'submitted', 'accepted', 'declined']) elif value == 'all': return None else: return Q(status=value) @staticmethod def _search_licence_number(search): # testing to see if search term contains no spaces and two hyphens, # meaning it's a licence number with a sequence if search and search.count(' ') == 0 and search.count('-') == 2: components = search.split('-') licence_number, licence_sequence = '-'.join( components[:2]), '-'.join(components[2:]) return Q(licence__licence_number__icontains=licence_number) & Q( licence__licence_sequence__icontains=licence_sequence) else: return Q(licence__licence_number__icontains=search) def get_initial_queryset(self): return Return.objects.all()
class DataTableLicencesOfficerView(OfficerRequiredMixin, base.DataTableBaseView): model = WildlifeLicence columns = [ 'licence_number', 'licence_type', 'profile.user', 'issue_date', 'end_date', 'licence', 'cover_letter', 'renewal_letter', 'status', 'action' ] order_columns = [ 'licence_number', ['licence_type.short_name', 'licence_type.name'], ['profile.user.last_name', 'profile.user.first_name'], 'issue_date', 'end_date', '', '' ] columns_helpers = dict( base.DataTableBaseView.columns_helpers.items(), **{ 'licence_number': { 'search': lambda self, search: DataTableLicencesOfficerView. _search_licence_number(search), 'render': lambda self, instance: base.render_licence_number(instance) }, 'profile.user': { 'render': lambda self, instance: base.render_user_name( instance.profile.user, first_name_first=False), 'search': lambda self, search: base.build_field_query([ 'profile__user__last_name', 'profile__user__first_name' ], search), }, 'issue_date': { 'render': lambda self, instance: base.render_date(instance.issue_date) }, 'start_date': { 'render': lambda self, instance: base.render_date(instance.start_date) }, 'end_date': { 'render': lambda self, instance: base.render_date(instance.end_date) }, 'licence': { 'render': lambda self, instance: base.render_licence_document(instance) }, 'cover_letter': { 'render': lambda self, instance: _render_cover_letter_document(instance) }, 'renewal_letter': { 'render': lambda self, instance: self._render_renewal_letter(instance) }, 'status': { 'render': lambda self, instance: self._render_status(instance) }, 'action': { 'render': lambda self, instance: self._render_action(instance) } }) @staticmethod def filter_status(value): today = datetime.date.today() if value == TablesLicencesOfficerView.STATUS_FILTER_ACTIVE: return Q(start_date__lte=today) & Q(end_date__gte=today) elif value == TablesLicencesOfficerView.STATUS_FILTER_RENEWABLE: return Q(is_renewable=True) & Q(end_date__gte=today) & Q( end_date__lte=today + datetime.timedelta(days=30)) elif value == TablesLicencesOfficerView.STATUS_FILTER_EXPIRED: return Q(end_date__lt=today) else: return None @staticmethod def filter_licence_type(value): if value.lower() != 'all': return Q(licence_type__pk=value) else: return None @staticmethod def filter_expiry_after(value): if value: try: date = date_parse(value, dayfirst=True).date() return Q(end_date__gte=date) except: pass return None @staticmethod def filter_expiry_before(value): if value: try: date = date_parse(value, dayfirst=True).date() return Q(end_date__lte=date) except: pass return None @staticmethod def _search_licence_number(search): # testing to see if search term contains no spaces and two hyphens, # meaning it's a lodgement number with a sequence if search and search.count(' ') == 0 and search.count('-') == 2: components = search.split('-') licence_number, licence_sequence = '-'.join( components[:2]), '-'.join(components[2:]) return Q(licence_number__icontains=licence_number) & Q( licence_sequence__icontains=licence_sequence) else: return Q(licence_number__icontains=search) @staticmethod def _render_renewal_letter(instance): if instance.is_renewable: return '<a href="{0}" target="_blank">Create PDF</a><img height="20" src="{1}"></img>'. \ format(reverse('wl_main:licence_renewal_pdf', args=(instance.pk,)), static('wl/img/pdf.png')) else: return 'Not renewable' @staticmethod def _render_status(instance): if not instance.is_issued: return 'Unissued' try: application = Application.objects.get(licence=instance) replacing_application = Application.objects.get( previous_application=application) if replacing_application.application_type == 'amendment': return 'Amended' else: return 'Renewed' except Application.DoesNotExist: pass if instance.end_date is not None: expiry_days = (instance.end_date - datetime.date.today()).days if instance.end_date < datetime.date.today(): return '<span class="label label-danger">Expired</span>' elif expiry_days <= 30 and instance.is_renewable: return '<span class="label label-warning">Due for renewal</span>' else: return 'Current' else: # should not happen message = "The licence ref:{ref} pk:{pk} has no end date!".format( ref=instance.reference, pk=instance.pk) logger.exception(Exception(message)) return 'Unissued' @staticmethod def _render_action(instance): try: application = Application.objects.get(licence=instance) if Application.objects.filter( previous_application=application).exists(): return 'N/A' except Application.DoesNotExist: application = None if not instance.is_issued: return '<a href="{0}">Issue</a>'.format( reverse('wl_applications:issue_licence', args=(application.pk, ))) amend_url = reverse('wl_applications:amend_licence', args=(instance.pk, )) renew_url = reverse('wl_applications:renew_licence', args=(instance.pk, )) reissue_url = reverse('wl_applications:reissue_licence', args=(instance.pk, )) if instance.end_date is not None: expiry_days = (instance.end_date - datetime.date.today()).days if instance.is_renewable: if 30 >= expiry_days > 0: return '<a href="{0}">Amend</a> / <a href="{1}">Renew</a> / <a href="{2}">Reissue</a>'.\ format(amend_url, renew_url, reissue_url) elif expiry_days <= 30: return '<a href="{0}">Renew</a>'.format(renew_url) if instance.end_date >= datetime.date.today(): return '<a href="{0}">Amend</a> / <a href="{1}">Reissue</a>'.format( amend_url, reissue_url) else: return 'N/A' else: return '<a href="{0}">Issue</a>'.format( reverse('wl_applications:issue_licence', args=(application.pk, ))) def get_initial_queryset(self): return WildlifeLicence.objects.all()
class DataTableLicencesOfficerView(OfficerRequiredMixin, base.DataTableBaseView): model = WildlifeLicence columns = [ 'licence_number', 'licence_type', 'profile.user', 'start_date', 'end_date', 'licence', 'cover_letter', 'renewal_letter', 'action' ] order_columns = [ 'licence_number', ['licence_type.short_name', 'licence_type.name'], ['profile.user.last_name', 'profile.user.first_name'], 'start_date', 'end_date', '', '' ] columns_helpers = dict( base.DataTableBaseView.columns_helpers.items(), **{ 'licence_number': { 'search': lambda self, search: DataTableLicencesOfficerView. _search_licence_number(search), 'render': lambda self, instance: base.render_licence_number(instance) }, 'profile.user': { 'render': lambda self, instance: base.render_user_name( instance.profile.user, first_name_first=False), 'search': lambda self, search: base.build_field_query([ 'profile__user__last_name', 'profile__user__first_name' ], search), }, 'issue_date': { 'render': lambda self, instance: base.render_date(instance.issue_date) }, 'start_date': { 'render': lambda self, instance: base.render_date(instance.start_date) }, 'end_date': { 'render': lambda self, instance: base.render_date(instance.end_date) }, 'licence': { 'render': lambda self, instance: base.render_licence_document(instance) }, 'cover_letter': { 'render': lambda self, instance: _render_cover_letter_document(instance) }, 'renewal_letter': { 'render': lambda self, instance: self._render_renewal_letter(instance) }, 'action': { 'render': lambda self, instance: self._render_action(instance) } }) @staticmethod def filter_status(value): today = datetime.date.today() if value == TableLicencesOfficerView.STATUS_FILTER_ACTIVE: return Q(start_date__lte=today) & Q(end_date__gte=today) elif value == TableLicencesOfficerView.STATUS_FILTER_RENEWABLE: return Q(is_renewable=True) & Q(end_date__gte=today) & Q( end_date__lte=today + datetime.timedelta(days=30)) elif value == TableLicencesOfficerView.STATUS_FILTER_EXPIRED: return Q(end_date__lt=today) else: return None @staticmethod def filter_licence_type(value): if value.lower() != 'all': return Q(licence_type__pk=value) else: return None @staticmethod def filter_expiry_after(value): if value: try: date = date_parse(value, dayfirst=True).date() return Q(end_date__gte=date) except: pass return None @staticmethod def filter_expiry_before(value): if value: try: date = date_parse(value, dayfirst=True).date() return Q(end_date__lte=date) except: pass return None @staticmethod def _search_licence_number(search): # testing to see if search term contains no spaces and two hyphens, meaning it's a lodgement number with a sequence if search and search.count(' ') == 0 and search.count('-') == 2: components = search.split('-') licence_number, licence_sequence = '-'.join( components[:2]), '-'.join(components[2:]) return Q(licence_number__icontains=licence_number) & Q( licence_sequence__icontains=licence_sequence) else: return Q(licence_number__icontains=search) @staticmethod def _render_renewal_letter(instance): if instance.is_renewable: return '<a href="{0}" target="_blank">Create PDF</a><img height="20" src="{1}"></img>'. \ format(reverse('wl_main:licence_renewal_pdf', args=(instance.pk,)), static('wl/img/pdf.png')) else: return 'Not renewable' @staticmethod def _render_action(instance): reissue_url = reverse('wl_applications:reissue_licence', args=(instance.pk, )) expiry_days = (instance.end_date - datetime.date.today()).days if expiry_days <= 30 and instance.is_renewable: renew_url = reverse('wl_applications:renew_licence', args=(instance.pk, )) return '<a href="{0}">Renew</a> / <a href="{1}">Reissue</a>'.format( renew_url, reissue_url) else: amend_url = reverse('wl_applications:amend_licence', args=(instance.pk, )) return '<a href="{0}">Amend</a> / <a href="{1}">Reissue</a>'.format( amend_url, reissue_url) def get_initial_queryset(self): return WildlifeLicence.objects.all()