combo/combo/apps/lingo/manager_views.py

176 lines
6.2 KiB
Python

# lingo - basket and payment system
# Copyright (C) 2015 Entr'ouvert
#
# This program is free software: you can redistribute it and/or modify it
# under the terms of the GNU Affero General Public License as published
# by the Free Software Foundation, either version 3 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 Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
import csv
import datetime
from dateutil import parser as date_parser
from django.core.urlresolvers import reverse_lazy
from django.db.models import Q
from django.db.models.expressions import RawSQL
from django.utils import six
from django.utils.timezone import make_aware, now
from django.views.generic import CreateView, UpdateView, ListView, DeleteView
from django.http import HttpResponse
from django.template.response import TemplateResponse
import eopayment
from .forms import RegieForm
from .forms import TransactionExportForm
from .models import BasketItem, PaymentBackend, Regie, Transaction
class RegieListView(ListView):
model = Regie
class RegieCreateView(CreateView):
model = Regie
fields = ['label', 'slug', 'description', 'payment_backend']
success_url = reverse_lazy('lingo-manager-regie-list')
class RegieUpdateView(UpdateView):
model = Regie
form_class = RegieForm
success_url = reverse_lazy('lingo-manager-regie-list')
class RegieDeleteView(DeleteView):
model = Regie
success_url = reverse_lazy('lingo-manager-regie-list')
class PaymentBackendListView(ListView):
model = PaymentBackend
class PaymentBackendCreateView(CreateView):
model = PaymentBackend
fields = '__all__'
success_url = reverse_lazy('lingo-manager-paymentbackend-list')
class PaymentBackendUpdateView(UpdateView):
model = PaymentBackend
fields = '__all__'
success_url = reverse_lazy('lingo-manager-paymentbackend-list')
class PaymentBackendDeleteView(DeleteView):
model = PaymentBackend
success_url = reverse_lazy('lingo-manager-paymentbackend-list')
class TransactionListView(ListView):
model = Transaction
paginate_by = 10
def get_context_data(self, **kwargs):
context = super(TransactionListView, self).get_context_data(**kwargs)
context['query'] = self.request.GET.get('q') or ''
return context
def get_queryset(self):
qs = Transaction.objects.filter(
status__in=(eopayment.PAID, eopayment.ACCEPTED)).order_by('-start_date')
query = self.request.GET.get('q')
if query:
try:
date = date_parser.parse(query, dayfirst=True)
except:
qs = qs.filter(
Q(order_id=query) |
Q(bank_transaction_id=query) |
Q(items__subject__icontains=query)
)
else:
date = make_aware(date)
qs = qs.filter(start_date__gte=date, start_date__lt=date + datetime.timedelta(days=1))
return qs
class BasketItemErrorListView(ListView):
model = BasketItem
template_name = 'lingo/basketitem_error_list.html'
paginate_by = 10
def get_context_data(self, **kwargs):
context = super(BasketItemErrorListView, self).get_context_data(**kwargs)
context['query'] = self.request.GET.get('q') or ''
return context
def get_queryset(self):
raw = (
'SELECT %s FROM lingo_transaction '
'INNER JOIN lingo_transaction_items '
'ON "lingo_transaction"."id" = "lingo_transaction_items"."transaction_id" '
'AND "lingo_transaction_items"."basketitem_id"="lingo_basketitem"."id" '
'ORDER BY start_date DESC LIMIT 1')
queryset = (
BasketItem.objects
.annotate(bank_transaction_id=RawSQL(raw % 'bank_transaction_id', []))
.annotate(transaction_status=RawSQL(raw % 'status', []))
.filter(regie__webservice_url='')
.order_by())
terms = self.request.GET.get('q')
if terms:
queryset = queryset.filter(subject__icontains=terms)
queryset1 = (
queryset
.filter(
notification_date__isnull=True,
cancellation_date__isnull=True,
payment_date__lt=now() - datetime.timedelta(minutes=300)))
queryset2 = queryset.filter(transaction_status=eopayment.ERROR)
return queryset1.union(queryset2).order_by('-creation_date')
def download_transactions_csv(request):
if request.method == 'POST':
form = TransactionExportForm(data=request.POST)
if form.is_valid():
response = HttpResponse(content_type='text/csv')
response['Content-Disposition'] = 'attachment; filename="transactions.csv"'
writer = csv.writer(response)
transactions = (
Transaction.objects
.filter(
status__in=(eopayment.PAID, eopayment.ACCEPTED),
start_date__gte=form.cleaned_data['start_date'],
start_date__lte=form.cleaned_data['end_date'],
).order_by('-start_date'))
for transaction in transactions:
row = [transaction.order_id,
transaction.bank_transaction_id,
transaction.start_date.strftime('%Y-%m-%d %H:%M:%S'),
transaction.get_user_name(),
str(transaction.amount)]
for item in transaction.items.all():
row.extend([item.subject, str(item.amount)])
if six.PY3:
writer.writerow([x for x in row])
else:
writer.writerow([unicode(x).encode('utf-8') for x in row])
return response
else:
form = TransactionExportForm()
return TemplateResponse(request, 'lingo/transaction_export.html', {'form': form})