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.
199 lines
7.2 KiB
199 lines
7.2 KiB
# -*- coding: utf-8 -*-
|
|
from django import forms
|
|
from django.shortcuts import render
|
|
from django.views.decorators.csrf import csrf_protect
|
|
from django.contrib.admin.views.decorators import staff_member_required
|
|
from django.contrib.auth.decorators import permission_required
|
|
from django.utils.encoding import force_text
|
|
from django.conf import settings
|
|
|
|
import xlrd
|
|
|
|
from .models import Fond, FondStats
|
|
|
|
from .forms import AdminBaseImportForm, AdminFondStatsImportForm
|
|
|
|
|
|
DEBUG_IMPORT = getattr(settings, 'DEBUG_NPF_IMPORT', False)
|
|
|
|
|
|
def _getval_str(row, cx):
|
|
"""Взять значение из колонки внутри переданной строки.
|
|
Если значение прочитано из экселя как float вида 123.0, то .0 отбрасывается.
|
|
Иначе значение берётся как есть.
|
|
Всегда возвращает строку, начальные и хвостовые пробелы отрезаются.
|
|
"""
|
|
val = row[cx].value
|
|
if isinstance(val, float) and val - int(val) == 0:
|
|
val = int(val)
|
|
return force_text((u'%s' % val).strip())
|
|
|
|
|
|
def _getval_int(row, cx):
|
|
"""Взять целое значение из колонки внутри переданной строки.
|
|
Возвращает число или выбрасывает ошибку конвертации.
|
|
"""
|
|
val = row[cx].value
|
|
return int(val)
|
|
|
|
|
|
def _getval_int_or_none(row, cx):
|
|
"""Взять целое значение из колонки внутри переданной строки.
|
|
Возвращает число или None в случае ошибки конвертации.
|
|
"""
|
|
val = row[cx].value
|
|
try:
|
|
return int(val)
|
|
except ValueError:
|
|
return None
|
|
|
|
|
|
def _getval_float_or_none(row, cx):
|
|
"""Взять float из колонки внутри переданной строки.
|
|
Возвращает число или None в случае ошибки конвертации.
|
|
"""
|
|
val = row[cx].value
|
|
try:
|
|
return float(val)
|
|
except ValueError:
|
|
return None
|
|
|
|
|
|
@csrf_protect
|
|
@staff_member_required
|
|
@permission_required('can_import_export_fond', raise_exception=True)
|
|
def revise_licenses(request):
|
|
"""Сверка лицензий НПФ."""
|
|
IDX_LICENSE = 0 # номер лицензии
|
|
|
|
xls_file = None
|
|
new_licenses = None
|
|
closed_licenses = None
|
|
|
|
start_nrow = 1 # с какой строки начинать импорт из файла (отсчёт с нуля)
|
|
|
|
form_class = AdminBaseImportForm
|
|
|
|
if request.method == 'GET':
|
|
form = form_class()
|
|
else:
|
|
form = form_class(request.POST, request.FILES)
|
|
|
|
if request.method == 'POST' and form.is_valid():
|
|
xls_file = request.FILES['xls_file']
|
|
xls_to_import = xls_file.read()
|
|
book = xlrd.open_workbook(file_contents=xls_to_import)
|
|
|
|
sh = book.sheet_by_index(0)
|
|
|
|
# все лицензии в файле
|
|
xls_licenses = set([_getval_str(sh.row(rx), IDX_LICENSE) for rx in xrange(start_nrow, sh.nrows)])
|
|
|
|
# все лицензии на сайте
|
|
db_licenses = set(Fond.objects.all().order_by('license').values_list('license', flat=True))
|
|
|
|
# лицензии, которые есть в файле, но отсутствуют на сайте (новые фонды)
|
|
new_licenses = xls_licenses.difference(db_licenses)
|
|
|
|
# лицензии, которые есть на сайте, но отсутствуют в файле (закрывшиеся фонды)
|
|
closed_licenses = db_licenses.difference(xls_licenses)
|
|
|
|
return render(request, 'admin/npfs/revise_licenses.html',
|
|
{
|
|
'form': form,
|
|
'xls': xls_file,
|
|
'new_licenses': new_licenses,
|
|
'closed_licenses': closed_licenses,
|
|
},
|
|
)
|
|
|
|
|
|
@csrf_protect
|
|
@staff_member_required
|
|
@permission_required('can_imp_exp_fond_stats', raise_exception=True)
|
|
def import_fond_stats(request):
|
|
"""Импорт основных показателей НПФ."""
|
|
import_errors = []
|
|
err_license_not_found = []
|
|
|
|
xls_file = None
|
|
wrong_file = None
|
|
|
|
start_nrow = 4 # с какой строки начинать импорт из файла (отсчёт с нуля)
|
|
|
|
form_class = AdminFondStatsImportForm
|
|
|
|
if request.method == 'GET':
|
|
form = form_class()
|
|
else:
|
|
form = form_class(request.POST, request.FILES)
|
|
|
|
if request.method == 'POST' and form.is_valid():
|
|
xls_file = request.FILES['xls_file']
|
|
xls_to_import = xls_file.read()
|
|
book = xlrd.open_workbook(file_contents=xls_to_import)
|
|
|
|
sh = book.sheet_by_index(0)
|
|
|
|
god = int(form.cleaned_data['god'])
|
|
kvartal = int(form.cleaned_data['kvartal'])
|
|
|
|
# закешировать НПФ в словарь. ключ номер лицензии
|
|
fond_cache = {_fond.license: _fond for _fond in Fond.objects.all()}
|
|
|
|
rx = 0
|
|
for rx in xrange(start_nrow, sh.nrows):
|
|
row = sh.row(rx)
|
|
|
|
try:
|
|
license = _getval_str(row, 0)
|
|
|
|
if not license:
|
|
raise Exception(u'Не указан `№ лицензии` в строке номер %d!' % (rx+1))
|
|
|
|
try:
|
|
fond = fond_cache[license]
|
|
except KeyError:
|
|
err_license_not_found.append(rx + 1)
|
|
raise Exception(u'Не найден `НПФ` в строке номер %d!' % (rx+1))
|
|
|
|
fond_stats, created = FondStats.objects.get_or_create(
|
|
fond=fond, god=god, kvartal=kvartal)
|
|
|
|
fond_stats.imusch = _getval_float_or_none(row, 2)
|
|
fond_stats.kapital = _getval_float_or_none(row, 3)
|
|
fond_stats.ioud = _getval_float_or_none(row, 4)
|
|
fond_stats.pens_rezerv = _getval_float_or_none(row, 5)
|
|
fond_stats.pens_nakopl = _getval_float_or_none(row, 6)
|
|
fond_stats.obyazat = _getval_float_or_none(row, 7)
|
|
fond_stats.pens_nakopl_rynok = _getval_float_or_none(row, 8)
|
|
fond_stats.num_zastrah = _getval_int_or_none(row, 9)
|
|
fond_stats.num_zastrah_pens = _getval_int_or_none(row, 10)
|
|
fond_stats.pens_ops = _getval_float_or_none(row, 11)
|
|
fond_stats.num_chel = _getval_int_or_none(row, 12)
|
|
fond_stats.num_chel_pens = _getval_int_or_none(row, 13)
|
|
fond_stats.vyplat_npo = _getval_float_or_none(row, 14)
|
|
fond_stats.dohod_razmesch = _getval_float_or_none(row, 15)
|
|
fond_stats.dohod_invest = _getval_float_or_none(row, 16)
|
|
|
|
fond_stats.save()
|
|
except:
|
|
if DEBUG_IMPORT:
|
|
raise
|
|
else:
|
|
import_errors.append(rx + 1)
|
|
|
|
if rx + 1 > len(import_errors):
|
|
wrong_file = False
|
|
else:
|
|
wrong_file = True
|
|
|
|
return render(request, 'admin/npfs/fond_stats.html',
|
|
{
|
|
'form': form,
|
|
'import_errors': import_errors,
|
|
'err_license_not_found': err_license_not_found,
|
|
'xls': xls_file,
|
|
'wrong_file': wrong_file,
|
|
},
|
|
)
|
|
|