Browse Source

Add ordering by Service

devel
Dmitry Novikov 7 years ago
parent
commit
eb4e82d03f
  1. 1
      abonapp/admin.py
  2. 203
      abonapp/models.py
  3. 6
      abonapp/templates/abonapp/peoples.html

1
abonapp/admin.py

@ -9,6 +9,5 @@ admin.site.register(models.AbonTariff)
admin.site.register(models.AbonStreet) admin.site.register(models.AbonStreet)
admin.site.register(models.AllTimePayLog) admin.site.register(models.AllTimePayLog)
admin.site.register(models.AbonRawPassword) admin.site.register(models.AbonRawPassword)
admin.site.register(models.AllPayLog)
admin.site.register(models.PassportInfo) admin.site.register(models.PassportInfo)
admin.site.register(models.AdditionalTelephone) admin.site.register(models.AdditionalTelephone)

203
abonapp/models.py

@ -1,29 +1,30 @@
from datetime import datetime from datetime import datetime
from typing import Optional from typing import Optional
from accounts_app.models import UserProfile, MyUserManager, BaseAccount
from bitfield import BitField
from django.conf import settings from django.conf import settings
from django.core import validators from django.core import validators
from django.core.validators import RegexValidator from django.core.validators import RegexValidator
from django.db import models, connection, transaction from django.db import models, connection, transaction
from django.db.models.signals import post_delete, pre_delete, post_init, pre_save
from django.db.models.signals import post_delete, pre_delete, post_init, \
pre_save
from django.dispatch import receiver from django.dispatch import receiver
from django.shortcuts import resolve_url from django.shortcuts import resolve_url
from django.utils import timezone from django.utils import timezone
from django.utils.translation import ugettext_lazy as _, gettext from django.utils.translation import ugettext_lazy as _, gettext
from accounts_app.models import UserProfile, MyUserManager, BaseAccount
from gw_app.nas_managers import SubnetQueue, NasFailedResult, NasNetworkError
from group_app.models import Group
from djing.lib import LogicError from djing.lib import LogicError
from group_app.models import Group
from gw_app.nas_managers import SubnetQueue, NasFailedResult, NasNetworkError
from ip_pool.models import NetworkModel from ip_pool.models import NetworkModel
from tariff_app.models import Tariff, PeriodicPay from tariff_app.models import Tariff, PeriodicPay
from bitfield import BitField
class AbonLog(models.Model): class AbonLog(models.Model):
abon = models.ForeignKey('Abon', on_delete=models.CASCADE) abon = models.ForeignKey('Abon', on_delete=models.CASCADE)
amount = models.FloatField(default=0.0) amount = models.FloatField(default=0.0)
author = models.ForeignKey(UserProfile, on_delete=models.CASCADE, related_name='+', blank=True, null=True)
author = models.ForeignKey(UserProfile, on_delete=models.CASCADE,
related_name='+', blank=True, null=True)
comment = models.CharField(max_length=128) comment = models.CharField(max_length=128)
date = models.DateTimeField(auto_now_add=True) date = models.DateTimeField(auto_now_add=True)
@ -36,7 +37,11 @@ class AbonLog(models.Model):
class AbonTariff(models.Model): class AbonTariff(models.Model):
tariff = models.ForeignKey(Tariff, on_delete=models.CASCADE, related_name='linkto_tariff')
tariff = models.ForeignKey(
Tariff,
on_delete=models.CASCADE,
related_name='linkto_tariff'
)
time_start = models.DateTimeField(null=True, blank=True, default=None) time_start = models.DateTimeField(null=True, blank=True, default=None)
@ -86,19 +91,75 @@ class AbonManager(MyUserManager):
class Abon(BaseAccount): class Abon(BaseAccount):
current_tariff = models.OneToOneField(AbonTariff, null=True, blank=True, on_delete=models.SET_NULL, default=None)
group = models.ForeignKey(Group, on_delete=models.SET_NULL, blank=True, null=True, verbose_name=_('User group'))
current_tariff = models.OneToOneField(
AbonTariff,
null=True,
blank=True,
on_delete=models.SET_NULL,
default=None
)
group = models.ForeignKey(
Group,
on_delete=models.SET_NULL,
blank=True, null=True,
verbose_name=_('User group')
)
ballance = models.FloatField(default=0.0) ballance = models.FloatField(default=0.0)
ip_address = models.GenericIPAddressField(verbose_name=_('Ip address'), null=True, blank=True)
description = models.TextField(_('Comment'), null=True, blank=True)
street = models.ForeignKey(AbonStreet, on_delete=models.SET_NULL, null=True, blank=True, verbose_name=_('Street'))
house = models.CharField(_('House'), max_length=12, null=True, blank=True)
device = models.ForeignKey('devapp.Device', null=True, blank=True, on_delete=models.SET_NULL)
dev_port = models.ForeignKey('devapp.Port', null=True, blank=True, on_delete=models.SET_NULL)
is_dynamic_ip = models.BooleanField(_('Is dynamic ip'), default=False)
nas = models.ForeignKey('gw_app.NASModel', null=True, blank=True, on_delete=models.SET_NULL,
verbose_name=_('Network access server'), default=None)
autoconnect_service = models.BooleanField(_('Automatically connect next service'), default=False)
ip_address = models.GenericIPAddressField(
verbose_name=_('Ip address'),
null=True,
blank=True
)
description = models.TextField(
_('Comment'),
null=True,
blank=True
)
street = models.ForeignKey(
AbonStreet,
on_delete=models.SET_NULL,
null=True,
blank=True,
verbose_name=_('Street')
)
house = models.CharField(
_('House'),
max_length=12,
null=True,
blank=True
)
device = models.ForeignKey(
'devapp.Device',
null=True,
blank=True,
on_delete=models.SET_NULL
)
dev_port = models.ForeignKey(
'devapp.Port',
null=True,
blank=True,
on_delete=models.SET_NULL
)
is_dynamic_ip = models.BooleanField(
_('Is dynamic ip'),
default=False
)
nas = models.ForeignKey(
'gw_app.NASModel',
null=True,
blank=True,
on_delete=models.SET_NULL,
verbose_name=_('Network access server'),
default=None
)
autoconnect_service = models.BooleanField(
_('Automatically connect next service'),
default=False
)
# last_connected_tariff = models.ForeignKey(
# Tariff, verbose_name=_('Last connected service'),
# on_delete=models.CASCADE, null=True, blank=True, default=None
# )
MARKER_FLAGS = ( MARKER_FLAGS = (
('icon_donkey', _('Donkey')), ('icon_donkey', _('Donkey')),
@ -144,7 +205,8 @@ class Abon(BaseAccount):
AbonLog.objects.create( AbonLog.objects.create(
abon=self, abon=self,
amount=amount, amount=amount,
author=current_user if isinstance(current_user, UserProfile) else None,
author=current_user if isinstance(current_user,
UserProfile) else None,
comment=comment comment=comment
) )
self.ballance += amount self.ballance += amount
@ -153,10 +215,11 @@ class Abon(BaseAccount):
""" """
Trying to buy a service if enough money. Trying to buy a service if enough money.
:param tariff: instance of tariff_app.models.Tariff. :param tariff: instance of tariff_app.models.Tariff.
:param author: Instance of accounts_app.models.UserProfile. Who connected this
service. May be None if author is a system.
:param author: Instance of accounts_app.models.UserProfile.
Who connected this service. May be None if author is a system.
:param comment: Optional text for logging this pay. :param comment: Optional text for logging this pay.
:param deadline: Instance of datetime.datetime. Date when service is expired.
:param deadline: Instance of datetime.datetime. Date when service is
expired.
:return: Nothing :return: Nothing
""" """
if not isinstance(tariff, Tariff): if not isinstance(tariff, Tariff):
@ -166,7 +229,8 @@ class Abon(BaseAccount):
if tariff.is_admin and author is not None: if tariff.is_admin and author is not None:
if not author.is_staff: if not author.is_staff:
raise LogicError(_('User that is no staff can not buy admin services'))
raise LogicError(
_('User that is no staff can not buy admin services'))
if self.current_tariff is not None: if self.current_tariff is not None:
if self.current_tariff.tariff == tariff: if self.current_tariff.tariff == tariff:
@ -217,7 +281,8 @@ class Abon(BaseAccount):
return True return True
return False return False
# is subscriber have access to service, view in tariff_app.custom_tariffs.<TariffBase>.manage_access()
# is subscriber have access to service,
# view in tariff_app.custom_tariffs.<TariffBase>.manage_access()
def is_access(self) -> bool: def is_access(self) -> bool:
if not self.is_active: if not self.is_active:
return False return False
@ -320,11 +385,27 @@ class Abon(BaseAccount):
class PassportInfo(models.Model): class PassportInfo(models.Model):
series = models.CharField(_('Pasport serial'), max_length=4, validators=(validators.integer_validator,))
number = models.CharField(_('Pasport number'), max_length=6, validators=(validators.integer_validator,))
distributor = models.CharField(_('Distributor'), max_length=64)
series = models.CharField(
_('Pasport serial'),
max_length=4,
validators=(validators.integer_validator,)
)
number = models.CharField(
_('Pasport number'),
max_length=6,
validators=(validators.integer_validator,)
)
distributor = models.CharField(
_('Distributor'),
max_length=64
)
date_of_acceptance = models.DateField(_('Date of acceptance')) date_of_acceptance = models.DateField(_('Date of acceptance'))
abon = models.OneToOneField(Abon, on_delete=models.CASCADE, blank=True, null=True)
abon = models.OneToOneField(
Abon,
on_delete=models.CASCADE,
blank=True,
null=True
)
class Meta: class Meta:
db_table = 'passport_info' db_table = 'passport_info'
@ -343,7 +424,13 @@ class InvoiceForPayment(models.Model):
comment = models.CharField(max_length=128) comment = models.CharField(max_length=128)
date_create = models.DateTimeField(auto_now_add=True) date_create = models.DateTimeField(auto_now_add=True)
date_pay = models.DateTimeField(blank=True, null=True) date_pay = models.DateTimeField(blank=True, null=True)
author = models.ForeignKey(UserProfile, related_name='+', on_delete=models.SET_NULL, blank=True, null=True)
author = models.ForeignKey(
UserProfile,
related_name='+',
on_delete=models.SET_NULL,
blank=True,
null=True
)
def __str__(self): def __str__(self):
return "%s -> %.2f" % (self.abon.username, self.amount) return "%s -> %.2f" % (self.abon.username, self.amount)
@ -367,7 +454,9 @@ class AllTimePayLogManager(models.Manager):
def by_days(): def by_days():
cur = connection.cursor() cur = connection.cursor()
cur.execute( cur.execute(
'SELECT SUM(summ) AS alsum, DATE_FORMAT(date_add, "%Y-%m-%d") AS pay_date FROM all_time_pay_log '
'SELECT SUM(summ) AS alsum, '
'DATE_FORMAT(date_add, "%Y-%m-%d") AS pay_date '
'FROM all_time_pay_log '
'GROUP BY DATE_FORMAT(date_add, "%Y-%m-%d")' 'GROUP BY DATE_FORMAT(date_add, "%Y-%m-%d")'
) )
while True: while True:
@ -375,16 +464,33 @@ class AllTimePayLogManager(models.Manager):
if r is None: if r is None:
break break
summ, dat = r summ, dat = r
yield {'summ': summ, 'pay_date': datetime.strptime(dat, '%Y-%m-%d')}
yield {'summ': summ,
'pay_date': datetime.strptime(dat, '%Y-%m-%d')}
# Log for pay system "AllTime" # Log for pay system "AllTime"
class AllTimePayLog(models.Model): class AllTimePayLog(models.Model):
abon = models.ForeignKey(Abon, on_delete=models.SET_DEFAULT, blank=True, null=True, default=None)
pay_id = models.CharField(max_length=36, unique=True, primary_key=True)
abon = models.ForeignKey(
Abon,
on_delete=models.SET_DEFAULT,
blank=True,
null=True,
default=None
)
pay_id = models.CharField(
max_length=36,
unique=True,
primary_key=True
)
date_add = models.DateTimeField(auto_now_add=True) date_add = models.DateTimeField(auto_now_add=True)
summ = models.FloatField(default=0.0) summ = models.FloatField(default=0.0)
trade_point = models.CharField(_('Trade point'), max_length=20, default=None, null=True, blank=True)
trade_point = models.CharField(
_('Trade point'),
max_length=20,
default=None,
null=True,
blank=True
)
receipt_num = models.BigIntegerField(_('Receipt number'), default=0) receipt_num = models.BigIntegerField(_('Receipt number'), default=0)
objects = AllTimePayLogManager() objects = AllTimePayLogManager()
@ -424,7 +530,11 @@ class AbonRawPassword(models.Model):
class AdditionalTelephone(models.Model): class AdditionalTelephone(models.Model):
abon = models.ForeignKey(Abon, on_delete=models.CASCADE, related_name='additional_telephones')
abon = models.ForeignKey(
Abon,
on_delete=models.CASCADE,
related_name='additional_telephones'
)
telephone = models.CharField( telephone = models.CharField(
max_length=16, max_length=16,
verbose_name=_('Telephone'), verbose_name=_('Telephone'),
@ -446,10 +556,18 @@ class AdditionalTelephone(models.Model):
class PeriodicPayForId(models.Model): class PeriodicPayForId(models.Model):
periodic_pay = models.ForeignKey(PeriodicPay, on_delete=models.CASCADE, verbose_name=_('Periodic pay'))
periodic_pay = models.ForeignKey(
PeriodicPay,
on_delete=models.CASCADE,
verbose_name=_('Periodic pay')
)
last_pay = models.DateTimeField(_('Last pay time'), blank=True, null=True) last_pay = models.DateTimeField(_('Last pay time'), blank=True, null=True)
next_pay = models.DateTimeField(_('Next time to pay')) next_pay = models.DateTimeField(_('Next time to pay'))
account = models.ForeignKey(Abon, on_delete=models.CASCADE, verbose_name=_('Account'))
account = models.ForeignKey(
Abon,
on_delete=models.CASCADE,
verbose_name=_('Account')
)
def payment_for_service(self, author: UserProfile = None, now=None): def payment_for_service(self, author: UserProfile = None, now=None):
""" """
@ -465,9 +583,10 @@ class PeriodicPayForId(models.Model):
next_pay_date = pp.get_next_time_to_pay(self.last_pay) next_pay_date = pp.get_next_time_to_pay(self.last_pay)
abon = self.account abon = self.account
with transaction.atomic(): with transaction.atomic():
abon.add_ballance(author, -amount, comment=gettext('Charge for "%(service)s"') % {
'service': self.periodic_pay
})
abon.add_ballance(author, -amount, comment=gettext(
'Charge for "%(service)s"') % {
'service': self.periodic_pay
})
abon.save(update_fields=('ballance',)) abon.save(update_fields=('ballance',))
self.last_pay = now self.last_pay = now
self.next_pay = next_pay_date self.next_pay = next_pay_date

6
abonapp/templates/abonapp/peoples.html

@ -52,7 +52,11 @@
{% if order_by == 'house' %}<span class="glyphicon glyphicon-filter"></span>{% endif %} {% if order_by == 'house' %}<span class="glyphicon glyphicon-filter"></span>{% endif %}
</th> </th>
<th class="col-xs-1">{% trans 'Telephone' %}</th> <th class="col-xs-1">{% trans 'Telephone' %}</th>
<th class="col-xs-2">{% trans 'Service' %}</th>
<th class="col-xs-2">
<a href="{% url 'abonapp:people_list' group.pk %}?{% url_order_by request order_by='current_tariff__tariff' %}">
{% trans 'Service' %}
</a>
</th>
<th class="hidden-xs col-sm-1"> <th class="hidden-xs col-sm-1">
<a href="{% url 'abonapp:people_list' group.pk %}?{% url_order_by request order_by='ballance' %}"> <a href="{% url 'abonapp:people_list' group.pk %}?{% url_order_by request order_by='ballance' %}">
{% trans 'Balance' %} {% trans 'Balance' %}

Loading…
Cancel
Save