Django рассчитать сложный процент для всех объектов в модели - PullRequest
0 голосов
/ 13 февраля 2020

Использование Python 3.8.1 и Django 3.0.1.

Я занят финансовым приложением для отслеживания непогашенных дебетов и расчета процентов по непогашенным остаткам.

У меня есть три модели:

  • Должник - который содержит личную информацию клиента, а также применимую процентную ставку, период начисления процентов и т. Д. c.
  • DebtorAccount - создается всякий раз, когда новый клиент создан. Он также поддерживает текущий баланс и начисленные проценты.
  • DebtorTransaction - записывает тип описания транзакции, дебет / кредит, сумму и т. Д. c.

models.py

class Debtor(models.Model):
    name = models.CharField(max_length=200, default="")
    period = models.DecimalField(max_digits=100, decimal_places=2, default=0, null=True)
    interestrate = models.DecimalField(max_digits=100, decimal_places=2, default=0, null=True, blank=True)

    def __str__(self):
        return self.name


@property
def unique_id(self):
    return str(self.pk)


class DebtorAccount(models.Model):
    accountname = models.OneToOneField(Debtor, on_delete=models.CASCADE)
    balance = models.DecimalField(max_digits=100, decimal_places=2, default=0)
    interest = models.DecimalField(max_digits=100, decimal_places=2, default=0)
    rate = models.DecimalField(max_digits=100, decimal_places=2, default=0)
    period = models.DecimalField(max_digits=100, decimal_places=2, default=0)

    def __str__(self):
        return str(self.accountname)


def create_debtoraccount(sender, **kwargs):
    if kwargs['created']:
        debtor_account = DebtorAccount.objects.create(accountname=kwargs['instance'])


post_save.connect(create_debtoraccount, sender=Debtor)


class DebtorTransaction(models.Model):
    CREDIT = 'CREDIT'
    DEBIT = 'DEBIT'
    TRANSACTION_TYPES = (
        ("CREDIT", "Credit"),
        ("DEBIT", "Debit"),
    )

    debtor = models.ForeignKey(DebtorAccount, on_delete=models.CASCADE, blank=True, null=True)
    amount = models.DecimalField(max_digits=100, decimal_places=2, default=0)
    description = models.CharField(max_length=200, blank=True, default="Transaction Description")
    date = models.DateTimeField(auto_now_add=True)
    type = models.CharField(choices=TRANSACTION_TYPES, max_length=6)
    transaction_balance = models.DecimalField(max_digits=100, decimal_places=2, default=0, null=True, blank=True)

    def __str__(self):
        return str(self.debtor)


    @property
    def calculate_interest(user_account):
        user_account = DebtorAccount.objects.all()
        for account in user_account:
            user_interest = (account.balance * (1 + (account.rate / account.period))) - account.balance
            account.save()
            return user_interest

    @property
    def get_transaction_balance(self):
        user_account = DebtorAccount.objects.get(accountname=self.debtor.id)
        if self.type == DebtorTransaction.DEBIT:
            user_balance = user_account.balance + self.amount + self.initiationfee
        else:
            user_balance = user_account.balance - self.amount
        return user_balance


    def save(self, *args, **kwargs):
        self.interest = self.calculate_interest
        self.transaction_balance = self.get_transaction_balance
        super(DebtorTransaction, self).save(*args, **kwargs)


@receiver(post_save, sender=DebtorTransaction, dispatch_uid="transaction log entry")
def update_user_account(sender, instance, **kwargs):
    user_account = DebtorAccount.objects.get(accountname=instance.debtor.id)
    if instance.type == DebtorTransaction.CREDIT:
        user_account.balance = F('balance') - instance.amount
    else:
        user_account.balance = F('balance') + instance.amount

    user_account.save()

Примеры таблиц

Таблица клиентов

Таблица транзакций

Я использую Django Таблицы2 для отображения клиентов и транзакций. Я не знаю, было ли необходимо иметь функцию get_transaction_balance, но это был единственный способ получить текущий баланс с транзакцией в таблице транзакций.

Теперь я хочу рассчитать начисленные проценты по непогашенному остатку для каждого клиента. Я хочу, чтобы это автоматически рассчитывалось в первый день каждого месяца для каждого клиента. Из того, что я прочитал, Celery - лучший способ сделать это sh, но я раньше этим не пользовался и еще не начал исследования.

Пока я просто хочу рассчитать проценты по непогашенный остаток каждого клиента. Позже я также уточню формулу процента, чтобы скорректировать для разных периодов начисления процентов для разных клиентов.

Я полностью застрял в том, как выполнить sh это. Функция Подсчитать проценты - это моя последняя попытка решить эту проблему, но она не работает.

Проценты рассчитываются только на непогашенный остаток последнего клиента и затем применяются к указанному экземпляру c. Он не рассчитывается для каждого клиента в отдельности и сохраняется.

Я знаю, что проблема с моим для l oop и когда метод сохранения перезаписывается. Я просто не знаю, как ее решить.

Как рассчитать проценты по непогашенному остатку на каждого клиента?

1 Ответ

0 голосов
/ 14 февраля 2020

Ваша непосредственная проблема заключается в том, что вы рассчитываете проценты только для первого экземпляра DebtorAccount, а затем возвращаете. Однако я не очень понимаю, почему это свойство, которое выполняет вычисления. Это должен быть метод, чтобы пользователь знал, что данные изменяются. Свойство изменяет данные необычно.

@property
def calculate_interest(self): # Use the self argument for properties.
    user_accounts = DebtorAccount.objects.all()
    for account in user_accounts:
        # No need for both the subtraction and the 1 + portion.
        user_interest = account.balance * (account.rate / account.period)
        account.save()
    return # I don't know what you want to return from this

Кроме того, я действительно не знаю, почему свойство в одном экземпляре DebtorTransaction может изменить полностью не связанные экземпляры DebtorAccount. Возможно, вы хотите сделать:

def calculate_interest(self):
    account = self.debtor
    # No need for both the subtraction and the 1 + portion.
    user_interest = account.balance * (account.rate / account.period)
    account.interest = user_interest
    account.save()
    return user_interest

Все это говорит, я все еще не уверен, что ваша модель данных верна из-за моего непонимания вашего сценария.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...