You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
225 lines
8.0 KiB
225 lines
8.0 KiB
import csv
|
|
from hashlib import md5
|
|
|
|
from django.contrib import messages
|
|
from django.contrib.auth.mixins import PermissionRequiredMixin
|
|
from django.db import DatabaseError, transaction
|
|
from django.db.models import Count
|
|
from django.http import HttpResponse
|
|
from django.shortcuts import get_object_or_404, resolve_url
|
|
from django.urls import reverse_lazy
|
|
from django.utils import timezone
|
|
from django.utils.decorators import method_decorator
|
|
from django.views.generic import ListView, DetailView, CreateView, UpdateView
|
|
from django.utils.translation import ugettext_lazy as _
|
|
from xmlview.decorators import xml_view
|
|
from djing import lib
|
|
from djing.global_base_views import OrderedFilteredList
|
|
from djing.lib.mixins import LoginAdminMixin, LoginAdminPermissionMixin
|
|
from finapp.forms import PayAllTimeGatewayForm
|
|
from finapp.models import AllTimePayLog, PayAllTimeGateway
|
|
from abonapp.models import Abon
|
|
|
|
|
|
class AllTimePay(DetailView):
|
|
http_method_names = 'get',
|
|
model = PayAllTimeGateway
|
|
pk_url_kwarg = 'slug'
|
|
slug_url_kwarg = 'pay_slug'
|
|
|
|
@staticmethod
|
|
def _bad_ret(err_id, err_description=None):
|
|
now = timezone.now()
|
|
r = {
|
|
'status_code': lib.safe_int(err_id),
|
|
'time_stamp': now.strftime("%d.%m.%Y %H:%M")
|
|
}
|
|
if err_description:
|
|
r.update({'description': err_description})
|
|
return r
|
|
|
|
def check_sign(self, data: dict, sign: str) -> bool:
|
|
act = lib.safe_int(data.get('ACT'))
|
|
pay_account = data.get('PAY_ACCOUNT')
|
|
serv_id = data.get('SERVICE_ID')
|
|
pay_id = data.get('PAY_ID')
|
|
md = md5()
|
|
s = '_'.join(
|
|
(str(act), pay_account or '', serv_id or '',
|
|
pay_id or '', self.object.secret)
|
|
)
|
|
md.update(bytes(s, 'utf-8'))
|
|
our_sign = md.hexdigest()
|
|
return our_sign == sign
|
|
|
|
@method_decorator(xml_view(root_node='pay-response'))
|
|
def get(self, request, *args, **kwargs):
|
|
self.object = self.get_object()
|
|
act = lib.safe_int(request.GET.get('ACT'))
|
|
self.current_date = timezone.now().strftime("%d.%m.%Y %H:%M")
|
|
|
|
if act <= 0:
|
|
return self._bad_ret(-101, 'ACT must be more than 0')
|
|
sign = request.GET.get('SIGN')
|
|
if not sign:
|
|
return self._bad_ret(-101, 'SIGN not passed')
|
|
if not self.check_sign(request.GET, sign.lower()):
|
|
return self._bad_ret(-101, 'Bad sign')
|
|
|
|
try:
|
|
if act == 1:
|
|
return self._fetch_user_info(request.GET)
|
|
elif act == 4:
|
|
return self._make_pay(request.GET)
|
|
elif act == 7:
|
|
return self._check_pay(request.GET)
|
|
else:
|
|
return self._bad_ret(-101, 'ACT is not passed')
|
|
except Abon.DoesNotExist:
|
|
return self._bad_ret(-40, 'Account does not exist')
|
|
except DatabaseError:
|
|
return self._bad_ret(-90)
|
|
except AllTimePayLog.DoesNotExist:
|
|
return self._bad_ret(-10)
|
|
except AttributeError:
|
|
return self._bad_ret(-101)
|
|
|
|
def _fetch_user_info(self, data: dict):
|
|
pay_account = data.get('PAY_ACCOUNT')
|
|
abon = Abon.objects.get(username=pay_account)
|
|
fio = abon.fio
|
|
ballance = float(abon.ballance)
|
|
return {
|
|
'balance': round(ballance, 2),
|
|
'name': fio,
|
|
'account': pay_account,
|
|
'service_id': self.object.service_id,
|
|
'min_amount': 10.0,
|
|
'max_amount': 5000,
|
|
'status_code': 21,
|
|
'time_stamp': self.current_date
|
|
}
|
|
|
|
def _make_pay(self, data: dict):
|
|
trade_point = lib.safe_int(data.get('TRADE_POINT'))
|
|
receipt_num = lib.safe_int(data.get('RECEIPT_NUM'))
|
|
pay_account = data.get('PAY_ACCOUNT')
|
|
pay_id = data.get('PAY_ID')
|
|
pay_amount = lib.safe_float(data.get('PAY_AMOUNT'))
|
|
abon = Abon.objects.get(username=pay_account)
|
|
pays = AllTimePayLog.objects.filter(pay_id=pay_id)
|
|
if pays.exists():
|
|
return self._bad_ret(-100, 'Pay already exists')
|
|
|
|
with transaction.atomic():
|
|
abon.add_ballance(
|
|
None, pay_amount,
|
|
comment='%s %.2f' % (self.object.title, pay_amount)
|
|
)
|
|
abon.save(update_fields=('ballance',))
|
|
|
|
AllTimePayLog.objects.create(
|
|
pay_id=pay_id,
|
|
summ=pay_amount,
|
|
abon=abon,
|
|
trade_point=trade_point,
|
|
receipt_num=receipt_num,
|
|
pay_gw=self.object
|
|
)
|
|
return {
|
|
'pay_id': pay_id,
|
|
'service_id': data.get('SERVICE_ID'),
|
|
'amount': round(pay_amount, 2),
|
|
'status_code': 22,
|
|
'time_stamp': self.current_date
|
|
}
|
|
|
|
def _check_pay(self, data: dict):
|
|
pay_id = data.get('PAY_ID')
|
|
pay = AllTimePayLog.objects.get(pay_id=pay_id)
|
|
return {
|
|
'status_code': 11,
|
|
'time_stamp': self.current_date,
|
|
'transaction': {
|
|
'pay_id': pay_id,
|
|
'service_id': data.get('SERVICE_ID'),
|
|
'amount': round(pay.summ, 2),
|
|
'status': 111,
|
|
'time_stamp': pay.date_add.strftime("%d.%m.%Y %H:%M")
|
|
}
|
|
}
|
|
|
|
|
|
class BasicFinReport(LoginAdminMixin, ListView):
|
|
model = AllTimePayLog
|
|
queryset = AllTimePayLog.objects.by_days()
|
|
template_name = 'finapp/fin_report.html'
|
|
context_object_name = 'logs'
|
|
|
|
def get(self, request, *args, **kwargs):
|
|
res_format = request.GET.get('f')
|
|
if res_format == 'csv':
|
|
response = HttpResponse(content_type='text/csv')
|
|
response['Content-Disposition'] = 'attachment; filename="report.csv"'
|
|
writer = csv.writer(response, quoting=csv.QUOTE_NONNUMERIC)
|
|
for row in self.object_list:
|
|
writer.writerow(
|
|
(row['summ'], row['pay_date'].strftime('%Y-%m-%d'))
|
|
)
|
|
return response
|
|
return super().get(request, *args, **kwargs)
|
|
|
|
|
|
class PayHistoryListView(LoginAdminMixin, PermissionRequiredMixin,
|
|
OrderedFilteredList):
|
|
permission_required = 'group_app.view_group'
|
|
context_object_name = 'pay_history'
|
|
template_name = 'finapp/payHistory.html'
|
|
model = AllTimePayLog
|
|
|
|
def get_queryset(self):
|
|
pay_history = AllTimePayLog.objects.filter(
|
|
pay_gw__slug=self.kwargs.get('pay_slug')
|
|
).select_related('abon__group').order_by('-date_add')
|
|
return pay_history
|
|
|
|
def get_context_data(self, **kwargs):
|
|
context = {
|
|
'pay_gw': get_object_or_404(PayAllTimeGateway, slug=self.kwargs.get('pay_slug'))
|
|
}
|
|
context.update(kwargs)
|
|
return super(PayHistoryListView, self).get_context_data(**context)
|
|
|
|
|
|
class AddAllTimeGateway(LoginAdminMixin, PermissionRequiredMixin, CreateView):
|
|
permission_required = 'finapp.add_payalltimegateway'
|
|
model = PayAllTimeGateway
|
|
form_class = PayAllTimeGatewayForm
|
|
success_url = reverse_lazy('finapp:alltime_gateways_list')
|
|
|
|
def form_valid(self, form):
|
|
messages.success(self.request, _('New pay gateway created successfully'))
|
|
return super(AddAllTimeGateway, self).form_valid(form)
|
|
|
|
|
|
class AllTimeGatewaysListView(LoginAdminPermissionMixin, ListView):
|
|
permission_required = 'finapp.view_payalltimegateway'
|
|
model = PayAllTimeGateway
|
|
queryset = PayAllTimeGateway.objects.annotate(
|
|
pays_count=Count('alltimepaylog')
|
|
)
|
|
|
|
|
|
class EditPayUpdateView(LoginAdminPermissionMixin, UpdateView):
|
|
permission_required = 'finapp.change_payalltimegateway'
|
|
model = PayAllTimeGateway
|
|
form_class = PayAllTimeGatewayForm
|
|
pk_url_kwarg = 'slug'
|
|
slug_url_kwarg = 'pay_slug'
|
|
|
|
def get_success_url(self):
|
|
return resolve_url('finapp:edit_pay_gw', self.object.slug)
|
|
|
|
def form_valid(self, form):
|
|
messages.success(self.request, _('Payment gateway successfully updated'))
|
|
return super(EditPayUpdateView, self).form_valid(form)
|