确保交易在复式会计中始终保持平衡的最佳方法是什么?
我正在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来检查管理中的余额,但这在从脚本添加事务时没有帮助。我愿意改变我的模型以使其更容易。
答案 0 :(得分:2)
这可能听起来非常幼稚,但为什么不将每个交易记录在包含“to account”和“from account”外键的单个记录中,而这些外键链接到一个帐户表而不是尝试为每个事务创建两个记录?从我的观点来看,似乎“复式”的本质是交易总是将钱从一个账户转移到另一个账户。使用两个记录来存储此类事务并存在许多缺点是没有优势的。
答案 1 :(得分:2)
(嗨瑞恩! - 史蒂夫特拉戈特)
你发布这个已经有一段时间了,所以我相信你已经过了这个难题了。对于其他人和后代,我必须说是,你需要能够分割交易,不,你不想采取天真的方法并假设交易支柱将永远成对,因为他们不会。你需要能够进行N路分裂,其中N是任何大于1的正整数.Ryan在这里有正确的结构。
Ryan称之为Entry我通常称之为Leg,就像在事务中一样,我通常在一些SQL数据库上使用裸Python。我还没有使用过Django,但如果Django不支持以下内容,我会感到惊讶(震惊):我不会使用本机数据库行ID作为事务ID,而是通常从某些人生成一个唯一的事务ID其他来源,存储在Transaction和Leg对象中,进行最后检查以确保借方和贷方余额,然后在一次SQL事务中将Transaction和Legs提交给db。
瑞恩,你或多或少都在做什么?