194 lines
7.0 KiB
Python
194 lines
7.0 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
|
|
|
|
import eopayment
|
|
from dateutil import parser as date_parser
|
|
from django.contrib import messages
|
|
from django.db.models import Prefetch, Q
|
|
from django.db.models.expressions import RawSQL
|
|
from django.http import HttpResponse, HttpResponseRedirect
|
|
from django.shortcuts import get_object_or_404
|
|
from django.template.response import TemplateResponse
|
|
from django.urls import reverse, reverse_lazy
|
|
from django.utils import six
|
|
from django.utils.timezone import make_aware, now
|
|
from django.utils.translation import ugettext_lazy as _
|
|
from django.views.generic import CreateView, DeleteView, ListView, UpdateView, View
|
|
|
|
from .forms import PaymentBackendForm, RegieForm, 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 = ['label', 'slug', 'service']
|
|
|
|
def get_success_url(self):
|
|
messages.info(self.request, _('Please fill additional backend parameters.'))
|
|
return reverse_lazy('lingo-manager-paymentbackend-edit', kwargs={'pk': self.object.pk})
|
|
|
|
|
|
class PaymentBackendUpdateView(UpdateView):
|
|
model = PaymentBackend
|
|
form_class = PaymentBackendForm
|
|
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.select_related('user')
|
|
.prefetch_related(Prefetch('items', to_attr='prefetched_items'))
|
|
.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')
|
|
|
|
|
|
class BasketItemMarkAsNotifiedView(View):
|
|
def get(self, request, *args, **kwargs):
|
|
item = get_object_or_404(
|
|
BasketItem.objects.exclude(source_url=''),
|
|
pk=kwargs['item_id'],
|
|
regie__webservice_url='',
|
|
notification_date__isnull=True,
|
|
cancellation_date__isnull=True,
|
|
payment_date__lt=now() - datetime.timedelta(minutes=300),
|
|
)
|
|
item.notify_payment(notify_origin=False)
|
|
|
|
return HttpResponseRedirect(reverse('lingo-manager-payment-error-list'))
|
|
|
|
|
|
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__date__gte=form.cleaned_data['start_date'],
|
|
start_date__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)])
|
|
writer.writerow([x for x in row])
|
|
return response
|
|
else:
|
|
form = TransactionExportForm()
|
|
|
|
return TemplateResponse(request, 'lingo/transaction_export.html', {'form': form})
|