diff --git a/emencia/django/newsletter/forms.py b/emencia/django/newsletter/forms.py index fc47e873..762f63ee 100644 --- a/emencia/django/newsletter/forms.py +++ b/emencia/django/newsletter/forms.py @@ -2,6 +2,7 @@ """Forms for emencia.django.newsletter""" from datetime import datetime, date, timedelta from django import forms +from django.db.models import Sum from django.utils.translation import ugettext_lazy as _ from django.http import Http404 @@ -9,7 +10,7 @@ from django.core.exceptions import ValidationError from django.utils import translation from haystack.query import SearchQuerySet from functions.search_forms import get_by_lang -from emencia.django.newsletter.models import Contact, ContactSettings, MailingList, PopupCount +from emencia.django.newsletter.models import Contact, ContactSettings, MailingList, PopupCount, ContactMailingStatus from functions.form_check import translit_with_separator as tr from theme.models import Theme from country.models import Country, Area @@ -336,7 +337,7 @@ class SubscribeSettingsForm(AbstractSubscribeForm): def clean_email(self): return self.cleaned_data['email'] -from django.db.models import Sum + class PopupCountFilter(forms.Form): fr = forms.DateField(required=False) to = forms.DateField(required=False) @@ -358,4 +359,20 @@ class PopupCountFilter(forms.Form): activated = contacts.filter(activated=True).count() popups = qs.aggregate(count=Sum('cnt'))['count'] - return {'subscribed': subscribed, 'activated': activated, 'popups': popups} \ No newline at end of file + return {'subscribed': subscribed, 'activated': activated, 'popups': popups} + + +class MailingStatusFilter(forms.Form): + status = forms.ChoiceField(choices=[('', u'Не выбрано')] + [(item[0], item[1]) for item in ContactMailingStatus.STATUS_CHOICES], + required=False) + email = forms.CharField(required=False, widget=forms.TextInput(attrs={'placeholder': 'Email'})) + + def filter(self, newsletter): + status = self.cleaned_data.get('status') + email = self.cleaned_data.get('email') + qs = ContactMailingStatus.objects.select_related().filter(newsletter=newsletter) + if status: + qs = qs.filter(status=status) + if email: + qs = qs.filter(contact__email=email) + return qs \ No newline at end of file diff --git a/emencia/django/newsletter/views/admin_views.py b/emencia/django/newsletter/views/admin_views.py index 7697fef9..11fe5f23 100644 --- a/emencia/django/newsletter/views/admin_views.py +++ b/emencia/django/newsletter/views/admin_views.py @@ -1,4 +1,5 @@ # -*- coding: utf-8 -*- +import datetime from django.views.generic import CreateView, ListView, UpdateView, DeleteView, FormView, DetailView, RedirectView, TemplateView from django.conf import settings from django.utils import translation @@ -7,14 +8,17 @@ from django.forms.formsets import formset_factory from django.http import HttpResponseRedirect, HttpResponse from django.shortcuts import get_object_or_404 from django.core.urlresolvers import reverse_lazy +from django.forms.models import modelformset_factory from HTMLParser import HTMLParseError from emencia.django.newsletter.models import Contact, ContactSettings, MailingList, Newsletter, Attachment, ContactMailingStatus from emencia.django.newsletter.admin_forms import ContactSettingsForm, MailingListForm, NewsletterForm, AttachmentForm from emencia.django.newsletter.mailer import Mailer -from emencia.django.newsletter.forms import PopupCountFilter +from emencia.django.newsletter.forms import PopupCountFilter, MailingStatusFilter from ..forms import ContactFilterForm, ContactImportForm from ..utils.excel import ExcelResponse from functions.admin_views import paginate_results +from ..models import PopupCount +from theme.models import Theme class ContactList(FormView): @@ -71,8 +75,6 @@ class ContactQueryDelete(RedirectView): return HttpResponse('400') - - class DeleteContact(DeleteView): model = Contact success_url = reverse_lazy('newsletters_contact_list') @@ -128,8 +130,6 @@ class ImportContacts(FormView): return HttpResponseRedirect(self.get_success_url()) - - class MailingListView(ListView): paginate_by = settings.ADMIN_PAGINATION model = MailingList @@ -167,8 +167,6 @@ class CreateMailingList(CreateView): obj.save() return HttpResponseRedirect(self.success_url) -from django.forms.models import modelformset_factory - class NewsletterCreate(CreateView): model = Newsletter @@ -241,7 +239,6 @@ class NewsletterUpdate(UpdateView): return HttpResponseRedirect(self.success_url) - class NewsletterListView(ListView): paginate_by = settings.ADMIN_PAGINATION model = Newsletter @@ -272,21 +269,25 @@ class NewsletterStatistics(DetailView): context = super(NewsletterStatistics, self).get_context_data(**kwargs) sent = self.object.contactmailingstatus_set.filter(status=ContactMailingStatus.SENT).count() errors = self.object.contactmailingstatus_set.filter(status=ContactMailingStatus.ERROR).count() - opened = self.object.contactmailingstatus_set.filter(status=ContactMailingStatus.OPENED).count() + opened = self.object.contactmailingstatus_set.filter(status=ContactMailingStatus.OPENED).\ + values_list('contact', flat=True).distinct().count() unsubscribed = self.object.contactmailingstatus_set.filter(status=ContactMailingStatus.UNSUBSCRIPTION).\ values_list('contact', flat=True).distinct().count() no_data = self.object.contactmailingstatus_set.filter(status=ContactMailingStatus.ANNOUNCE_NO_DATA).count() links = self.object.contactmailingstatus_set.filter(status=ContactMailingStatus.LINK_OPENED).count() + links_unique = self.object.contactmailingstatus_set.filter(status=ContactMailingStatus.LINK_OPENED).\ + values_list('contact', flat=True).distinct().count() CMS = ContactMailingStatus opened_percent = 0 if opened or sent == 0 else (float(opened)/sent)*100 unsub_percent = 0 if unsubscribed or sent == 0 else (float(unsubscribed)/sent)*100 stat = { - 'sent':{'data':sent, 'filter':""}, - 'errors':{ 'data':errors, 'filter':CMS.ERROR}, - 'opened':{'data': opened, 'filter': CMS.OPENED, 'percent': opened_percent}, - 'unsub':{'data': unsubscribed, 'filter': CMS.UNSUBSCRIPTION, 'percent': unsub_percent}, - 'no_data':{'data': no_data, 'filter': CMS.ANNOUNCE_NO_DATA}, - 'links':{'data': links, 'filter': CMS.LINK_OPENED}} + 'sent': {'data': sent, 'filter': ""}, + 'errors': {'data': errors, 'filter': CMS.ERROR}, + 'opened': {'data': opened, 'filter': CMS.OPENED, 'percent': opened_percent}, + 'unsub': {'data': unsubscribed, 'filter': CMS.UNSUBSCRIPTION, 'percent': unsub_percent}, + 'no_data': {'data': no_data, 'filter': CMS.ANNOUNCE_NO_DATA}, + 'links': {'data': links, 'filter': CMS.LINK_OPENED}, + 'links_unique': {'data': links_unique, 'filter': CMS.LINK_OPENED}} context.update({'stat': stat}) return context @@ -310,33 +311,36 @@ class NewsletterHistory(ListView): def get_queryset(self): self.newsletter = get_object_or_404(Newsletter, pk=self.kwargs['pk']) - qs = self.newsletter.contactmailingstatus_set.select_related('contact', 'link').all() - if self.request.GET.get('filter'): - qs = qs.filter(status=self.request.GET['filter']) + if self.request.GET: + form = MailingStatusFilter(self.request.GET) + if form.is_valid(): + qs = form.filter(self.newsletter) + else: + qs = ContactMailingStatus.objects.select_related().filter(newsletter=self.newsletter) + else: + qs = ContactMailingStatus.objects.select_related().filter(newsletter=self.newsletter) return qs + def get_context_data(self, **kwargs): context = super(NewsletterHistory, self).get_context_data(**kwargs) context['newsletter'] = self.newsletter context['choices'] = ContactMailingStatus.STATUS_CHOICES + form = MailingStatusFilter(self.request.GET) + context['filter_form'] = form return context - class NewsletterDelete(DeleteView): model = Newsletter template_name = 'admin/newsletters/confirm_delete.html' success_url = reverse_lazy('newsletters_newsletters_list') -import datetime -from ..models import PopupCount -from theme.models import Theme - def count_popups(request): - #if not request.is_ajax(): - # return HttpResponse("request is not ajax") - #else: + if not request.is_ajax(): + return HttpResponse("request is not ajax") + else: themes = request.GET.getlist('theme') if themes: for theme_id in themes: @@ -350,8 +354,6 @@ def count_popups(request): return HttpResponse(obj.cnt, content_type='application/json') - - class PopupStatisticsView(FormView): form_class = PopupCountFilter template_name = 'admin/newsletters/popup_count.html' @@ -368,27 +370,4 @@ class PopupStatisticsView(FormView): data = form.filter() data['form'] = form - return self.render_to_response(data) - - -""" -class PopupStatisticsView(TemplateView): - model = PopupCount - template_name = 'admin/newsletters/popup_count.html' - - def get(self, request, *args, **kwargs): - qs = PopupCount.objects.all() - data = self.request.GET - if data.get('from'): - qs = qs.filter(date__gte=datetime.datetime.strptime(data['from'], '%d.%m.%Y').date()) - if data.get('to'): - qs = qs.filter(date__lt=datetime.datetime.strptime(data['to'], '%d.%m.%Y').date()) - if not data.get('from') and not data.get('to'): - qs = qs.filter(date=datetime.date.today()) - if qs: - res = {'cnt':qs.aggregate(cnt=Sum('cnt'))['cnt'], 'subscr':qs[0].get_subscr(), 'active':qs[0].get_active()} - else: - res = {'cnt':0, 'subscr':0, 'active':0} - return self.render_to_response({'object':res}) - -""" + return self.render_to_response(data) \ No newline at end of file diff --git a/templates/admin/newsletters/newsletter_history.html b/templates/admin/newsletters/newsletter_history.html index f9a64245..ff5c7f40 100644 --- a/templates/admin/newsletters/newsletter_history.html +++ b/templates/admin/newsletters/newsletter_history.html @@ -8,14 +8,11 @@