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


Разобраться и избежать кучи граблей в этом деле мне помогла данная статья. При этом информации по теме "как сделать свою платежную систему" довольно мало, а в учебниках по бухучету программисту сходу разобраться не так просто (и очень нудно). Надеюсь, этот материал окажется полезным тем, кто только собирается что-то такое делать.


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


Введение


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



Лука Пачоли, автор самой старой (15 век) дошедшей до нас книги с описанием принципов двойной записи


В системе с "простой записью" числовые значения записываются только один раз. В системе с "двойной записью" каждое значение записывается дважды, как кредит (положительное значение) и как дебет (отрицательное значение). При этом есть набор правил, определяющих связь между этими значениями. Эти правила вам легко опишет любой опытный бухгалтер, хотя он может и не представлять, как именно они могут быть представлены в реляционной БД.


Основные правила таковы:


  1. Каждая запись в системе должна быть сбалансированной, т.е. сумма всех значений в рамках одной операции должна давать ноль.
  2. Сумма всех значений во всей системе в любой момент времени должна давать ноль (правило т.н. "пробного баланса").
  3. Уже занесенные в БД значения нельзя редактировать или удалять. При необходимости исправлений операция сперва должна быть отменена другой операцией с противоположным знаком, а затем повторена с правильным значением. Это позволяет реализовать надежный аудиторский след (полный лог всех транзакций, часто требуемый при проверках).

Применимость двойной бухгалтерии


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


Если бухгалтерская информация в ИТ системе лишь копирует существующую бумажную отчетность, хранящуюся вне разрабатываемой БД, тогда простая запись еще имеет право на жизнь. Однако если хотя бы один из перечисленных ниже фактов о системе правдив, то с самого начала стоит использовать двойную запись:


  1. Если когда-либо потребуется бухгалтерский аудит информации
  2. Если информация в системе — единственный источник сведений о собственности
  3. Если информация касается объектов, имеющих высокую ценность
  4. Если систему планируется серьезно развивать в дальнейшем

Пример двойной записи


Ключевой идеей двойной записи является существование особого "cash book" аккаунта (прим. перев.: не нашел как это адекватно назвать по-русски, может кто подскажет?). Этот аккаунт содержит записи, сделанные когда ценности (например, деньги) вносятся или выводятся из нашей бухгалтерской системы. Таким образом, текущий баланс этого аккаунта отражает общее количество ценностей в системе.


Дальше показан простой пример с двумя аккаунтами, "cash book" и "Смит".


(а) ?300 вводится в систему и кладется на счет Смита. Создается кредит на ?300 в аккаунте Смита (кредит справа, дебет слева). Чтобы уровнять эту сумму, создается дебет на ?300 в аккаунте cash book.



(b) Затем Смит выводит ?50 из системы. Создаем дебет на эту сумму в аккаунте Смита и кредит в cash book.



(c ) Добавим еще один аккаунт Паттел и переведем 100? ему от Смита. Для этого нам понадобится создать дебет на эту сумму у Смита и кредит у Паттела.


(d) В качестве завершающего штриха пусть теперь Паттел выведет из системы 60?. Мы создаем дебет в его аккаунте и кредит в Cash book.



В результате всех этих операций мы можем подсчитать, что итоговый баланс Смита 150?, Паттела 40?, а в Cash Book -190?, отрицательная сумма балансов всех остальных аккаунтов. Основываясь на этих простых правилах и операциях в дальнейшем можно построить очень комплексные системы контроля ценностями.


Модель данных


Структура простой модели данных, которая может использоваться для представления всей этой информации:



Таблица POSTING содержит сами двойные записи. Хранение всех цифр в одной таблице сильно упрощает все вычисления. В качестве первичного ключа стоит использовать монотонно возрастающий счетчик. Значения при этом должны идти подряд, в таком случае по номеру всегда можно будет убедиться, что ни одна запись не была удалена. Таблицы BATCH и JOURNAL используются для контроля и ввода данных в эту таблицу POSTING.


Каждая запись в таблице JOURNAL представляет транзакцию (с точки зрения бизнеса), которая генерирует двойные записи. Такая транзакция — это завершенная единица работы или какого-либо бизнес-процесса. Либо все POSTING записи, ассоциированные с JOURNAL записью должны быть успешно завершены, либо ни одна из них. Сумма всех POSTING записей в рамках одной транзакции должна давать ноль. Каждая операция по переводу средств из примера выше представляется своей записью в таблице JOURNAL


Запись в таблице BATCH сделана для удобства ввода данных. Она используется для группировки записей JOURNAL в удобные пакеты, например набор чеков для ввода в систему, какой-то глобальный бизнес-процесс вроде начисления процентов сразу всем пользователям и т.п.


Таблица ACCOUNT хранит данные о владельцах ценностей в системе.


Таблица ASSET TYPE содержит информацию о типах ценностей, использующихся в системе. Добавив тип ценности в первичный ключ таблицы POSTING можно сделать систему, оперирующую сразу несколькими видами ценностей (например, обработку нескольких валют).


Вот как может выглядеть такая БД для примера выше в максимально упрощенном виде:



Баланс столбца Amount в таблице POSTING всегда равен нулю после завершения любой транзакции из JOURNAL (ПО должно гарантировать отсутствие записи незавершенных транзакций в БД).


Сумма операций для аккаунта Cash Book дает -190, что равно сумме балансов Смита и Паттела с обратным знаком.


Для демонстрации работы с многовалютностью был добавлен новый вид ценности. Если Смит хочет поменять 20 фунтов на доллары по курсу 1 за 1.5, транзакция будет проведена через Cash Book таким образом:



Расчетные периоды


Модель, которую мы получили, отлично выглядит, но в реальности очень быстро сломается под высокой нагрузкой из-за того, что мы не можем ничего удалять и вынуждены постоянно пересчитывать все возрастающее количество записей в POSTING.


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


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


Сперва были бы очищены балансы предыдущего периода.


image


А затем они были бы перенесены в новый период



После определенного времени все записи периода YEAR 1 могут быть отправлены в архив и удалены из системы без потери ее целостности.


Агрегирование транзакций


Некоторые операции в бухгалтерской системе могут затрагивать сразу многих, или вообще всех пользователей. Например, выплата процентов всем пользователям в виде доли от их текущего баланса.


Такие операции могут быть обработаны в рамках одной транзакции в таблице JOURNAL и можно агрегировать все операции с Cash Book в одну общую запись в таблице POSTING (вместо создания отдельной операции для каждого аккаунта). Это позволит соблюсти все перечисленные выше правила бухгалтерского учета и при этом сократить в два раза количество записей в БД. При использовании такого подхода конец года в БД будет выглядеть так:



Пакетная обработка


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


Исторически так работала обработка чеков. Бухгалтеру выдавалась пачка из десяти чеков, номер пачки и общая сумма всех чеков. На первом этапе чеки вносятся в систему в виде "неавторизованных" записей. При этом через таблицу BATCH проверяется их количество и общая сумма, и только если они совпадают с правильным значением пользователю позволяется закоммитить пачку. После того как это сделано, пачка отправляется другому сотруднику, который проверяет ее на валидность и затем "авторизует" если все введено верно.


Такой процесс называется "maker/checker" и может использоваться для ввода любых значимых данных в систему.


Правильным при этом будет хранить "неавторизованные" записи в отдельной таблице от основного набора двойных записей в таблице POSTING. Также можно иметь целый ряд таких таблиц для разных бизнес-процессов. Например, в случае с чеками, через которые осуществляется ввод или вывод денег из системы, бухгалтеру надо будет проверить только один аккаунт. Так как второй, Cash Book, в таких операциях всегда подразумевается неявно. В таком случае в таблице CHEQUE можно будет обойтись только одним столбцом с аккаунтом, в то время как в гипотетической таблице FUND TRANSFER нужно будет два столбца: "отправитель" и "получатель".


Именно тут возникает основное непонимание принципов двойной записи. Большинство людей в обычной жизни встречают только простые бумажные книги учета. В такой бумажной книге, например для учета финансов какого-то клуба по интересам, нужна только одна запись для каждой операции. Однако в ней по-прежнему есть неявная двойная запись, так как всегда неявно присутствует Cash Book аккаунт (в данном случае — этот самый клуб), ведь все движения средств это всегда или ввод (оплата взносов участниками), или вывод денег из системы (траты клуба).


Вторая причина заблуждений — то что в личных выписках по счету деньги, положенные на счет будут считаться "кредитом", потому что человек по сути кредитует банк, который получает его деньги. Хотя если бы этот человек вел свою бухгалтерскую книгу, эта запись была бы в ней учтена как "дебет" — так как банк должен эти деньги своему клиенту. Эти деньги выводятся из "платежной системы" пользователя и вводятся в систему банка.


Архитектура программной части


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


  1. Внешний интерфейс
  2. Бизнес-логика
  3. Работа с БД

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


PostEntry: модуль, который управляет созданием двойных записей в таблице POSTING. Он отвечает за вставку записей, присвоение ID и таймстампов. Модуль не может удалять или изменять записи и никакой другой модуль не должен удалять или изменять эти записи, за исключением возможного удаления старых архивированных записей для уже неактуальных расчетных периодов. Таблица POSTING должна быть доступна только на чтение для всех других модулей.


MakeDeposit, MakeWithdrawal, MakeTransfer: эти модули реализуют базовую бизнес-логику для операций переводов средств. Они будут использовать модуль PostEntry для занесения своих результатов в БД


ChequeEntry и ChequeAuthorisation, ReceiveBACS (прим перев: BACS — система межбанковских платежей): эти модули будут связывать систему с внешним миром и предоставят высокоуровневый интерфейс. Они будут использовать модули бизнес-слоя для выполнения своих функций. В таком случае можно гарантировать правильность процессинга вне зависимости от метода ввода данных, так как и ChequeEntry и ReceiveBACS будут работать через тот же самый MakeDeposit


Эту методологию разделения слоев можно применять в большей или меньшей степени, в зависимости от сложности системы и желаемой чистоты использования принципов объектного дизайна. При этом может иметь смысл, например, разрешить модулю генерации отчетов (например TestTrialBalance) прямой доступ к БД с уровня интерфейса — вместо того чтобы создавать промежуточные модули на бизнес и БД слоях.



Пробный баланс


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


Лучшим способом проверки является последовательное движение от верхнего уровня к нижнему. Проверки имеет смысл выполнять в таком порядке:


  1. Сумма всех значений в столбце POSTING.Amount
    Если найдена ошибка (значение не ноль), то:
  2. Сумма всех значений POSTING.Amount, но отдельно посчитанная для разных типов ценностей и расчетных периодов
    На этом этапе должно стать яснее, в какой части системы произошла ошибка.
  3. Проверка отдельных операций в таблице JOURNAL. Поскольку сумма всех POSTING.Account в каждой транзакции из таблицы JOURNAL должна тоже давать ноль, дальше можно отследить конкретную проблемную транзакцию.

Типы записей в JOURNAL


Таблица JOURNAL содержит простое представление сущностей, которые однако часто оказываются на деле более сложными и вовлеченными в различные отношения.


Иногда имеет смысл разбить одну таблицу на несколько. Например на MATERIALISED и DEMATERIALISED, которые могут иметь различный набор столбцов, например для материальных сущностей могут потребоваться данные об их текущем местоположении.


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


Сущности, имеющие как под- так и надтипы могут организовываться в БД одним из четырех способов (это довольно стандартная ситуация для любой БД):


  1. Одна общая большая таблица с множеством необязательных столбцов для атрибутов подтипов
  2. Отдельная таблица для каждого подтипа, с дублированием всех общих столбцов
  3. Разделение сущностей таким образом, чтобы надтип хранился в отдельной таблице и джоинился с другими таблицами, содержащими только специфичные для подтипов столбцы
  4. Так же как в 3, но с дублированием столбцов супертипа в таблицах подтипов

У каждого из четырех вариантов есть свои плюсы и минусы. С точки зрения двойной записи полезно иметь общую таблицу для POSTING записей. Вариант 1 лучше подходит для простой бухгалтерской системы (как в примерах в данной статье, где единственное отличие в типах ценностей определяется столбцом JOURNAL.Type). Вариант 3, вероятно, лучше подходит для сложных систем, работающих с широким спектром сильно отличающихся ценностей.

Комментарии (37)


  1. Sora
    18.12.2019 14:07

    «cash book» == «кассовая книга», вроде.


    1. EvilArcher
      18.12.2019 14:52

      Книга продаж / книга покупок


  1. Chagevare
    18.12.2019 15:15

    Дебит — Количество газа, а также воды, нефти или другой жидкости, даваемое источником в определённый промежуток времени. (с) Вики
    В статье речь скорее про дебет.


    1. JediPhilosopher Автор
      18.12.2019 15:55

      Спасибо, поправил. Интересно, а по-английски именно debit


      1. Chagevare
        18.12.2019 16:41

        Однако, насчет «Cash book» задумались, даже посовещались. Ну в данном конкретном случае, если клиент приносит наличные (судя по cash в названии), причем не важно зачем — оплата за товар, либо положить на свой счет в банке — то это будет с точки зрения бухгалтера 50 счет плана счетов — «Касса предприятия». Перевод тут неуместен.


        1. census
          18.12.2019 17:05

          Все правильно «cash book» — это кассовая книга. А счет 50 (точнее его субсчета) используется только в обычных организациях. В банках для учета наличных денежных средств используется счет 202 согласно плану счетов в кредитных организациях.


        1. LostAlly
          19.12.2019 14:22

          Кэш, это не только наличные, это все не кредитные средства клюоторыми вы можете распоряжаться. Налиные, это дословный перевод который не отражает реалное значение этого термина.


  1. Neyury
    18.12.2019 17:26
    +1

    Спасибо за статью, как раз предстоит писать биллинг в собственном проекте.

    Правильно ли я понял работу с расчетными периодами?
    Предположим, что после периода A наступил период B. Мы выводим остатки по каждому аккаунту в сash book в периоде A, а потом возвращаем остатки аккаунтов из сash book в периоде B.


    1. Neyury
      18.12.2019 18:21

      В статье перепутаны картинки в этом месте, поэтому и не разобрался.


    1. JediPhilosopher Автор
      18.12.2019 18:21

      Да, именно так.
      В итоге каждый период можно рассматривать независимо от всех остальных периодов. Можно выкинуть из БД все периоды кроме текущего, и это никак не повлияет на балансы пользователей и выполнение правил общего нулевого баланса. Зато сильно упростит подсчеты — ибо транзакции копятся, и с миллионами архивных записей в БД подсчеты начинают уже подтормаживать.

      Да, картинки были действительно перепутаны, поправил


      1. Neyury
        18.12.2019 19:13

        Как правильно организовывать переход между расчетными периодами на уровне архитектуры/кода?

        Блокировать новые транзакции пока не будут перенесены все остатки на новый период? (Но тут много вопросов. Что делать если переход занимает неприемлемое время (SLA)? Как организовать блокировку при микросервисной архитектуре? И т.д)

        Или обновлять каждый аккаунт при первой транзакции отдельно, а неактивные аккаунты в фоне?


        1. JediPhilosopher Автор
          18.12.2019 19:39

          Обычно во всех таких системах есть некий период, в течение которого проводятся тяжелые операции на БД — бекапы, клиринг и т.п. Как правило делается это все ночью, когда клиентов нет.

          У нас в системе около ста тысяч аккаунтов, операция подсчетов балансов по всем занимает пару минут. Это не так долго. В это время апи просто на все запросы о переводах отдает код ошибки «на сервере ведутся работы».

          Нагрузка у нас невелика (где-то один запрос в две-три секунды), а ночью почти совсем сходит на нет, так что это все не проблема.

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


          1. Neyury
            18.12.2019 19:58

            И я так понимаю, что не страшно, если перенос остатков на новый период будет осуществлён не сразу, а после того, как некоторые транзакции в новом периоде уже были совершены? Просто при переносе остатков на текущий период не учитывать транзакции за этот же текущий период, верно? Или есть нюансы?


            1. apple01
              18.12.2019 22:36

              Если я правильно понимаю вопрос, а также основываясь на своем небольшом опыте:
              — транзакиям по определенным правилам назначаются posting period id чтобы заранее определить к какому периоду они относятся. В зависимости от принятых правил, транзакция может быть отнесена к следующему периоду если даже она началась в текущем.
              — перенос остатков осуществляется процедурой закрытия периода


            1. JediPhilosopher Автор
              19.12.2019 00:21

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


        1. corwincooper
          20.12.2019 23:14

          В моем сервисе это реализовано как-то так:

          Сущность Account имеет поле period
          Баланс юзера счетается примерно так (пример абстрактный, не используйте в продакшн):

          SELECT SUM(amount) as balance FROM Transaction WHERE account_id = account.id AND period <= account.period

          Организовать блокировку можно средствами самой СУБД:
          SELECT * FROM Account WHERE period < "current period" FOR UPDATE SKIP LOCKED LIMIT 10

          Таким образом, условный мускул пикнет вам 10 аккаунтов и залочит их, так что параллельные транзакции не смогут получить доступ к этим записям. И перенос балансов можно повесить на крон, либо придумать что-то более эффективное, исходя из вашей конкретной ситауции. Почитайте про такие фичи как FOR UPDATE, SKIP LOCKED, NOWAIT


    1. nikolayv81
      20.12.2019 08:43

      Можно сделать saldo(тут account, в АБС видел ledger) по дням(неделям/месяцам) и считать его накопительным итогом при этом для проведения платёжного документа (тут journal, но, вроде как обычно это payment_document) можно считать входящий остаток как сумму закрытого периода по saldo + записи из task (мне чаще попадалось названное как journal) за незакрытые периоды. Это может помочь решить вопросы с производительностью.
      p.s. названия не привычны мне, привык к тому что journal — это полупроводки, ledger/saldo — остатки account — справочник счетов, payment_document -платёжный документ (может быть иерархическим, т.е. заменяет и batch из статьи)


  1. NickUkolov
    18.12.2019 17:43

    В контексте данной статьи account переводится как счет


    1. German1984
      20.12.2019 07:27

      А transaction как проводка


  1. apple01
    18.12.2019 22:50

    Еще у такой архитектуры (когда все данные сводятся в одну таблицу Posting) есть такое огромное преимущество как высокая скорость подсчета балансов и простота генерации отчетов. Ну а факт что подсчет нужно вести от начала последнего открытого периода, ускоряет еще больше.


    1. JediPhilosopher Автор
      19.12.2019 00:22

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


  1. roller
    19.12.2019 04:49

    Кажется тут происходит попытка изобретения Event Source'инга. Не надо так (с) Не нужны вам никакие cash book если все движения денег описаны транзакциями (записями), а перекладывание денег со счета на счет это всегда две транзакции ссылающиеся на общий обьект "причина" или типа того.


    1. JediPhilosopher Автор
      19.12.2019 14:26

      Ну так вопрос: если мы вносим деньги в систему, то с какого счета мы должны деньги переложить на счет получателя? Вот он cash book и есть.

      Ну и главное тут на самом деле — не столько организовать транзакции (их можно было бы и без двойной записи легко сделать), сколько организовать контроль за их корректностью. А правила нулевых суммарных балансов — очень мощная штука, позволяющая легко искать ошибки и проверять валидность состояния системы. Очень, просто супер легко, одним запросом в духе «сложить все значения amount с timestamp в указанном периоде и сравнить с нулем».


  1. VolCh
    19.12.2019 09:36

    У меня в последнее время большие сомнения, что физическая двойная запись оправдана в современных ИС. Таблиц транзакций и операций с ид транзакции, суммой, валютой, счётом дебета и счётом кредита вполне достаточно.
    Любая транзакция — 1+N вставок только в две таблицы, где N — количество операций в транзакции, в простых случаях одна только. В целом можно обойтись даже одной вставкой в одну таблицу, если база поддерживает эффективную работу со сложными типами данных типа объектов и их массивов.


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


    P. S. Архаичный перевод архаичного cash book — амбарная книга


    1. ggo
      19.12.2019 10:13

      Неочевидно, как по одной таблице безболезненно собирать балансы и оборотку.


    1. JediPhilosopher Автор
      19.12.2019 14:30

      В бухгалтерии контроль обычно на одном из первых мест стоит. И ошибки могут быть всегда — от ошибок ввода данных в систему или багов в ПО до аппаратных сбоев.

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

      Поэтому все и перестраховываются. Опять же повторю мнение из комментария выше — двойная запись нужна не для оптимальной организации хранения данных (для этого и простая запись подойдет), а для гарантий надежности и верифицируемости. Причем в такой записи эти задачи (та же проверка нулевого общего баланса) делаются тривиально, быстро и просто одним запросом к БД. Вот в чем основной профит такой архитектуры.


  1. frkbvfnjh
    19.12.2019 16:07

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

    (c ) Добавим еще один аккаунт Паттел и переведем 100? ему от Смита. Для этого нам понадобится создать дебет на эту сумму у Смита и кредит у Паттела.

    Вроде бы Смит теряет деньги (передает со своего счета/аккаунта в счет/аккаунт Паттела) и сумму нужно писать в кредит, но нет, именно в этой операции все на оборот! Как нужно правильно мыслить, что бы понять в каком случае нужно писать в дебет, а в каком в кредит?


    1. JediPhilosopher Автор
      19.12.2019 16:42

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

      Но поскольку такая вот система предназначена для работы только с пассивными счетами, для них все просто. Кредит — то что дали (плюс), дебет — то что забрали (минус). Слово дебет вообще происходит от слова debt, долг.

      Это надо просто запомнить.

      Ну а дальше любая операция просто состоит из того, что мы берем деньги в одном месте (и записываем их туда с минусом, дебет), а в другое место их кладем — и туда записываем с плюсом, кредит. Если операция связана с движением денег между границами системы и окружающего мира — в качестве одного из счетов используем специальный cash book.


      1. frkbvfnjh
        20.12.2019 06:39

        Блииин, спасибо! Хоть какая то крупица стала понятнее. Я же знал, что debt — долг, но не придавал этому никакого значения, теперь многое стало понятнее. Полностью согласен с Вашим высказыванием:

        Если лезть в глубины бухучета — там вообще черт ногу сломит.
        Я думал, что я один считаю бух учет адом адским, ведь все говорят — «Это же так просто!». Для меня это всегда мУка, вообще не понимаю что происходит. Кроме того есть ведь не только активные и пассивные счета, в мире 1С к примеру есть еще активно-пассивные и парные счета =0 Я вообще не понимаю зачем было изобретать двойную запись, я просто не могу этого понять…


        1. JediPhilosopher Автор
          20.12.2019 09:40

          Как я в комментариях выше писал, главная задача двойной записи — контроль за ошибками. Изобретали ее еще в средние века (точно даже неизвестно когда именно).

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


          1. frkbvfnjh
            20.12.2019 10:08

            Как я в комментариях выше писал, главная задача двойной записи — контроль за ошибками.
            Спасибо, что еще раз ткнули носом, теперь буду имет об этом более приземленное представление. Всегда думал, что в двойной записи какой-то более сакральный смысл, который могут понять люди с геном бухгалтера.


      1. DrPass
        20.12.2019 06:56

        Все еще усложняется тем, что есть два вида счетов — активные и пассивные, для которых дебет с кредитом имеют противоположный смысл.

        Более того, есть ещё и активно-пассивные счета, где сальдо может быть и дебетовое, и кредитовое. Например, расчеты с контрагентами :)


  1. frkbvfnjh
    20.12.2019 08:44

    Может есть у кого ссылки на материал, который позволяет раскрыть тайный смысл двойной записи в бух. учете и понять его мышлением IT-шника со всеми тонкостями и примерами (активные, пассивные, активно-пассивные, парные счета, какой в каких случаях используется и почему и т.д)?


    1. DrPass
      20.12.2019 08:57

      А у вас есть ссылки на материал, который позволяет раскрыть тайный смысл паттернов разработки софта и понять его мышлением бухгалтера со всеми тонкостями и примерами (observer, decorator, DI, какой в каких случаях используется и почему и т.д.)? ;)


    1. nikolayv81
      20.12.2019 09:00

      Там же два правила, квадрат 2х2 и "дебет слева, кредит справа", но я первый никак запомнить не могу :)
      Из жизни, т.к. cr при сортировке идёт раньше db (debit) выгрузил как-то данные с обратным порядком записей, попросили больше так не делать, т.к. очень неудобно :)


    1. Vitos85
      20.12.2019 09:44
      +1

      "Алексей Виноградов
      Азбука бухгалтерского учета. Что надо знать для работы с бухгалтерскими программами" Мне в свое время очень помогла эта книга, сразу говорю — она небольшая, но даже программист поймет основы.


      1. frkbvfnjh
        20.12.2019 10:02

        Спасибо, за дельный совет!