Каков наилучший способ обеспечить сбалансированные транзакции в бухгалтерском приложении с двойной записью? - PullRequest
4 голосов
/ 05 декабря 2010

Каков наилучший способ обеспечить сбалансированность транзакций в бухгалтерии с двумя записями?

Я создаю приложение для бухгалтерии двойной записи в 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 с чистым методом, который проверяет баланс в админке, но это не помогает при добавлении транзакций из скрипта.Я готов изменить свои модели, чтобы сделать это проще.

Ответы [ 2 ]

2 голосов
/ 01 апреля 2012

(Привет, Райан! - Стив Трауготт)

Прошло много времени с тех пор, как вы опубликовали это, так что я уверен, что вы уже прошли эту головоломку. Что касается других и потомков, я должен сказать, да, вам нужно иметь возможность разделять транзакции, и нет, вы не хотите использовать наивный подход и предполагать, что ветви транзакций всегда будут в парах, потому что они не будут. Вы должны быть в состоянии сделать N-стороннее разбиение, где N - любое положительное целое число, большее 1. Здесь Райан имеет правильную структуру.

То, что Райан называет Entry, я обычно называю Leg, как и в транзакции leg, и я обычно работаю с голым Python поверх некоторой базы данных SQL. Я еще не использовал Django, но я был бы удивлен (шокирован), если Django не поддерживает что-то вроде следующего: Вместо того, чтобы использовать собственный идентификатор строки БД для идентификатора транзакции, я вместо этого обычно генерирую уникальный идентификатор транзакции из некоторых другой источник, сохраните его в объектах Transaction и Leg, сделайте мою последнюю проверку, чтобы обеспечить баланс дебетов и кредитов, а затем передайте и Transaction, и Legs в БД в одной транзакции SQL.

Райан, это более или менее то, что ты в итоге делал?

2 голосов
/ 26 января 2011

Это может звучать ужасно наивно, но почему бы просто не записать каждую транзакцию в одну запись, содержащую внешние ключи «от учетной записи» и «от учетной записи», которые ссылаются на таблицу счетов, вместо попытки создания двух записей для каждой транзакции? С моей точки зрения, похоже, что суть «двойной записи» заключается в том, что транзакции всегда переводят деньги с одного счета на другой. Нет преимущества в использовании двух записей для хранения таких транзакций и много недостатков.

...