Browse Source

fix bugs

devel
bashmak 8 years ago
parent
commit
ca4988896f
  1. 59
      abonapp/models.py
  2. 28
      abonapp/views.py
  3. 5
      agent/commands/dhcp.py
  4. 82
      clientsideapp/locale/ru/LC_MESSAGES/django.po
  5. 11
      clientsideapp/views.py
  6. 136
      migrate_to_0.2.py

59
abonapp/models.py

@ -5,10 +5,10 @@ from django.core import validators
from django.core.exceptions import ValidationError
from django.core.validators import RegexValidator
from django.db import models, connection, transaction
from django.db.models.signals import post_save, post_delete, pre_delete, post_init
from django.db.models.signals import post_delete, pre_delete, post_init
from django.dispatch import receiver
from django.utils import timezone
from django.utils.translation import ugettext_lazy as _
from django.utils.translation import ugettext_lazy as _, gettext
from accounts_app.models import UserProfile, MyUserManager, BaseAccount
from agent import Transmitter, AbonStruct, TariffStruct, NasFailedResult, NasNetworkError
@ -187,13 +187,6 @@ class Abon(BaseAccount):
verbose_name_plural = _('Abons')
ordering = ['fio']
# pay something
def make_pay(self, curuser, how_match_to_pay=0.0):
post_save.disconnect(abon_post_save, sender=Abon)
self.ballance -= how_match_to_pay
self.save(update_fields=['ballance'])
post_save.connect(abon_post_save, sender=Abon)
def add_ballance(self, current_user, amount, comment):
AbonLog.objects.create(
abon=self,
@ -281,6 +274,23 @@ class Abon(BaseAccount):
raise LogicError(_('Ip address already exist'))
super(Abon, self).save(*args, **kwargs)
def sync_with_nas(self, created: bool):
timeout = None
if hasattr(self, 'is_dhcp') and self.is_dhcp:
timeout = getattr(settings, 'DHCP_TIMEOUT', 14400)
agent_abon = self.build_agent_struct()
if agent_abon is None:
return True
try:
tm = Transmitter()
if created:
tm.add_user(agent_abon, ip_timeout=timeout)
else:
tm.update_user(agent_abon, ip_timeout=timeout)
except (NasFailedResult, NasNetworkError, ConnectionResetError) as e:
print('ERROR:', e)
return True
class PassportInfo(models.Model):
series = models.CharField(max_length=4, validators=[validators.integer_validator])
@ -426,14 +436,10 @@ class PeriodicPayForId(models.Model):
next_pay_date = pp.get_next_time_to_pay(self.last_pay)
abon = self.account
with transaction.atomic():
abon.make_pay(author, amount)
AbonLog.objects.create(
abon=abon, amount=-amount,
author=author,
comment=comment or _('Charge for "%(service)s"') % {
abon.add_ballance(author, -amount, comment=gettext('Charge for "%(service)s"') % {
'service': self.periodic_pay
}
)
})
abon.save(update_fields=['ballance'])
self.last_pay = now
self.next_pay = next_pay_date
self.save(update_fields=['last_pay', 'next_pay'])
@ -445,27 +451,6 @@ class PeriodicPayForId(models.Model):
db_table = 'periodic_pay_for_id'
@receiver(post_save, sender=Abon)
def abon_post_save(sender, **kwargs):
instance, created = kwargs["instance"], kwargs["created"]
timeout = None
if hasattr(instance, 'is_dhcp') and instance.is_dhcp:
timeout = getattr(settings, 'DHCP_TIMEOUT', 14400)
agent_abon = instance.build_agent_struct()
if agent_abon is None:
return True
try:
tm = Transmitter()
if created:
tm.add_user(agent_abon, ip_timeout=timeout)
else:
tm.update_user(agent_abon, ip_timeout=timeout)
except (NasFailedResult, NasNetworkError, ConnectionResetError) as e:
print('ERROR:', e)
return True
@receiver(post_delete, sender=Abon)
def abon_del_signal(sender, **kwargs):
abon = kwargs["instance"]

28
abonapp/views.py

@ -3,7 +3,7 @@ from json import dumps
from django.contrib.gis.shortcuts import render_to_text
from django.core.exceptions import PermissionDenied
from django.db import IntegrityError, ProgrammingError, transaction
from django.db.models import Count, Q, signals
from django.db.models import Count, Q
from django.shortcuts import render, redirect, get_object_or_404, resolve_url
from django.contrib.auth.decorators import login_required
from django.http import HttpResponse, HttpResponseBadRequest
@ -29,7 +29,6 @@ from guardian.shortcuts import get_objects_for_user, assign_perm
from guardian.decorators import permission_required_or_403 as permission_required
from djing.global_base_views import OrderingMixin
PAGINATION_ITEMS_PER_PAGE = getattr(settings, 'PAGINATION_ITEMS_PER_PAGE', 10)
@ -110,6 +109,7 @@ def addabon(request, gid):
assign_perm("abonapp.can_buy_tariff", request.user, abon)
assign_perm("abonapp.can_view_passport", request.user, abon)
assign_perm('abonapp.can_add_ballance', request.user, abon)
abon.sync_with_nas(created=True)
messages.success(request, _('create abon success msg'))
return redirect('abonapp:abon_home', group.id, abon.pk)
else:
@ -145,6 +145,7 @@ def del_abon(request):
raise PermissionDenied
gid = abon.group.id
abon.delete()
abon.sync_with_nas(created=False)
messages.success(request, _('delete abon success msg'))
return mydefs.res_success(request, resolve_url('abonapp:people_list', gid=gid))
@ -264,7 +265,8 @@ def abonhome(request, gid, uid):
newip = request.POST.get('ip')
if newip:
abon.ip_address = newip
frm.save()
abon = frm.save()
abon.sync_with_nas(created=False)
messages.success(request, _('edit abon success msg'))
else:
messages.warning(request, _('fix form errors'))
@ -370,6 +372,7 @@ def pick_tariff(request, gid, uid):
deadline = datetime.strptime(deadline, '%Y-%m-%d')
deadline += timedelta(hours=23, minutes=59, seconds=59)
abon.pick_tariff(trf, request.user, deadline=deadline, comment=log_comment)
abon.sync_with_nas(created=False)
messages.success(request, _('Tariff has been picked'))
return redirect('abonapp:abon_services', gid=gid, uid=abon.id)
except (mydefs.LogicError, NasFailedResult) as e:
@ -397,8 +400,10 @@ def pick_tariff(request, gid, uid):
@permission_required('abonapp.delete_abontariff')
def unsubscribe_service(request, gid, uid, abon_tariff_id):
try:
abon = get_object_or_404(models.Abon, pk=uid)
abon_tariff = get_object_or_404(models.AbonTariff, pk=int(abon_tariff_id))
abon_tariff.delete()
abon.sync_with_nas(created=False)
messages.success(request, _('User has been detached from service'))
except NasFailedResult as e:
messages.error(request, e)
@ -681,12 +686,15 @@ def abon_ping(request):
loses_percent = (ping_result[0] / ping_result[1] if ping_result[1] != 0 else 1)
ping_result = {'all': ping_result[0], 'return': ping_result[1]}
if loses_percent > 1.0:
text = '<span class="glyphicon glyphicon-exclamation-sign"></span> %s' % _('IP Conflict! %(all)d/%(return)d results') % ping_result
text = '<span class="glyphicon glyphicon-exclamation-sign"></span> %s' % _(
'IP Conflict! %(all)d/%(return)d results') % ping_result
elif loses_percent > 0.5:
text = '<span class="glyphicon glyphicon-ok"></span> %s' % _('ok ping, %(all)d/%(return)d loses') % ping_result
text = '<span class="glyphicon glyphicon-ok"></span> %s' % _(
'ok ping, %(all)d/%(return)d loses') % ping_result
status = True
else:
text = '<span class="glyphicon glyphicon-exclamation-sign"></span> %s' % _('no ping, %(all)d/%(return)d loses') % ping_result
text = '<span class="glyphicon glyphicon-exclamation-sign"></span> %s' % _(
'no ping, %(all)d/%(return)d loses') % ping_result
else:
text = '<span class="glyphicon glyphicon-ok"></span> %s' % _('ping ok') + ' ' + str(ping_result)
status = True
@ -760,7 +768,8 @@ def save_user_dev_port(request, gid, uid):
other_abon = models.Abon.objects.get(device=abon.device, dev_port=port)
if other_abon != abon:
user_url = resolve_url('abonapp:abon_home', other_abon.group.id, other_abon.id)
messages.error(request, _("<a href='%(user_url)s'>%(user_name)s</a> already pinned to this port on this device") % {
messages.error(request, _(
"<a href='%(user_url)s'>%(user_name)s</a> already pinned to this port on this device") % {
'user_url': user_url,
'user_name': other_abon.get_full_name()
})
@ -899,7 +908,8 @@ def tel_del(request, gid, uid):
def phonebook(request, gid):
res_format = request.GET.get('f')
t1 = models.Abon.objects.filter(group__id=int(gid)).only('telephone', 'fio').values_list('telephone', 'fio')
t2 = models.AdditionalTelephone.objects.filter(abon__group__id=gid).only('telephone', 'owner_name').values_list('telephone', 'owner_name')
t2 = models.AdditionalTelephone.objects.filter(abon__group__id=gid).only('telephone', 'owner_name').values_list(
'telephone', 'owner_name')
tels = list(t1) + list(t2)
if res_format == 'csv':
import csv
@ -955,10 +965,8 @@ def abon_export(request, gid):
@permission_required('group_app.can_view_group', (Group, 'pk', 'gid'))
def reset_ip(request, gid, uid):
abon = get_object_or_404(models.Abon, pk=uid)
signals.post_save.disconnect(models.abon_post_save, sender=models.Abon)
abon.ip_address = None
abon.save(update_fields=['ip_address'])
signals.post_save.connect(models.abon_post_save, sender=models.Abon)
return HttpResponse(dumps({
'status': 0,
'dat': "<span class='glyphicon glyphicon-refresh'></span>"

5
agent/commands/dhcp.py

@ -21,9 +21,8 @@ def dhcp_commit(client_ip, client_mac, switch_mac, switch_port):
print('D:', 'User %s is not access to service' % abon.username)
return
abon.ip_address = client_ip
abon.is_dhcp = True
abon.save(update_fields=['ip_address'])
# print('S:', _("Ip address:'%s' update for '%s' successfull, on port: %s") % (client_ip, abon.get_short_name(), port))
abon.sync_with_nas(created=False)
except Abon.DoesNotExist:
print('N:', "User with device '%s' does not exist" % dev)
except Device.DoesNotExist:
@ -41,8 +40,8 @@ def dhcp_expiry(client_ip):
try:
abon = Abon.objects.get(ip_address=client_ip)
abon.ip_address = None
abon.is_dhcp = True
abon.save(update_fields=['ip_address'])
abon.sync_with_nas(created=False)
except Abon.DoesNotExist:
pass

82
clientsideapp/locale/ru/LC_MESSAGES/django.po

@ -8,7 +8,7 @@ msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2017-02-28 12:46+0300\n"
"POT-Creation-Date: 2018-03-08 14:24+0300\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: Dmitry Novikov nerosketch@gmail.com\n"
"Language: ru\n"
@ -19,19 +19,19 @@ msgstr ""
"%10<=4 && (n%100<12 || n%100>14) ? 1 : n%10==0 || (n%10>=5 && n%10<=9) || (n"
"%100>=11 && n%100<=14)? 2 : 3);\n"
#: clientsideapp/templates/clientsideapp/debt_buy.html:6
#: templates/clientsideapp/debt_buy.html:6
msgid "Debts"
msgstr "Задолженность"
#: clientsideapp/templates/clientsideapp/debt_buy.html:11
#: templates/clientsideapp/debt_buy.html:11
msgid "repayment of debts"
msgstr "Оплатить задолженность"
#: clientsideapp/templates/clientsideapp/debt_buy.html:18
#: templates/clientsideapp/debt_buy.html:18
msgid "Are you sure you want to spend a payment?"
msgstr "Вы уверены что хотите провести платёж?"
#: clientsideapp/templates/clientsideapp/debt_buy.html:21
#: templates/clientsideapp/debt_buy.html:21
#, fuzzy, python-format
#| msgid ""
#| "From your account, they withdraw funds in <b>%(amount)s</b> rub. <br/>\n"
@ -48,92 +48,86 @@ msgstr ""
"В результате у вас на счету останется %(ballance_after)s руб.<br/>\n"
"Администратор сразу сможет видеть что у вас закрыта задолженность."
#: clientsideapp/templates/clientsideapp/debt_buy.html:24
#: templates/clientsideapp/debt_buy.html:24
msgid "Description of payment"
msgstr "Описание платежа"
#: clientsideapp/templates/clientsideapp/debt_buy.html:32
#: templates/clientsideapp/debt_buy.html:32
msgid "Confirm"
msgstr "Подтвердить"
#: clientsideapp/templates/clientsideapp/debt_buy.html:35
#: templates/clientsideapp/debt_buy.html:35
msgid "Cancel"
msgstr "Отменить"
#: clientsideapp/templates/clientsideapp/modal_service_buy.html:5
#: templates/clientsideapp/modal_service_buy.html:5
msgid "Pick service"
msgstr "Заказать услугу"
#: clientsideapp/templates/clientsideapp/modal_service_buy.html:8
#: templates/clientsideapp/modal_service_buy.html:8
msgid "Are you sure you want to order the service?"
msgstr "Вы уверены что хотите заказать услугу?"
#: templates/clientsideapp/modal_service_buy.html:15
#, python-format
msgid ""
"Inbound speed: %(speedIn)s MBit/s<br>\n"
"Outgoing speed: %(speedOut)s MBit/s<br>\n"
"Cost: %(amount)s rubles."
msgstr ""
#: clientsideapp/templates/clientsideapp/modal_service_buy.html:28
#: templates/clientsideapp/modal_service_buy.html:22
#: templates/clientsideapp/services.html:59
msgid "Pick"
msgstr "Заказать"
#: clientsideapp/templates/clientsideapp/modal_service_buy.html:30
#: templates/clientsideapp/modal_service_buy.html:24
msgid "Close"
msgstr "Закрыть"
#: clientsideapp/templates/clientsideapp/pays.html:6
#: templates/clientsideapp/pays.html:6
msgid "conducted payments"
msgstr "Проведённые платежи"
#: clientsideapp/templates/clientsideapp/pays.html:11
#: templates/clientsideapp/pays.html:11
msgid "Transaction Amount (rubles)"
msgstr "Сумма транзакции (руб)"
#: clientsideapp/templates/clientsideapp/pays.html:12
#: templates/clientsideapp/pays.html:12
msgid "Date of transaction"
msgstr "Дата транзакции"
#: clientsideapp/templates/clientsideapp/pays.html:13
#: templates/clientsideapp/pays.html:13
msgid "Comment"
msgstr "Комментарий"
#: clientsideapp/templates/clientsideapp/pays.html:25
#: templates/clientsideapp/pays.html:25
msgid "You have not spent payments"
msgstr "У вас нет проведённых платежей"
#: clientsideapp/views.py:53
#: templates/clientsideapp/services.html:25
msgid "currency"
msgstr ""
#: views.py:51
#, python-format
msgid "Buy the service via user side, service '%s'"
msgstr "Покупка тарифного плана через личный кабинет, тариф '%s'"
#: clientsideapp/views.py:82
#, python-format
msgid "Service '%s' has been finished"
msgstr "Услуга '%s' успешно завершена"
#: clientsideapp/views.py:87
#, python-format
msgid "Early terminated service '%s' via client side"
msgstr "Досрочное завершение услуги '%s' из личного кабинета"
#: clientsideapp/views.py:90 clientsideapp/views.py:119
#: clientsideapp/views.py:147
msgid "Act is not confirmed"
msgstr "Действие не подтверждено"
#: clientsideapp/views.py:103 clientsideapp/views.py:130
msgid "Temporary network bug"
msgstr "Временные неполадки в сети"
#: clientsideapp/views.py:126
msgid "The service was not found"
msgstr "Указанная подписка на услугу не найдена"
#: clientsideapp/views.py:145
#: views.py:54
#, python-format
msgid "The service '%s' wan successfully activated"
msgstr "Услуга '%s' успешно подключена"
#: clientsideapp/views.py:181
#: views.py:84
msgid "Are you not sure that you want buy the service?"
msgstr "Вы не уверены что хотите оплатить долг?"
#: clientsideapp/views.py:183
#: views.py:86
msgid "Your account have not enough money"
msgstr "Недостаточно средств на счету"
#: views.py:90
#, python-format
msgid "%(username)s paid the debt %(amount).2f"
msgstr "%(username)s заплатил долг в размере %(amount).2f"

11
clientsideapp/views.py

@ -4,7 +4,7 @@ from django.contrib.gis.shortcuts import render_to_text
from django.shortcuts import render, get_object_or_404, redirect
from django.contrib import messages
from django.db import transaction
from django.utils.translation import gettext_lazy as _
from django.utils.translation import gettext_lazy as _, gettext
from abonapp.models import AbonLog, InvoiceForPayment, Abon
from tariff_app.models import Tariff
@ -50,6 +50,7 @@ def buy_service(request, srv_id):
if request.method == 'POST':
abon.pick_tariff(service, request.user, _("Buy the service via user side, service '%s'")
% service)
abon.abon.sync_with_nas(created=False)
messages.success(request, _("The service '%s' wan successfully activated") % service.title)
else:
return render_to_text('clientsideapp/modal_service_buy.html', {
@ -84,9 +85,13 @@ def debt_buy(request, d_id):
if abon.ballance < debt.amount:
raise LogicError(_('Your account have not enough money'))
abon.make_pay(request.user, debt.amount)
debt.set_ok()
amount = -debt.amount
abon.add_ballance(request.user, amount, comment=gettext('%(username)s paid the debt %(amount).2f') % {
'username': abon.get_full_name(),
'amount': amount
})
abon.save(update_fields=['ballance'])
debt.set_ok()
debt.save(update_fields=['status', 'date_pay'])
return redirect('client_side:debts')
except LogicError as e:

136
migrate_to_0.2.py

@ -1,136 +0,0 @@
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
import os
from json import dump
import django
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "djing.settings")
django.setup()
from django.db.models import fields as django_fields
def get_fixture_from_unchanget_model(model_name: str, model_class):
"""
Создаёт фикстуру если модели между версиями не изменились
:param model_name: str 'app_label.model_name'
:param model_class: Model модель для которой надо сделать фикстуру
:return: список словарей
"""
print(model_name)
def get_fields(obj):
fields = dict()
for field in obj._meta.get_fields():
if isinstance(field, django_fields.reverse_related.ManyToOneRel) or \
isinstance(field, django_fields.reverse_related.ManyToManyRel):
continue
field_val = getattr(obj, field.name)
if field_val is None:
continue
if isinstance(field, django_fields.related.ManyToManyField):
fields[field.name] = [f.pk for f in field_val.all()]
elif isinstance(field, django_fields.related.ForeignKey):
fields[field.name] = field_val.pk
elif isinstance(field, django_fields.FloatField):
fields[field.name] = float(field_val)
elif isinstance(field, django_fields.DateTimeField):
fields[field.name] = str(field_val)
elif isinstance(field, django_fields.AutoField):
continue
else:
fields[field.name] = field_val
return fields
res = [{
'model': model_name,
'pk': obj.pk,
'fields': get_fields(obj)
} for obj in model_class.objects.all()]
return res
def dump_abonapp():
from abonapp import models
res = [{
'model': 'group_app.group',
'pk': abon_group.pk,
'fields': {
'title': abon_group.title
}
} for abon_group in models.AbonGroup.objects.all()]
#res += get_fixture_from_unchanget_model('abonapp.abonlog', models.AbonLog)
res += get_fixture_from_unchanget_model('abonapp.abontariff', models.AbonTariff)
res += get_fixture_from_unchanget_model('abonapp.abonstreet', models.AbonStreet)
res += get_fixture_from_unchanget_model('abonapp.extrafieldsmodel', models.ExtraFieldsModel)
res += get_fixture_from_unchanget_model('abonapp.abon', models.Abon)
'''res += [{
'model': 'abonapp.abon',
'pk': ab.pk,
'fields': {
'current_tariff': ab.current_tariff.pk,
'group': ab.group.pk,
'ballance': ab.ballance,
'ip_address': ab.ip_address,
'description': ab.description,
'street': ab.street,
'house': ab.house,
'extra_fields': [pid.pk for pid in ab.extra_fields.all()],
'device': ab.device.pk,
'dev_port': ab.dev_port.pk,
'is_dynamic_ip': ab.is_dynamic_ip
}
} for ab in models.Abon.objects.all()]'''
res += get_fixture_from_unchanget_model('abonapp.passportinfo', models.PassportInfo)
res += get_fixture_from_unchanget_model('abonapp.invoiceforpayment', models.InvoiceForPayment)
res += get_fixture_from_unchanget_model('abonapp.alltimepaylog', models.AllTimePayLog)
res += get_fixture_from_unchanget_model('abonapp.abonrawpassword', models.AbonRawPassword)
res += get_fixture_from_unchanget_model('abonapp.additionaltelephone', models.AdditionalTelephone)
res += get_fixture_from_unchanget_model('abonapp.periodicpayforid', models.PeriodicPayForId)
return res
def dump_tariffs():
from tariff_app import models
res = get_fixture_from_unchanget_model('tariff_app.Tariff', models.Tariff)
res += get_fixture_from_unchanget_model('tariff_app.periodicpay', models.PeriodicPay)
return res
def dump_devs():
pass
#from devapp import models
def make_migration():
from datetime import datetime
from datetime import date
def my_date_converter(o):
if isinstance(o, datetime) or isinstance(o, date):
return "%s" % o
def appdump(fname, func):
with open(fname, 'w') as f:
dump(func(), f, default=my_date_converter, ensure_ascii=False)
appdump('abon_fixture.json', dump_abonapp)
appdump('tariffs_fixture.json', dump_tariffs)
if __name__ == '__main__':
make_migration()
Loading…
Cancel
Save