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.
113 lines
4.0 KiB
113 lines
4.0 KiB
from datetime import datetime
|
|
from django.db import models, IntegrityError
|
|
from django.utils.translation import gettext_lazy as _
|
|
from django.dispatch import receiver
|
|
from .base_intr import TariffBase, PeriodicPayCalcBase
|
|
from .custom_tariffs import TARIFF_CHOICES, PERIODIC_PAY_CHOICES
|
|
from group_app.models import Group
|
|
from mydefs import MyChoicesAdapter
|
|
from jsonfield import JSONField
|
|
|
|
|
|
class TariffManager(models.Manager):
|
|
|
|
def get_tariffs_by_group(self, group_id):
|
|
return self.filter(groups__id__in=[group_id])
|
|
|
|
|
|
class Tariff(models.Model):
|
|
title = models.CharField(_('Service title'), max_length=32)
|
|
descr = models.CharField(_('Service description'), max_length=256)
|
|
speedIn = models.FloatField(_('Speed In'), default=0.0)
|
|
speedOut = models.FloatField(_('Speed Out'), default=0.0)
|
|
amount = models.FloatField(_('Price'), default=0.0)
|
|
calc_type = models.CharField(_('Script'), max_length=2, default=TARIFF_CHOICES[0][0],
|
|
choices=MyChoicesAdapter(TARIFF_CHOICES))
|
|
is_admin = models.BooleanField(_('Tech service'), default=False)
|
|
|
|
groups = models.ManyToManyField(Group, blank=True)
|
|
|
|
objects = TariffManager()
|
|
|
|
def get_calc_type(self):
|
|
"""
|
|
:return: Child of tariff_app.base_intr.TariffBase,
|
|
methods which provide the desired logic of payments
|
|
"""
|
|
calc_code = self.calc_type
|
|
for choice_pair in TARIFF_CHOICES:
|
|
choice_code, logic_class = choice_pair
|
|
if choice_code == calc_code:
|
|
if not issubclass(logic_class, TariffBase):
|
|
raise TypeError
|
|
return logic_class
|
|
|
|
def calc_deadline(self):
|
|
calc_type = self.get_calc_type()
|
|
calc_obj = calc_type(self)
|
|
return calc_obj.calc_deadline()
|
|
|
|
def __str__(self):
|
|
return "%s (%.2f)" % (self.title, self.amount)
|
|
|
|
class Meta:
|
|
db_table = 'tariffs'
|
|
ordering = ['title']
|
|
verbose_name = _('Service')
|
|
verbose_name_plural = _('Services')
|
|
|
|
|
|
class PeriodicPay(models.Model):
|
|
name = models.CharField(_('Periodic pay name'), max_length=64)
|
|
when_add = models.DateTimeField(_('When pay created'), auto_now_add=True)
|
|
calc_type = models.CharField(_('Script type for calculations'), max_length=2, default='df',
|
|
choices=MyChoicesAdapter(PERIODIC_PAY_CHOICES))
|
|
amount = models.FloatField(_('Total amount'))
|
|
extra_info = JSONField()
|
|
|
|
def _get_calc_object(self):
|
|
"""
|
|
:return: subclass of custom_tariffs.PeriodicPayCalcBase with required
|
|
logic depending on the selected in database.
|
|
"""
|
|
calc_code = self.calc_type
|
|
for choice_pair in PERIODIC_PAY_CHOICES:
|
|
choice_code, logic_class = choice_pair
|
|
if choice_code == calc_code:
|
|
if not issubclass(logic_class, PeriodicPayCalcBase):
|
|
raise TypeError
|
|
return logic_class()
|
|
|
|
def get_next_time_to_pay(self, last_time_payment):
|
|
#
|
|
# last_time_payment may be None if it is a first payment
|
|
#
|
|
calc_obj = self._get_calc_object()
|
|
res = calc_obj.get_next_time_to_pay(self, last_time_payment)
|
|
if type(res) is not datetime:
|
|
raise TypeError
|
|
return res
|
|
|
|
def calc_amount(self):
|
|
calc_obj = self._get_calc_object()
|
|
res = calc_obj.calc_amount(self)
|
|
if type(res) is not float:
|
|
raise TypeError
|
|
return res
|
|
|
|
def __str__(self):
|
|
return self.name
|
|
|
|
class Meta:
|
|
db_table = 'periodic_pay'
|
|
permissions = (
|
|
('can_view_periodic_pay', _('Can view periodic pay')),
|
|
)
|
|
verbose_name = _('Periodic pay')
|
|
verbose_name_plural = _('Periodic pays')
|
|
ordering = ['-id']
|
|
|
|
|
|
@receiver(models.signals.pre_delete, sender=PeriodicPay)
|
|
def periodic_pay_pre_delete(sender, **kwargs):
|
|
raise IntegrityError('All linked abonapp.PeriodicPayForId will be removed, be careful')
|