В предыдущей заметке по бухучету было показано, что есть быстрые алгоритмы, позволяющие строить бух. балансы для произвольных моментов времени, даже при изменении бухгалтерских операций "задним числом" в процессе работы.
Однако помимо балансов (то есть результатов бух. учета в заданный момент времени) нам необходимо еще платить налоги и составлять документы, зависящие от оборотов. Например, в бухучете принято учитывать авансовые выплаты за товары/услуги на одном счете, а учет получения товаров/услуг вести на другом. Так, если поставщик выполнит некоторую работу для нашей основной деятельности на 100 рублей, то мы сделаем проводку Кт 100= сч. 60.1 и Дт 100= сч. 20. А когда расплатимся с ним, то сделаем проводки Дт 100= сч. 60.1 и Кт 100= сч. 51.
В предыдущем абзаце 60.1 - это счет для расчетов с поставщиками за выполненные работы. Точнее сказать, это субсчет 60.1 счета 60 "Расчеты с поставщиками". Ну, а счет 20 - там учитываются расходы на основное производство, а 51 - бух. счет для учета операций на банковских счетах фирмы. Я тут не заморачиваюсь учетом НДС, который не всегда начисляется и просто чтоб не усложнять посторонними деталями.
А вот если бы (второй случай) мы сначала платили, а потом получили результат от нашего поставщика, то проводка по оплате была бы такой: Дт 100= сч. 60.2 и Кт 100= сч. 51, потому что авансы положено учитывать на счете авансов. Для наших поставщиков - это субсчет 60.2 "Авансы, выданные поставщикам".
Кстати, выполненные работы мы учтем так же, как и раньше: Кт 100= сч. 60.1 и Дт 100= сч. 20, но помимо этой проводки нам надо будет еще закрыть выданные поставщику авансы: Дт 100= сч. 60.1 и Кт 100= сч. 60.2. Разумеется, если бы аванс был выдан только на 60 рублей, то последняя проводка была бы с 60= вместо 100=, а оставшиеся 40= надо было бы оплачивать и учитывать как в первом случае.
Как видим, простое изменение в очередности (какой факт был раньше) факта оплаты за услуги и факта получением услуги ведет к изменению в бухучете этих операций.
В смысле начисления налогов тоже есть разница - при предоплате за услуги (когда мы платим аванс) мы получаем у поставщика соответствующий счет-фактуру на аванс, который позволяет нам уменьшать свои платежи НДС в бюджет еще до получения соответствующей услуги. Хотя на ту же сумму "зачета" НДС за аванс нам придется уменьшить "зачет" НДС при получении услуги - чтоб не уменьшать налог дважды.
По существу субсчета 60.1 и 60.2 являются просто раздельным отражением движения по Кт и Дт счета 60. Нам же все равно надо учитывать раздельно Дт и Кт, если мы хотим быстро получать итоги по их оборотам - (метод быстрого расчета сумм изложен по первой ссылке раздела "Ранее было"). Другое дело, что если мы хотим иметь готовый результат движения по 60.1 и 60.2, то нам надо понимать, где у нас больше результат по Дт (тогда имеет место аванс и 60.2), а когда Кт (тогда - учет на 60.1).
Притом если обороты по Кт опережали обороты по Дт, то обороты по 60.2 будут близки к оборотам по 60.1, а если нет - то будут существенно меньше. И это при том, что от перестановки слагаемых (очередности Дт и Кт оборотов) итоговое сальдо не изменится, а величина оборота по субсчету - может изменится и весьма.
Увы, для случая субсчетов, зависящих от очередности оборотов по Дт и Кт у нас не может быть быстрого алгоритма расчета при изменении задним числом, потому что эти обороты существенно зависят от сальдо, которое имел ОУ (объект учета) перед движением по Дт и/или Кт. И вариантов зависимости получается больше, чем логарифм (пусть даже в фиксированной степени) от общего числа операций с ОУ. Значит, за малое количество шагов (соразмерно с логарифмом или небольшой степенью логарифма) пересчитать не получится в общем случае.
Придется построить данные и алгоритмы, пересчитывающие нужные субсчета в точке каждого оборота по Дт и Кт. Притом нам надо так построить данные, чтобы было видно не только дебетовость или кредитовость оборота, но и в какой степени этот оборот привел к росту самого субсчета, а в какой - к сокращению своего "визави". Например - если мы сделали предоплату 70 рублей, то мы имеем рост субсчета 60.2 на 70 рублей; когда выполнена работа для нас на 100 рублей, то 70 рублей уйдут на сокращение субсчета 60.1 до нуля, а 30 рублей увеличат субсчет 60.1. И наконец, когда мы заплатим оставшиеся 30 рублей, то они не увеличат субсчет 60.2, а сразу все уйдут на уменьшение субсчета 60.1 на 30 рублей до 0.
3. Сокращалки
Поскольку учет роста по Дт и Кт у нас уже есть (исходим из этого), то нам надо лишь добавить данные для учета взаимного сокращения Дт и Кт частей ОУ (объекта учета). Назовем такое взаимное сокращение Дт с Кт "сокращалка". При этом сокращалки будут делиться по происхождению - дебетовые (возникает при обороте по дебету и вызвана наличием кредитового сальдо, имевшимся на момент дебетового оборота, с которым данный Дт оборот и сокращается полностью или частично) и кредитовые сокращалки.
Для нашего случай субсчетов счета 60 учет такой: Предоплата нами на 70 рублей никакой сокращалки не вызывает - из-за отсутствия Кт сальдо. Выполненная работа на 100 рублей для нас вызовет кредитовую сокращалку на 70 рублей (есть Дт сальдо на 70 рублей), а остальные 30 увеличат субсчет 60.1 на 30 рублей и т.д.
Тут есть нюанс. По правилам бухучета аванс считается лишь в той мере, в какой оплата выходит за пределы расчета за уже выполненные работы. Ну, если нам уже сделали работу на 100 рублей, а мы платим только после этого, то вся сумма 100 рублей сразу попадет на счет 60.1, а не пройдет через 60.2 (Хотя если и пройдет, то при проверке тебя за это не расстреляют, да и не всегда пожурят). А вот выполненная работа всегда сначала проходит через субсчет учета выполненных работ, даже если была 100% предоплата. И лишь после того, как работа отражена на субсчете учета работы (счет 60.1 - если это нам делает кто-то, а не мы кому-то), лишь после этого ее стоимость сокращается в учете в полученным авансом - если аванс был.
Но из-за такого нюанса нам нет нужды менять алгоритм расчета данных. Для счета 60 в отчет о поступлении на 60.2 надо выдавать как разницу оборота по Дт 60 счета минус дебетовая сокращалка (это те суммы, которые сразу отправились сокращать 60.1 при Дт обороте и не прошли через 60.2). А рост счета 60.1 (по Кт - он пассивный) - будет весь оборот по Кт счета 60.
Соответственно сумма уменьшения счета 60.2 - это Кт сокращалка счета 60, а уменьшение счета 60.1 - сумма дебетовых и кредитовых сокращалок счета 60.
То есть, как видим, алгоритмы для построения данных, учитывающих очередность Дт и Кт у нас одинаковые что для случая наличия субсчетов, что для простых счетов бухучета, но отличия - в отчетах, которые получает пользователь. А это уже можно настроить для каждого счета (благо их немного).
Кстати, имея Дт и Кт обороты, а также сокращалки и их суммы по счетам, мы можем получать сумму Дт и Кт сальдо всех объектов учета данного счета отдельно друг от друга. Действительно, сокращалка данного ОУ за все время учета в каждый момент времени равна либо его тотальному обороту по Дт (если сальдо Кт), либо по Кт (в противном случае). Поэтому дебетовое сальдо ОУ равно тотальному обороту по Дт ОУ минус тотальная сокращалка ОУ. Кредитовое сальдо - аналогично. И только одно из них может быть не ноль (может и оба ноль). То есть, мы может взять сумму всех тотальныъ оборотов по Дт всех ОУ счета на момент Т, отнять общую сумму их сокращалок к моменту Т и получим сумму их Дт сальдо. С кредитовыми Сд - аналогично.
Ясно, что вместо бух. счетов мы можем брать любые объединения ОУ и считать их развернутые сальдо мгновенно, если рассматривать такое объединение как разновидность ОУ и включать в его Дт, Кт оборотам и сокращалки те же числа, что и к каждому ОУ из данного объединения. Напомню, впрочем, что для подобного объединения нет алгоритма быстрого расчета при изменении "задним числом", потому что его нет и для обычного ОУ. Я говорю про учет, учитывающий очередность Дт и Кт оборотов, естественно.
Однако, в сводке результатов в предыдущей заметке по бухучету "История изменения текста и история бух. баланса - алгоритмы" (
http://dmitgu.livejournal.com/44770.html ) п.4 сказано, что ошибки в бухучете встречаются редко - иначе бухучет не спасут никакие алгоритмы.
Поэтому: с учетом того, что дефекты практически не копятся - мы можем обрабатывать найденный дефект в фоновом режиме, не попадая в ситуацию нарастания дефектов быстрее, чем мы их исправляем. Понятно, что в отдельные моменты обнаружения ошибок их количество растет, но такая ситуация не является системной и быстро исправляется.
Впрочем, пока мы обозначили лишь принципы построения сокращалок, а нам предстоит еще придумать принципы работа алгоритмов их обработки с возможностью изменения в учете задним числом.
4. Заморочки в 1С и время внутри дня
При изменении задним числом в 1С сейчас (первые 2/3 от 2013 г., а вообще уже не 1 год) начинается занудство "нарушена последовательность документов", разваливаются закрытия месяцев и т.д. и т.п. И требуется перепроведение всех документов и перезакрытие всех отчетных периодов с вылезанием новых задниц и проблем. Ад и Израиль, короче.
А львиную долю канители вызывает учет порядка проведения документов - что было счетом авансов попадает на счет работ и наоборот и по всему периоду учета. Впрочем, влияние очередности - если ее не отделить от других свойств бухучета - действительно очень запутывает понимание бухучета на глубоком уровне - который требуется для написания алгоритмов, например.
Еще в 1С сейчас ерунда с учетом времени внутри дня. Это вообще у них от общей запутанности, наверно - ну какая разница, проведен приход в кассу до или после расхода внутри дня? Или материала? Чего мне не давать расходовать с воплем типа "нет денег в учете", если они в течение дня - есть? Раз по итогам была возможность расхода, значит, и внутри нормально порядок сложился, а как чел пишет внутри дня - это уже вопрос как ему красивше кажется и что важнее. И нечего с выстраиванием этого порядка внутри дня ради программистских заморочек юзеру извращаться.
Я к тому, что в своих алгоритмах будем исходить из предположения, что разные операции с одним и тем же ОУ в бухучете проведены в разное время, но их очередность (и время для нужд учета) внутри дня задается не временем в сутках, а соглашениями. Например, работы выполняются раньше прихода денег. Ну, в самом деле - что это за аванс, если он пришел в тот же день, что и выполнена работа? Кстати, по одному ОУ тогда можно считать в день не больше 2х операций, зависящих от порядка - потому что активные (в Дт) операции как бы объединяются в одну, а пассивные (в Кт счета) - в другую обобщенные операции.
5. Этапы обработки изменения "задним числом", ОУ родительский и отдельные
Если мы вносим изменения задним числом, то нам может потребоваться время для фонового исправления учета. Поэтому надо предусмотреть, чтоб само изменение сначала выделять в отдельный ОУ (объект учета), который потом перебрасывается временем №1 внутрь правильного ("родительского") ОУ (если изменение по Дт, например, то проводка переброски будет с Кт отдельного ОУ в Дт родительского ОУ) и в этом времени №1 и дальше учет приводится в порядок. Начинаем с самых поздних дат, исправляем, затем убираем переброску с времени №1 на более раннее время №2 и чиним учет от времени №2 до времени №1. Затем - переброска на время №3 еще более раннее и так - до исходного момента внесения изменения в бухучет.
Кстати, выделение "изменения задним числом" в отдельный ОУ было бы полезно и с точки зрения сохранения старых балансов в неизменности - если это надо. Раз все изменения у нас выделены в отдельные ОУ, то мы можем исключить их из отчета и он останется в прежнем виде. А вот за дату настоящего включения в учет можно выбрать дату следующего отчета. И тогда наша последовательность этапов, описанная только что, превращается в единственный этап включения изменений в основной учет с датой №1, равной дате нужной отчетности.
Такое решение "отложенного включения в учет" позволяло бы и с контрагентами сверятся правильно - использую уже известные изменения, и отчетность не портить - уже сданную, используя данные с исключенными изменениями. И перепроводить всю эту 1С-ю ерунду не приходилось бы.
Кстати, выделение некой операции из "родительского" ОУ в отдельный ОУ удобно в некоторых случаях и для текущей работы. Например, заплатил за какой-то этап работ и хочешь закрыть эти деньги каким-то конкретным актом - и вот удобно иногда, если есть возможность включить этот отдельный ОУ в родительский ОУ в момент появления данного акта в родительском ОУ. Тогда они друг друга закрывают и родительский ОУ снова чист от них и его несколько проще читать. Такая привязка "взаимных" операций друг к другу удобна и с точки зрения возможной смены даты закрывающих документов - поменял дату появления второго документа - изменилась и дата включения в родительский ОУ отдельного ОУ. И опять происходит мгновенное закрытие и в родительском ОУ опять меньше путаницы от этого.
6. Алгоритмы для сокращалок
Задача состоит в том, чтобы в каждый момент времени у ОУ были или только Дт, или только Кт, или 0. И чтобы ни Дт, ни Кт не были отрицательными. Отрицательным будет Дт или Кт если мы "пересокращаем". Как написано выше, тотальная (суммарная с начала учета дебетовая и кредитовая вместе) сокращалка ОУ на данный момент времени равна тотальному же Дт и/или Кт данного ОУ на данный момент времени - если алгоритм правильный.
Допустим, у нас нормальный учет ОУ и мы решили внести изменения в него задним числом. Без потери общности полагаем, что наше изменение - это оборот по Дт в какой-то прошлой дате. Тут возможно несколько вариантов:
1. ОУ (объект учета) еще до изменения был активный (дебетовый) от момента изменения и до конца.
Тогда мы просто увеличиваем обороты по Дт и никаких сокращалок не возникает. ОУ как был активным начиная с даты изменения так и останется после внесения изменения. Самый простой вариант.
2. ОУ будет пассивным после внесения изменения начиная с момента изменения и до конца.
Значит, ОУ изначального был пассивным с даты изменения и нам надо просто увеличить Дт, сделать дебетовую сокращалку в момент изменения на ту же величину и все. Тоже очень просто.
3. До изменения ОУ был не везде активным с момента изменения, а после - станет везде активным с момента изменения.
В этом случае надо пробежать всё ОУ от момента изменения - не включая само изменение - до последнего момента учета (можно в любом направлении) и убрать все Дт сокращалки (нет кредита, чтоб его сокращать) и поставить на каждом Кт обороте Кт сокращалку величиной с весь оборот - т.к. все Кт обороты сразу "съедаются" Дт сальдо. Ну, а на самом изменении поставить сокращалку, которая "съедает" входящее Кт сальдо - если оно есть, или просто ничего не делать, если входящего Кт сальдо в момент изменения нет.
4. После внесения изменения ОУ он станет где-то от момента изменения до конца активным в некоторых периодах, а в некоторых останется пассивным.
Это 4ий вариант, никаких других кроме названных нет и 4й вариант мы рассмотрим подробно.
Выделяем сначала изменение в отдельный ОУ в соответствии с разделом "5. Этапы обработки изменения "задним числом".
В соответствии с методикой из разделом 5 будем последовательно выбирать (как - напишу ниже) время №1, №2 и т.д., временно перебрасывать в выбранный момент наше изменение, обрабатывать учет для такого положения изменения, затем удалять данное временное положение изменения с его сокращалкой (которая, возможно, возникнет в момент данного временного положения изменения) и перебрасывать это изменение к очередному времени №Икс, повторяя цикл обработки. При этом в каждый момент перед удалением временного положения изменения с его сокращалкой в ОУ мы можем приостановить процесс и вернуться к нему когда будет возможно. Так будет обеспечен фоновый режим.
Для простоты считаем, что время №1 - это положение перед последним по времени оборотом (по Дт или Кт) нашего ОУ, время №2 - перед предпоследним и т.д. А в конце мы обработаем момент и самого изменения. В принципе, можно захватывать и "последние 10 оборотов", "предпоследние 10 оборотов" или типа того для ускорения обработки (хоть и с увеличением времени на каждый отдельный "шаг" фонового процесса), но для наглядности возьмем минимальный шаг.
Итак, наше изменение временно стоит перед каким-то оборотом, но данный оборот еще не скорректирован в соответствии с новым изменением. Для начала поставим Дт сокращалку на временное изменение, если для данного времени №Икс входящее сальдо - кредитовое. Напомню, мы разбираем только Дт изменение.
Величина временной сокращалки будет равна либо 0 (если входящее сальдо не Кт), либо меньшей сумме из двух - (1:) суммы изменения и (2:) входящему сальдо (если входящее сальдо Кт).
Все что нам требуется сделать для завершения обработки этапа теперь - это изменить сокращалку у ближайшего следующего оборота. Разберем 2 варианта:
А. Оборот Дт
Если у него нет сокращалки до учета изменения - то теперь тем более не надо - Кт оборот тем более "съеден" новым изменением до данного оборота.
Если же сокращалка была размеров с весь оборот Дт, то оставим ее такой же только если после данного оборота и после внесенного изменения сальдо все равно будет Кт или 0. Тогда наше изменение в этой точке вместе с данным оборотом не смогли еще "съесть" накопленный Кт с избытком.
А вот если сокращалка в разбираемом обороте была, а исходящее сальдо стало Дт (при учете изменения), то Дт сокращалка данного оборота должна быть уменьшена - ведь часть Кт "съело" новое изменение, а Кт уже не хватает на новое изменение и старый оборот с его старой сокращалкой. Новый уровень Дт сокращалки будет равен данному Дт обороту минус исходящее (новое!) Дт сальдо.
Как видим, Дт изменение "убивает" Дт сокращалки. Кажется странным - как одно Дт изменение может убивать множество Дт сокращалок, но если обдумать пару абзацев выше, то окажется, что "убийство" происходит только для "граничных" оборотов Дт, когда происходит переход от Кт сальдо к Дт сальдо. Поэтому внутри полосы Дт оборотов "убьют" Дт сокращалок на сумму не больше, чем сумма нового Дт изменения. А для Кт оборотов мы сейчас разберем процедуру и увидим, что Кт сокращалки как раз прибывают.
Б. Оборот Кт
Если у данного оборота была сокращалка на всю величину - то ничего не изменяем. Ведь если до изменения приходилось тратить весь оборот на гашение Дт, то после добавления нового Дт это тем более в силе.
Если же сокращалки не было, то оставим это без изменения только если перед данным оборотом и после внесенного изменения исходящее сальдо все равно будет Кт или 0. Тогда наше изменение не смогло еще "съесть" с избытком Кт, накопленный до разбираемого Кт оборота.
А вот если сокращалка была не полной на разбираемом обороте и исходящее сальдо станет при учете изменения Дт или Кт, но меньше разбираемого оборота Кт, то сокращалку надо увеличить - ведь после изменения надо закрывать больше Дт оборотов. Поэтому если исходящее сальдо Дт - то делаем Кт сокращалку размером с весь разбираемый оборот Кт, а если сальдо исходящее Кт - то размер сокращалки станет равен разбираемому обороту Кт минус новое исходящее Кт сальдо.
После отработки всех этапов с старыми оборотами зададим нужную сокращалку для самого изменение - если эта сокращалка нужна. Сделаем это так же, как это делалось выше для временных положений изменения. После этого изменение можно считать включенным в учет.
Для ускорения алгоритма можно рассчитывать всякие сальдо исходящие и входящие на базе сальдо предыдущего этапа - отняв/прибавив "оставшиеся в будущем" дебетовые и кредитовые обороты предыдущего этапа.
По сути алгоритм включения Дт изменения состоит в том, что Дт сокращалки заменяются на Кт сокращалки - более ранние. Кажется странным, почему при этом происходит увеличение суммы сокращалок. Но тут ответ - в появлении новых оборотов. Если внести изменения Дт и Кт задним числом, то общее число Дт "горбов" и Кт "впадин" увеличиться и на них тоже будут сокращалки. Хотя эти сокращалки просто "сдвигаются внутрь" к более ранним временам в процессе своей обработки (включения в учет), но сам "внутрь" становится от этого больше, и сумма по нему - растет соответственно.
Напомню, что "шагом" отдельного оборота Дт или Кт по данному ОУ вполне можно сделать день и более крупный период (не более одного оборота по Кт в день и не более одного по Дт). А это вполне посильная обработка для компьютера даже для 100 лет учета. Всего-то при внесении изменения надо поменять порядка 100 *366*2 чисел, ну еще умножить это сколько-то раз на логарифм этого числа в худшем случае.