From eb4e82d03fd8c6df70c112ef205c7d97076d3044 Mon Sep 17 00:00:00 2001 From: Dmitry Novikov Date: Thu, 8 Nov 2018 17:01:41 +0300 Subject: [PATCH] Add ordering by Service --- abonapp/admin.py | 1 - abonapp/models.py | 203 ++++++++++++++++++++----- abonapp/templates/abonapp/peoples.html | 6 +- 3 files changed, 166 insertions(+), 44 deletions(-) diff --git a/abonapp/admin.py b/abonapp/admin.py index 9448164..cda6f48 100644 --- a/abonapp/admin.py +++ b/abonapp/admin.py @@ -9,6 +9,5 @@ admin.site.register(models.AbonTariff) admin.site.register(models.AbonStreet) admin.site.register(models.AllTimePayLog) admin.site.register(models.AbonRawPassword) -admin.site.register(models.AllPayLog) admin.site.register(models.PassportInfo) admin.site.register(models.AdditionalTelephone) diff --git a/abonapp/models.py b/abonapp/models.py index 1af42ae..79bfadc 100644 --- a/abonapp/models.py +++ b/abonapp/models.py @@ -1,29 +1,30 @@ from datetime import datetime from typing import Optional +from accounts_app.models import UserProfile, MyUserManager, BaseAccount +from bitfield import BitField from django.conf import settings from django.core import validators from django.core.validators import RegexValidator 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.shortcuts import resolve_url from django.utils import timezone 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 group_app.models import Group +from gw_app.nas_managers import SubnetQueue, NasFailedResult, NasNetworkError from ip_pool.models import NetworkModel from tariff_app.models import Tariff, PeriodicPay -from bitfield import BitField class AbonLog(models.Model): abon = models.ForeignKey('Abon', on_delete=models.CASCADE) 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) date = models.DateTimeField(auto_now_add=True) @@ -36,7 +37,11 @@ class AbonLog(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) @@ -86,19 +91,75 @@ class AbonManager(MyUserManager): 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) - 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 = ( ('icon_donkey', _('Donkey')), @@ -144,7 +205,8 @@ class Abon(BaseAccount): AbonLog.objects.create( abon=self, amount=amount, - author=current_user if isinstance(current_user, UserProfile) else None, + author=current_user if isinstance(current_user, + UserProfile) else None, comment=comment ) self.ballance += amount @@ -153,10 +215,11 @@ class Abon(BaseAccount): """ Trying to buy a service if enough money. :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 deadline: Instance of datetime.datetime. Date when service is expired. + :param deadline: Instance of datetime.datetime. Date when service is + expired. :return: Nothing """ if not isinstance(tariff, Tariff): @@ -166,7 +229,8 @@ class Abon(BaseAccount): if tariff.is_admin and author is not None: 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.tariff == tariff: @@ -217,7 +281,8 @@ class Abon(BaseAccount): return True return False - # is subscriber have access to service, view in tariff_app.custom_tariffs..manage_access() + # is subscriber have access to service, + # view in tariff_app.custom_tariffs..manage_access() def is_access(self) -> bool: if not self.is_active: return False @@ -320,11 +385,27 @@ class Abon(BaseAccount): 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')) - 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: db_table = 'passport_info' @@ -343,7 +424,13 @@ class InvoiceForPayment(models.Model): comment = models.CharField(max_length=128) date_create = models.DateTimeField(auto_now_add=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): return "%s -> %.2f" % (self.abon.username, self.amount) @@ -367,7 +454,9 @@ class AllTimePayLogManager(models.Manager): def by_days(): cur = connection.cursor() 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")' ) while True: @@ -375,16 +464,33 @@ class AllTimePayLogManager(models.Manager): if r is None: break 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" 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) 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) objects = AllTimePayLogManager() @@ -424,7 +530,11 @@ class AbonRawPassword(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( max_length=16, verbose_name=_('Telephone'), @@ -446,10 +556,18 @@ class AdditionalTelephone(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) 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): """ @@ -465,9 +583,10 @@ class PeriodicPayForId(models.Model): next_pay_date = pp.get_next_time_to_pay(self.last_pay) abon = self.account 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',)) self.last_pay = now self.next_pay = next_pay_date diff --git a/abonapp/templates/abonapp/peoples.html b/abonapp/templates/abonapp/peoples.html index 843fc3a..1432448 100644 --- a/abonapp/templates/abonapp/peoples.html +++ b/abonapp/templates/abonapp/peoples.html @@ -52,7 +52,11 @@ {% if order_by == 'house' %}{% endif %} {% trans 'Telephone' %} - {% trans 'Service' %} + + + {% trans 'Service' %} + + {% trans 'Balance' %}