Начисление амортизации в рамках срока полезного использования.
Делюсь реализацией задачи о начислении амортизации основного средства в пределах периода срока полезного использования. Необходимо доработать типовой функционал конфигурации «Управление производственным предприятием», редакция 1.3, для того чтобы, при проведении документа «Амортизация ОС», анализировался срок полезного использования основного средства и производилось начисление амортизации в рамках срока полезного использования. Так как, иногда возникали ситуации, когда срок полезного использования завершен, а начисление производилось в последующие месяцы и обычно это были не большие суммы.
Схематично ситуацию можно представить следующим образом:
Доработка реализована для управленческого, бухгалтерского и налогового учета, основных средств, использующих линейных метод начисления.
При анализе кода проведения документа «Амортизация ОС», основные расчеты суммы начисления амортизации, производятся в общем модуле «УправлениеВнеоборотнымиАктивами», в соответствующих функциях: «РасчетАмортизацииУпр», «РасчетАмортизацииБухРегл» и «РасчетАмортизацииНалогРегл». Указанные функции по своей структуре схожи и имеют в своем составе основной запрос и последующий расчет начисления суммы амортизации.
Доработка происходила следующим образом, сначала в основной запрос, добавлялось получение даты, основанной на сроке полезного использования для вычисления амортизации и производился расчет дельты – то есть, той суммы которая будет начислена в следующий период, основываясь на балансовой стоимости и конечного остатка амортизации. Для каждой функции, анализ и расчет дельты различны!
Функция «РасчетАмортизацииБухРегл»:
1. Добавляем код получения даты проверки, в основной запрос, последний пакет выборки:
| ЕСТЬNULL(ВыработкаОС.ОбъемВыработки, 0) КАК ОбъемВыработки // Начисление амортизации в рамках срока полезного использования { | ,ВЫБОР | КОГДА ЕСТЬNULL(СостоянияОСОрганизаций.ДатаСостояния, 0) = 0 | ТОГДА ДАТАВРЕМЯ(1, 1, 1) | ИНАЧЕ ДОБАВИТЬКДАТЕ(НАЧАЛОПЕРИОДА(СостоянияОСОрганизаций.ДатаСостояния, МЕСЯЦ), МЕСЯЦ, ЕСТЬNULL(ПараметрыАмортизацииБухгалтерскийУчетСрезПоследних.СрокИспользованияДляВычисленияАмортизации, 0)) | КОНЕЦ КАК ПроверкаСрокаИспользования // Начисление амортизации в рамках срока полезного использования } |ИЗ | СписокОС | ЛЕВОЕ СОЕДИНЕНИЕ ПервоначальныеСведенияОбОсновныхСредствахОрганизацийСрезПоследних | ПО СписокОС.ОсновноеСредство = ПервоначальныеСведенияОбОсновныхСредствахОрганизацийСрезПоследних.ОсновноеСредство | ЛЕВОЕ СОЕДИНЕНИЕ ВыработкаОС | ПО ПервоначальныеСведенияОбОсновныхСредствахОрганизацийСрезПоследних.ОсновноеСредство = ВыработкаОС.ОсновноеСредство | И ПервоначальныеСведенияОбОсновныхСредствахОрганизацийСрезПоследних.ПараметрВыработки = ВыработкаОС.ПараметрВыработки | ЛЕВОЕ СОЕДИНЕНИЕ ПараметрыАмортизацииБухгалтерскийУчетСрезПоследних | ПО СписокОС.ОсновноеСредство = ПараметрыАмортизацииБухгалтерскийУчетСрезПоследних.ОсновноеСредство | ЛЕВОЕ СОЕДИНЕНИЕ ГрафикиАмортизацииБухгалтерскийУчетСрезПоследних | ПО СписокОС.ОсновноеСредство = ГрафикиАмортизацииБухгалтерскийУчетСрезПоследних.ОсновноеСредство | ЛЕВОЕ СОЕДИНЕНИЕ СпособыОтраженияРасходовПоАмортизацииСрезПоследних | ПО СписокОС.ОсновноеСредство = СпособыОтраженияРасходовПоАмортизацииСрезПоследних.ОсновноеСредство | ЛЕВОЕ СОЕДИНЕНИЕ АмортизацияБухгалтерскийУчетОстаткиИОбороты | ПО СписокОС.ОсновноеСредство = АмортизацияБухгалтерскийУчетОстаткиИОбороты.ОсновноеСредство | ЛЕВОЕ СОЕДИНЕНИЕ СчетаБухгалтерскогоУчетаОсновныхСредствСрезПоследних | ПО СписокОС.ОсновноеСредство = СчетаБухгалтерскогоУчетаОсновныхСредствСрезПоследних.ОсновноеСредство | ЛЕВОЕ СОЕДИНЕНИЕ АмортизацияНаНачалоГода | ПО СписокОС.ОсновноеСредство = АмортизацияНаНачалоГода.ОсновноеСредство | ЛЕВОЕ СОЕДИНЕНИЕ ОсновныеСредстваСписанныеНаЗатратыОрганизацииОстатки | ПО СписокОС.ОсновноеСредство = ОсновныеСредстваСписанныеНаЗатратыОрганизацииОстатки.ОсновноеСредство // Начисление амортизации в рамках срока полезного использования { | ЛЕВОЕ СОЕДИНЕНИЕ РегистрСведений.СостоянияОСОрганизаций КАК СостоянияОСОрганизаций | ПО СписокОС.ОсновноеСредство = СостоянияОСОрганизаций.ОсновноеСредство | И СостоянияОСОрганизаций.Состояние = ЗНАЧЕНИЕ(Перечисление.СостоянияОС.ПринятоКУчету) // Начисление амортизации в рамках срока полезного использования } |";
2. После расчета сумм амортизации, но до возврата таблицы с итоговыми данными, вставляем доработку по анализу полученных значений:
// Балансовая стоимость не может быть меньше 0 СуммаАмортизации = Макс( Мин( СуммаАмортизации, ВсегоОсталосьСписать), 0); СтрокаАмортизации = ТаблицаАмортизации.Добавить(); СтрокаАмортизации.ОС = ВыборкаПоОС.ОсновноеСредство; СтрокаАмортизации.СчетУчетаБУ = ВыборкаПоОС.СчетУчета; СтрокаАмортизации.СчетАмортизацииБУ = ВыборкаПоОС.СчетНачисленияАмортизации; СтрокаАмортизации.ИмяСубконто = "ОсновныеСредства"; СтрокаАмортизации.НаправлениеАмортизации = ВыборкаПоОС.СпособыОтраженияРасходовПоАмортизации; СтрокаАмортизации.Бух = СуммаАмортизации; // Начисление амортизации в рамках срока полезного использования { Если ВыборкаПоОС.СпособНачисленияАмортизации = Перечисления.СпособыНачисленияАмортизацииОС.Линейный И ЗначениеЗаполнено(ВыборкаПоОС.ПроверкаСрокаИспользования) И ЗначениеЗаполнено(ВыборкаПоОС.СрокИспользованияДляВычисленияАмортизации) Тогда Если ВыборкаПоОС.ПроверкаСрокаИспользования = НачалоМесяца(ДатаРасчета) Тогда Если ЗначениеЗаполнено(ВыборкаПоОС.АмортизацияКонечныйОстаток) И ЗначениеЗаполнено(ВыборкаПоОС.БалансоваяСтоимость) Тогда СтоимостьКрайняя = СуммаАмортизации + ВыборкаПоОС.АмортизацияКонечныйОстаток; БалансоваяСтоимость = ВыборкаПоОС.БалансоваяСтоимость; Если БалансоваяСтоимость > СтоимостьКрайняя Тогда Дельта = БалансоваяСтоимость - СтоимостьКрайняя; Сообщить("(БУ)ОС: " + ВыборкаПоОС.ОсновноеСредство + "(" + ВыборкаПоОС.ОсновноеСредство.Код + ")" + "истекает срок использования, остаток учтен: " + Дельта); СтрокаАмортизации.Бух = СтрокаАмортизации.Бух + Дельта; КонецЕсли; КонецЕсли; КонецЕсли; КонецЕсли; // Начисление амортизации в рамках срока полезного использования } Если СуммаАмортизации = 0 Тогда Если ВыдаватьСообщения = Истина Тогда ОбщегоНазначения.СообщитьОбОшибке(ТекстСообщения + " амортизация равна 0"); КонецЕсли; КонецЕсли; КонецЦикла; Возврат ТаблицаАмортизации;
Функция «РасчетАмортизацииНалогРегл»:
1. Добавляем код получения даты проверки, в основной запрос, последний пакет выборки:
| ЕСТЬNULL(НалоговыйОстатки.СуммаКапитальныхВложенийВключаемыхВРасходы, 0) КАК СуммаКапитальныхВложенийВключаемыхВРасходы // Начисление амортизации в рамках срока полезного использования { | ,ВЫБОР | КОГДА ЕСТЬNULL(СостоянияОСОрганизацийПринятоКУчету.ДатаСостояния, 0) = 0 | ТОГДА ДАТАВРЕМЯ(1, 1, 1) | ИНАЧЕ ДОБАВИТЬКДАТЕ(НАЧАЛОПЕРИОДА(СостоянияОСОрганизацийПринятоКУчету.ДатаСостояния, МЕСЯЦ), МЕСЯЦ, ЕСТЬNULL(ПараметрыАмортизацииНалоговыйУчетСрезПоследних.СрокПолезногоИспользования, 0)) | КОНЕЦ КАК ПроверкаСрокаИспользования // Начисление амортизации в рамках срока полезного использования } |ИЗ | СписокОС | ВНУТРЕННЕЕ СОЕДИНЕНИЕ ПервоначальныеСведенияОбОсновныхСредствахОрганизацийСрезПоследних | ПО СписокОС.ОсновноеСредство = ПервоначальныеСведенияОбОсновныхСредствахОрганизацийСрезПоследних.ОсновноеСредство | ЛЕВОЕ СОЕДИНЕНИЕ ПараметрыАмортизацииНалоговыйУчетСрезПоследних | ПО СписокОС.ОсновноеСредство = ПараметрыАмортизацииНалоговыйУчетСрезПоследних.ОсновноеСредство | ЛЕВОЕ СОЕДИНЕНИЕ АмортизацияНалоговыйУчетОстаткиИОбороты | ПО СписокОС.ОсновноеСредство = АмортизацияНалоговыйУчетОстаткиИОбороты.ОсновноеСредство | ЛЕВОЕ СОЕДИНЕНИЕ СчетаНалоговогоУчетаОсновныхСредствСрезПоследних | ПО СписокОС.ОсновноеСредство = СчетаНалоговогоУчетаОсновныхСредствСрезПоследних.ОсновноеСредство | ЛЕВОЕ СОЕДИНЕНИЕ СпециальныйКоэффициентДляАмортизацииНалоговыйУчетСрезПоследних | ПО СписокОС.ОсновноеСредство = СпециальныйКоэффициентДляАмортизацииНалоговыйУчетСрезПоследних.ОсновноеСредство | ЛЕВОЕ СОЕДИНЕНИЕ НачислениеАмортизацииПоБазовойСтоимостиНалоговыйУчетСрезПоследних | ПО СписокОС.ОсновноеСредство = НачислениеАмортизацииПоБазовойСтоимостиНалоговыйУчетСрезПоследних.ОсновноеСредство | ЛЕВОЕ СОЕДИНЕНИЕ НаправленияАмортизации | ПО СписокОС.ОсновноеСредство = НаправленияАмортизации.ОсновноеСредство | ЛЕВОЕ СОЕДИНЕНИЕ НалоговыйОстатки | ПО СписокОС.ОсновноеСредство = НалоговыйОстатки.ОсновноеСредство | ЛЕВОЕ СОЕДИНЕНИЕ УчетнаяПолитикаОрганизацийСрезПоследних | ПО ИСТИНА | ЛЕВОЕ СОЕДИНЕНИЕ СостоянияОСОрганизаций | ПО СписокОС.ОсновноеСредство = СостоянияОСОрганизаций.ОсновноеСредство | ЛЕВОЕ СОЕДИНЕНИЕ АмортизацияОСПриПереходеКЛинейномуМетоду | ПО СписокОС.ОсновноеСредство = АмортизацияОСПриПереходеКЛинейномуМетоду.ОсновноеСредство // Начисление амортизации в рамках срока полезного использования { | ЛЕВОЕ СОЕДИНЕНИЕ РегистрСведений.СостоянияОСОрганизаций КАК СостоянияОСОрганизацийПринятоКУчету | ПО СписокОС.ОсновноеСредство = СостоянияОСОрганизацийПринятоКУчету.ОсновноеСредство | И СостоянияОСОрганизацийПринятоКУчету.Состояние = ЗНАЧЕНИЕ(Перечисление.СостоянияОС.ПринятоКУчету) // Начисление амортизации в рамках срока полезного использования } |";
2. После расчета сумм амортизации, но до возврата таблицы с итоговыми данными, вставляем доработку по анализу полученных значений:
СтрокаАмортизации.СуммаКапитальныхВложенийВключаемыхВРасходы = ВыборкаПоОС.СуммаКапитальныхВложенийВключаемыхВРасходы; // Начисление амортизации в рамках срока полезного использования { Если ВыборкаПоОС.МетодНачисленияАмортизации = Перечисления.МетодыНачисленияАмортизации.Линейный И ЗначениеЗаполнено(ВыборкаПоОС.ПроверкаСрокаИспользования) И ЗначениеЗаполнено(ВыборкаПоОС.СрокПолезногоИспользования) Тогда Если ВыборкаПоОС.ПроверкаСрокаИспользования = НачалоМесяца(ДатаРасчета) Тогда АмортизацияНачальныйОстаток = ВыборкаПоОС.АмортизацияНачальныйОстаток; АмортизацияКонечныйОстаток = ВыборкаПоОС.АмортизацияКонечныйОстаток; СтоимостьНаНачалоМесяца = ВыборкаПоОС.СтоимостьНаНачалоМесяца; СтоимостьНаКонецМесяца = ВыборкаПоОС.СтоимостьНаКонецМесяца; Если ЗначениеЗаполнено(АмортизацияНачальныйОстаток) И ЗначениеЗаполнено(АмортизацияКонечныйОстаток) И ЗначениеЗаполнено(СтоимостьНаНачалоМесяца) И ЗначениеЗаполнено(СтоимостьНаКонецМесяца) Тогда Если АмортизацияНачальныйОстаток = АмортизацияКонечныйОстаток И СтоимостьНаНачалоМесяца = СтоимостьНаКонецМесяца Тогда СуммаАмортизацииРассчитанная = СтоимостьНаНачалоМесяца - АмортизацияНачальныйОстаток; Если СуммаАмортизации <> СуммаАмортизацииРассчитанная И СуммаАмортизацииРассчитанная > СуммаАмортизации Тогда Дельта = СуммаАмортизацииРассчитанная - СуммаАмортизации; Сообщить("(НУ)ОС: " + ВыборкаПоОС.ОсновноеСредство + "(" + ВыборкаПоОС.ОсновноеСредство.Код + ")" + "истекает срок использования, остаток учтен: " + Дельта); СтрокаАмортизации.Налог = СтрокаАмортизации.Налог + Дельта; КонецЕсли; КонецЕсли; КонецЕсли; КонецЕсли; КонецЕсли; // Начисление амортизации в рамках срока полезного использования } Если СуммаАмортизации = 0 Тогда Если ВыдаватьСообщения = Истина Тогда ОбщегоНазначения.СообщитьОбОшибке(ТекстСообщения + " амортизация равна 0"); КонецЕсли; КонецЕсли; КонецЦикла; Возврат ТаблицаАмортизации; КонецФункции // РасчетАмортизацииНалогРегл
Функция «РасчетАмортизацииУпр»:
1. Добавляем код получения даты проверки, в основной запрос, последний пакет выборки:
| КОНЕЦ КАК НачислятьВТекМесяце // Начисление амортизации в рамках срока полезного использования { | ,ВЫБОР | КОГДА ЕСТЬNULL(СостоянияОСОрганизаций.ДатаСостояния, 0) = 0 | ТОГДА ДАТАВРЕМЯ(1, 1, 1) | ИНАЧЕ ДОБАВИТЬКДАТЕ(НАЧАЛОПЕРИОДА(СостоянияОСОрганизаций.ДатаСостояния, МЕСЯЦ), МЕСЯЦ, ВЫБОР КОГДА ПараметрыАмортизацииСрезПоследних.ПрименитьВТекущемМесяце ТОГДА ПараметрыАмортизацииСрезПоследних.СрокИспользованияДляВычисленияАмортизации ИНАЧЕ ПараметрыАмортизацииСрезПоследнихНачалоМесяца.СрокИспользованияДляВычисленияАмортизации КОНЕЦ) | КОНЕЦ КАК ПроверкаСрокаИспользования // Начисление амортизации в рамках срока полезного использования } |ИЗ | СписокАмортизируемыхОС | ЛЕВОЕ СОЕДИНЕНИЕ АмортизацияОстаткиИОбороты | ПО СписокАмортизируемыхОС.ОсновноеСредство = АмортизацияОстаткиИОбороты.ОсновноеСредство | ЛЕВОЕ СОЕДИНЕНИЕ СтоимостьОС | ПО СписокАмортизируемыхОС.ОсновноеСредство = СтоимостьОС.ОсновноеСредство | // начало параметры зависящие от "применить в текущем месяце" | ЛЕВОЕ СОЕДИНЕНИЕ ГрафикиАмортизацииСрезПоследних | ПО СписокАмортизируемыхОС.ОсновноеСредство = ГрафикиАмортизацииСрезПоследних.ОсновноеСредство | ЛЕВОЕ СОЕДИНЕНИЕ СпособыОтраженияРасходовПоАмортизацииСрезПоследних | ПО СписокАмортизируемыхОС.ОсновноеСредство = СпособыОтраженияРасходовПоАмортизацииСрезПоследних.ОсновноеСредство | ЛЕВОЕ СОЕДИНЕНИЕ ПервоначальныеСведенияОССрезПоследних | ПО СписокАмортизируемыхОС.ОсновноеСредство = ПервоначальныеСведенияОССрезПоследних.ОсновноеСредство | ЛЕВОЕ СОЕДИНЕНИЕ ПараметрыАмортизацииСрезПоследних | ПО СписокАмортизируемыхОС.ОсновноеСредство = ПараметрыАмортизацииСрезПоследних.ОсновноеСредство | ЛЕВОЕ СОЕДИНЕНИЕ ГрафикиАмортизацииСрезПоследнихНачалоМесяца | ПО СписокАмортизируемыхОС.ОсновноеСредство = ГрафикиАмортизацииСрезПоследнихНачалоМесяца.ОсновноеСредство | ЛЕВОЕ СОЕДИНЕНИЕ СпособыОтраженияРасходовПоАмортизацииСрезПоследнихНачалоМесяца | ПО СписокАмортизируемыхОС.ОсновноеСредство = СпособыОтраженияРасходовПоАмортизацииСрезПоследнихНачалоМесяца.ОсновноеСредство | ЛЕВОЕ СОЕДИНЕНИЕ ПараметрыАмортизацииСрезПоследнихНачалоМесяца | ПО СписокАмортизируемыхОС.ОсновноеСредство = ПараметрыАмортизацииСрезПоследнихНачалоМесяца.ОсновноеСредство // конец параметры зависящие от "применить в текущем месяце" | | ЛЕВОЕ СОЕДИНЕНИЕ ОсновныеСредстваСписанныеНаЗатратыОстатки | ПО СписокАмортизируемыхОС.ОсновноеСредство = ОсновныеСредстваСписанныеНаЗатратыОстатки.ОсновноеСредство | ЛЕВОЕ СОЕДИНЕНИЕ ВыработкаОС | ПО СписокАмортизируемыхОС.ОсновноеСредство = ВыработкаОС.ОсновноеСредство | ЛЕВОЕ СОЕДИНЕНИЕ ИзменениеПризнакаАмортизации | ПО СписокАмортизируемыхОС.ОсновноеСредство = ИзменениеПризнакаАмортизации.ОсновноеСредство // Начисление амортизации в рамках срока полезного использования { | ЛЕВОЕ СОЕДИНЕНИЕ РегистрСведений.СостоянияОС КАК СостоянияОСОрганизаций | ПО СписокАмортизируемыхОС.ОсновноеСредство = СостоянияОСОрганизаций.ОсновноеСредство | И СостоянияОСОрганизаций.Состояние = ЗНАЧЕНИЕ(Перечисление.СостоянияОС.ПринятоКУчету) // Начисление амортизации в рамках срока полезного использования } |";
2. После расчета сумм амортизации, но до возврата таблицы с итоговыми данными, вставляем доработку по анализу полученных значений:
СтрокаАмортизации.Упр = СуммаАмортизации; // Начисление амортизации в рамках срока полезного использования { Если ВыборкаПоОС.СпособНачисленияАмортизации = Перечисления.СпособыНачисленияАмортизацииОС.Линейный И ЗначениеЗаполнено(ВыборкаПоОС.ПроверкаСрокаИспользования) И ЗначениеЗаполнено(ВыборкаПоОС.СрокИспользованияДляВычисленияАмортизации) Тогда Если ВыборкаПоОС.ПроверкаСрокаИспользования = НачалоМесяца(ДатаРасчета) Тогда Если ЗначениеЗаполнено(ВыборкаПоОС.АмортизацияКонечныйОстаток) И ЗначениеЗаполнено(ВыборкаПоОС.БалансоваяСтоимость) Тогда СтоимостьКрайняя = СуммаАмортизации + ВыборкаПоОС.АмортизацияКонечныйОстаток; БалансоваяСтоимость = ВыборкаПоОС.БалансоваяСтоимость; Если БалансоваяСтоимость > СтоимостьКрайняя Тогда Дельта = БалансоваяСтоимость - СтоимостьКрайняя; Сообщить("(УУ)ОС: " + ВыборкаПоОС.ОсновноеСредство + "(" + ВыборкаПоОС.ОсновноеСредство.Код + ")" + "истекает срок использования, остаток учтен: " + Дельта); СтрокаАмортизации.Упр = СтрокаАмортизации.Упр + Дельта; КонецЕсли; КонецЕсли; КонецЕсли; КонецЕсли; // Начисление амортизации в рамках срока полезного использования } КонецЦикла; Возврат ТаблицаАмортизации; КонецФункции // РасчетАмортизацииУпр()
Поставленная задача была реализована. Скачать исходный код, доработанных функций: ДоработанныеФункции.txt.
Внимание, в доработке есть одна особенность, недавно обнаружили. Если основное средство было на консервации, тогда начисление амортизации продолжается на этот срок дополнительно. Текущий алгоритм этого не учитывает, так как срок определяется датой принятия к учету и добавлением к этому срока полезного использования.