Dual Entry Accounting + Ошибка в моем коде где-то = :( - PullRequest
0 голосов
/ 11 мая 2019

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

У меня есть 3 модели: Account, JournalEntry, LineItem

Аккаунт

  • category соответствует %i[asset liability equity income expense]
  • normal_balance соответствует %i[debit credit]
  • Счет для уведомлений с идентификатором 3 является контр-счетом (этоcredit учетная запись, на которой обычно находятся активы debit)

account

JournalEntry

journal entry

LineItem

  • side соответствует %i[debit credit]
  • amount ВСЕГДА положительно

line item


Таким образом, у меня есть некоторые реальные трудности со счетами «contra».

Я ДУМАЮ, что у меня есть потенциальная проблема в моей модели данных.Я заметил, что многие люди в других учетных библиотеках хранят amount как +/- без сохранения side.Я решил сохранить side позиции, а также amount как всегда положительное число для моделирования реального учета на бумаге (помните, что я также храню normal_balance счета, чтобы сравнить его с этим).

Я понимаю, что это немного медленнее с математикой, но сначала я хотел, чтобы она работала без излишней путаницы с самим собой.

Другая причина, по которой я его так хранил, заключается в том, что он более интуитивно понятен при добавлении новых транзакций.Бухгалтер, помогавший мне, согласился с тем, что высказывание +200 или -150 сбивает с толку, а не debit the sales account.Поэтому я могу написать это:

Transaction.create!(:debit, sales, 200)

вместо

Transaction.create!(accumulated_depreciation, -140.30)

Проблема в том, что сейчас я пытаюсь написать некоторые формулы для выполнения 2 действий:

  1. Функция категории баланса, которую я буду использовать 5 раз для расчета пробного баланса (т.е. я балансирую все категории индивидуально и вставляю результаты в формулу, чтобы получить 0.00: asset balance - (liability balance + equity balance +income balance - expense balance))
  2. Баланс определенной учетной записи (как для линии P & L, такой как Sales account)

Вот мои функции, которые делают это.Обратите внимание, что balance_account однако не предполагает учета contra.

def balance_category(category)
  # ...

  LineItem
    .joins(:account)
    .where('accounts.category = ?', category_index)
    .sum('CASE WHEN line_items.side = accounts.normal_balance THEN (CASE WHEN accounts.contra = false THEN line_items.amount ELSE -line_items.amount END) ELSE (CASE WHEN accounts.contra = false THEN -line_items.amount ELSE line_items.amount END) END')
end

def self.balance_account(account)
  # ...

  LineItem
    .joins(:account)
    .where('accounts.id = ?', account.id)
    .sum('CASE WHEN line_items.side = accounts.normal_balance THEN line_items.amount ELSE -line_items.amount END')
end

Я пытался получить помощь бухгалтера, не являющегося программистом, чтобы проверить это, но это было безнадежно.Я попробовал себя поиграть с этим, но счета против довольно запутанные, и я сомневаюсь, что это правильно, хотя мои пробные балансировки работают.

Я пишу этот пост, потому что во время программирования отчета о прибылях и убытках я понял... если я наберу balance_category на :asset, я получу одну сумму.Но если я наберу balance_account на всех учетных записях в этой категории, а затем сложу эти итоги вместе, я не получу одинаковое число, если у меня есть позиции, полученные с контра-счета.Так что где-то что-то не так.

Моя интуиция говорит, что это может быть связано с тем, что balance_account не учитывает противоречие, но я не уверен ...

1 Ответ

0 голосов
/ 12 мая 2019

Вот что мне не хватало после очень долгого разговора с бухгалтером ... когда вы сохраняете значение, вам действительно нужно перевернуть знак СНОВА, если это контр-счет.

Вот функция, которую я использую для хранения правильного знака для каждой суммы (она вызывается один раз для каждой позиции)

if side == normal_balance
  # do nothing
else
  amount = amount * BigDecimal(-1)
end

amount = amount * BigDecimal(-1) if account.contra?

Я понимаю, что логику можно упростить, но я хотел быть явным, потому что это довольно круто

...