5

在复式记账法中确保交易始终保持平衡的最佳方式是什么?

我正在 Django 中创建一个复式会计应用程序。我有这些模型:

class Account(models.Model):
    TYPE_CHOICES = (
        ('asset', 'Asset'),
        ('liability', 'Liability'),
        ('equity', 'Equity'),
        ('revenue', 'Revenue'),
        ('expense', 'Expense'),
    )

    num = models.IntegerField()
    type = models.CharField(max_length=20, choices=TYPE_CHOICES, blank=False)
    description = models.CharField(max_length=1000)


class Transaction(models.Model):
    date = models.DateField()
    description = models.CharField(max_length=1000)
    notes = models.CharField(max_length=1000, blank=True)


class Entry(models.Model):
    TYPE_CHOICES = (
        ('debit', 'Debit'),
        ('credit', 'Credit'),
    )

    transaction = models.ForeignKey(Transaction, related_name='entries')
    type = models.CharField(max_length=10, choices=TYPE_CHOICES, blank=False)
    account = models.ForeignKey(Account, related_name='entries')
    amount = models.DecimalField(max_digits=11, decimal_places=2)

我想在模型级别强制执行平衡交易,但在正确的地方似乎没有挂钩。例如,Transaction.clean 不起作用,因为首先保存事务,然后由于 Entry.transaction ForeignKey 而添加条目。

我希望余额检查也可以在管理员中工作。目前,我使用 EntryInlineFormSet 和一个干净的方法来检查管理员中的余额,但这在从脚本添加事务时没有帮助。我愿意更改我的模型以使其更容易。

4

2 回答 2

2

这听起来可能非常天真,但为什么不将每笔交易记录在包含“to account”和“from account”外键的单个记录中,这些外键链接到一个帐户表,而不是尝试为每笔交易创建两条记录呢?在我看来,“复式”的本质似乎是交易总是将资金从一个账户转移到另一个账户。使用两条记录来存储这样的交易并没有什么好处,而且有很多缺点。

于 2011-01-26T10:36:20.383 回答
2

(嗨瑞恩!——史蒂夫·特劳戈特)

自从您发布此内容以来已经有一段时间了,所以我相信您已经解决了这个难题。对于其他人和后代,我不得不说是的,你需要能够拆分交易,不,你不想采取幼稚的方法并假设交易腿总是成对的,因为它们不会。您需要能够进行 N 向拆分,其中 N 是任何大于 1 的正整数。Ryan 在这里具有正确的结构。

Ryan 称之为 Entry 我通常称之为 Leg,就像在事务中的腿一样,我通常在一些 SQL 数据库之上使用裸 Python。我还没有使用过 Django,但是如果 Django 不支持以下内容,我会感到惊讶(震惊):我通常不会使用本地数据库行 ID 作为事务 ID,而是通常从一些生成唯一的事务 ID其他来源,将其存储在 Transaction 和 Leg 对象中,进行最后检查以确保借方和贷​​方余额,然后在一个 SQL 事务中将 Transaction 和 Legs 提交到数据库。

瑞恩,这或多或少是你最终做的吗?

于 2012-04-01T05:33:32.127 回答