Своя операция в закрытии месяца? Легко!

04.09.18

Задачи пользователя - Закрытие периода

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

Для решения задачи в качестве типовой конфигурации будем использовать «1С: ERP Управление предприятием 2». 

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

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

Как реализовать такую «хотелку»? Все достаточно просто. В конфигурации уже есть отчет «Контроль оформления документов товародвижения». Отчет показывает то что нам необходимо. Осталось только сделать пункт в операциях закрытия месяца и прикрутить туда данный отчет.

Обратимся к дереву метаданных конфигурации. Нам необходимо использовать следующие объекты:

  1. Отчет: «КонтрольОформленияДокументовТовародвижений»
  2. Общий модуль: «ЗакрытиеМесяцаСервер»
  3. Перечисление: «ОперацииЗакрытияМесяца»

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

  1. Добавим в конфигурацию новое значение перечисления: «КонтрольОформленияДокументовПоОрдернымСкладам»
  2. Поместим процедуру ЗаполнитьОписаниеЭтаповЗакрытияМесяца(...) общего модуля в расширение. Наш код будет выполняться после основного кода процедуры. Его выделим в отдельную область.
  3. Добавим функцию, которая будет отвечать за открытия отчета с указанными параметрами (период, организация).
  4. Добавим процедуру, которая анализирует корректность оформления товарных документов. По сути, внутри ее производится вызов функции, в которой выполняется запрос из отчета. Именно из-за этого я не буду приводить листинг данной функции. По результатам выполнения такого запроса мы устанавливаем состояние у нашей операции.
  5. Поместим в расширение модуль объекта отчета «КонтрольОформленияДокументовТовародвижений». Мы сделаем этого для того, чтобы обработать входные параметры из операции закрытия месяца, и использовать их как значения отбора для компоновщика отчета.

 

 Общий модуль «ЗакрытиеМесяцаСервер»

#Область ОписаниеЭтаповЗакрытияМесяца

&После("ЗаполнитьОписаниеЭтаповЗакрытияМесяца")
Процедура Расш_ЗаполнитьОписаниеЭтаповЗакрытияМесяца(ТаблицаЭтапов)
	#Область КонтрольПоОрдернымСкладам	
	// наша операция будет располагаться внутри группы операций, которые находятся на 
	// "ручном контроле"
	ТекущийРодитель = ИдентификаторГруппыРучныеОперации();

	// добавляем непосредственно в таблицу, которая содержит перечень операций
	НоваяСтрока = ДобавитьЭтапВТаблицу(ТаблицаЭтапов, ТекущийРодитель,
		Перечисления.ОперацииЗакрытияМесяца.КонтрольОформленияДокументовПоОрдернымСкладам,
		Истина, Ложь, Ложь);
		
	// так как наша операция по факту показывает что есть какие то отклонения в товародвижении 
	// но не выполняет никаких действий по автоматическому исправлению ситуации, то
	// основным действием - является интерактивный вызов отчета с нужными параметрами
	НоваяСтрока.ВыполняетсяВручную = Истина;
	НоваяСтрока.ТекстВыполнить     = НСтр("ru='Показать'");
	НоваяСтрока.ДействиеИспользование = ОписаниеДействия_СервернаяПроцедура(
		"ЗакрытиеМесяцаСервер.Использование_КонтрольОформленияДокументовПоОрдернымСкладам");
	
	// укажем что действием по нажатию гиперссылки будет являться открытие отчета с автоматическим формированием 
	НоваяСтрока.ДействиеВыполнить  = ОписаниеДействия_ОткрытьФормуОтчета("Отчет.КонтрольОформленияДокументовТовародвижений.Форма", Новый Структура("СформироватьПриОткрытии", истина));
	
	#КонецОбласти //КонтрольПоОрдернымСкладам		
	
КонецПроцедуры

#КонецОбласти

#Область КонтрольОформленияДокументовПоОрдернымСкладам

// Обработчики этапа.
//
// Параметры:
//  ПараметрыОбработчика - Структура, формируемая алгоритмом заполнения операций закрытия месяца, содержит основные параметры, такие как
// 							перечень организаций, период выполнения операции...
//
Процедура Использование_КонтрольОформленияДокументовПоОрдернымСкладам(ПараметрыОбработчика) Экспорт
	
	ПараметрыРасчета = ПараметрыОбработчика.ПараметрыРасчета;
	
	// формируем параметры, которые будут использоваться для установки параметров запроса,
	// который показывает картину с корректностью отражения товародвижения
	ПараметрыПроверки = Новый Структура;
	ПараметрыПроверки.Вставить("КонецПериода", КонецМесяца(ПараметрыРасчета.ПериодРегистрации));
	Если ПараметрыОбработчика.Свойство("ПараметрыРасчета") и ПараметрыОбработчика.ПараметрыРасчета.Свойство("МассивОрганизаций") Тогда
		ПараметрыПроверки.Вставить("Организации", ПараметрыОбработчика.ПараметрыРасчета.МассивОрганизаций);
	КонецЕсли;
	
	// возвращает результат выполнения запроса, который идентичен запросу, 
	// который содержится в отчете КонтрольОформленияДокументовТовародвижений
	Результат = ТоварноМатериальныеЦенностиСервер.ОперацииОрдерныеСкладыКВыполнению(ПараметрыПроверки);
	
	// Неопределено - если данные получить не удается
	// 1 строка - если все хорошо
	// В остальных случаях - необходимо обратить внимание на корректность оформления документов!
	Если Результат = Неопределено Тогда
		
		УстановитьСостояниеНеТребуется(
			ПараметрыОбработчика,
			НСтр("ru='Отсутствует информация о неоформленных документах.'"));

	ИначеЕсли Результат.Строки.Количество() = 1 Тогда
		
		УстановитьСостояниеНеТребуется(
			ПараметрыОбработчика,
			НСтр("ru='Нет неоформленных документов.'"));
		
	Иначе
				
		ИтоговаяСтрока = Результат.Строки[Результат.Строки.Количество() - 1];		
		ТекстПояснения = НСтр("ru='Требуется оформление документов по ордерным складам'");
		
		УстановитьСостояниеНеВыполнен(
			ПараметрыОбработчика,
			ТекстПояснения,
			,
			,
			Перечисления.ВариантыВажностиПроблемыСостоянияСистемы.Предупреждение);
		
	КонецЕсли;
	
КонецПроцедуры

// Описание действия "Открыть произвольную форму".
//
// Параметры:
//	ИмяФормы 				 - Строка - имя открываемой формы 
//	ПараметрыВСтруктуреОтбор - Булево - признак того, что параметры открываемой формы надо передать внутри параметра Отбор с типом Структура
//
// Возвращаемое значение:
//	Структура - см. СтруктураОписанияДействия()
//
Функция ОписаниеДействия_ОткрытьФормуОтчета(ИмяФормы, ПараметрыОткрытия) Экспорт
	Описание = СтруктураОписанияДействия();
	
	Описание.ВидДействия = Перечисления.ВидыДействийРасшифровкиОперацийЗакрытияМесяца.ОткрытьФорму;
	Описание.ИмяФормы    = ИмяФормы;
	Описание.НаКлиенте   = Истина;
	
	ПоляПараметровФормы = "Организация, МассивОрганизаций, ПериодРегистрации, Период, НачалоПериода, КонецПериода, ДатаОкончанияПериода";
	
	Описание.Вставить("ПараметрыФормы", Новый Структура(ПоляПараметровФормы));
	Описание.ПараметрыФормы.Вставить(ЗакрытиеМесяцаСервер.ИмяСлужебногоСвойстваОткрываемыхФорм(), Истина);
	
	Для каждого Элемент из ПараметрыОткрытия Цикл
		Описание.ПараметрыФормы.Вставить(Элемент.Ключ, Элемент.Значение);	
	КонецЦикла;
	
	Возврат Описание;
	
КонецФункции

#КонецОбласти

Модуль объекта «КонтрольОформленияДокументовТовародвижений»

#Если Сервер Или ТолстыйКлиентОбычноеПриложение Или ВнешнееСоединение Тогда
	
#Область СлужебныйПрограммныйИнтерфейс

&После("ПриСозданииНаСервере")
Процедура Расш_ПриСозданииНаСервере(ЭтаФорма, Отказ, СтандартнаяОбработка)
	Параметры = ЭтаФорма.Параметры;
	Если Параметры.Свойство("ДатаОкончанияПериода") И ЗначениеЗаполнено(Параметры.ДатаОкончанияПериода) Тогда
		ЭтаФорма.Отчет.КомпоновщикНастроек.Настройки.ПараметрыДанных.УстановитьЗначениеПараметра("Период", Параметры.ДатаОкончанияПериода);				
		ЭтаФорма.Отчет.КомпоновщикНастроек.Настройки.ПараметрыДанных.УстановитьЗначениеПараметра("ТекущаяДата", Параметры.ДатаОкончанияПериода);
		ЭтаФорма.Отчет.КомпоновщикНастроек.Настройки.ПараметрыДанных.УстановитьЗначениеПараметра("ПериодГраница", Новый Граница(Параметры.ДатаОкончанияПериода, ВидГраницы.Включая));	
		
		Параметры_ = Новый Массив;
		ПользовательскийПараметр = Новый Структура("Имя, Значение", "Период", Параметры.ДатаОкончанияПериода);
		Параметры_.Добавить(ПользовательскийПараметр);
		
		КомпоновкаДанныхКлиентСервер.ДобавитьПараметрыВПользовательскиеНастройки(ЭтаФорма.Отчет.КомпоновщикНастроек, Параметры_); 
	КонецЕсли;
	
КонецПроцедуры

&Перед("ПередЗагрузкойНастроекВКомпоновщик")
Процедура Расш_ПередЗагрузкойНастроекВКомпоновщик(Контекст, КлючСхемы, КлючВарианта, НовыеНастройкиКД, НовыеПользовательскиеНастройкиКД)
	Если ТипЗнч(Контекст) = Тип("Структура") Тогда
		Возврат;
	КонецЕсли;
	
	Параметры = Контекст.Параметры;
	Если Параметры.Свойство("ДатаОкончанияПериода") И ЗначениеЗаполнено(Параметры.ДатаОкончанияПериода) Тогда
		НовыеНастройкиКД.ПараметрыДанных.УстановитьЗначениеПараметра("Период", Параметры.ДатаОкончанияПериода);				
		
		МассивПараметров = Новый Массив;
		ПользовательскийПараметр = Новый Структура("Имя, Значение", "Период", Параметры.ДатаОкончанияПериода);
		МассивПараметров.Добавить(ПользовательскийПараметр);
		
		Для Каждого ЭлементКДобавлению Из МассивПараметров Цикл
			
			// поиск подходящего пользовательского параметра
			ИдентификаторПользовательскойНастройки = "";
			ЭлементыПараметровКомпоновщика = НовыеНастройкиКД.ПараметрыДанных.Элементы;
			Для Каждого ЭлементКомпоновщика Из ЭлементыПараметровКомпоновщика Цикл
				Если ЭлементКомпоновщика.Параметр = Новый ПараметрКомпоновкиДанных(ЭлементКДобавлению.Имя) Тогда
					ИдентификаторПользовательскойНастройки = ЭлементКомпоновщика.ИдентификаторПользовательскойНастройки;
					Прервать;
				КонецЕсли;
			КонецЦикла;
			
			// если пользовательский параметр найден, то редактируем его
			Если ЗначениеЗаполнено(ИдентификаторПользовательскойНастройки) И НовыеПользовательскиеНастройкиКД <> Неопределено Тогда
				Для Каждого ЭлементНастройки Из НовыеПользовательскиеНастройкиКД.Элементы Цикл
					Если ЭлементНастройки.ИдентификаторПользовательскойНастройки = ИдентификаторПользовательскойНастройки Тогда
						ЭлементПараметра = ЭлементНастройки;
						Прервать;
					КонецЕсли;
				КонецЦикла;
				ЭлементПараметра.Значение = ЭлементКДобавлению.Значение;
				ЭлементПараметра.Использование = Истина;
			КонецЕсли;
		КонецЦикла;		
	КонецЕсли;		

КонецПроцедуры

#КонецОбласти

#КонецЕсли

Вот как это выглядит в пользовательском режиме:

Рис. 1 Наша добавленная ручная операция «Контроль оформления документов по ордерным складам».

Если требуется расшифровка – по гиперссылке «Показать» открывается отчет.

Рис 2. Отчет, вызываемый из закрытия месяца.

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

Пример №2. Перед формированием финансового результата необходимо обязательно проводить реклассификацию договоров. То есть – нужна операция, которая является существенной для определения финансового результата. Как это реализовать? Легко. Алгоритм действий такой же. Но есть небольшое дополнение:

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

Дополним уже добавленную ранее в расширение процедуру. Приводить листинг процедуры реклассификации и ее актуальности я не буду. Здесь важен другой момент: у нас будет использоваться 3 "триггера": проверка ранее выполненной реклассификации и насколько она актуальна - "ДействиеИспользование", выполнение процедуры реклассификации - "ДействиеВыполнить", открытие перечня сформированных регламентных документов - "ДействиеПодробнее".

&После("ЗаполнитьОписаниеЭтаповЗакрытияМесяца")
Процедура Расш_ЗаполнитьОписаниеЭтаповЗакрытияМесяца(ТаблицаЭтапов)

	#Область РеклассификацияЗадолженности
	Индекс = Неопределено;
	// наша операция будет распологаться внутри группы операций, которые могут
	// выполняться как автоматически, так и вручную
	ТекущийРодитель = ИдентификаторГруппыРегламентированныйУчет();
	НоваяСтрока = ДобавитьЭтапВТаблицу(ТаблицаЭтапов, ТекущийРодитель, Перечисления.ОперацииЗакрытияМесяца.РеклассификацияДоговоровКредитаИДепозита);		
	
	// вклиниваем операцию после отражения документов в регл. учете
	Строка = ТаблицаЭтапов.Найти(Перечисления.ОперацииЗакрытияМесяца.ОтражениеДокументовВРегламентированномУчете, "Код");
	Если Не Строка = Неопределено Тогда
		Индекс = ТаблицаЭтапов.Индекс(Строка);
	КонецЕсли;
	
	Если Индекс <> Неопределено Тогда
		ИндексСтроки = ТаблицаЭтапов.Индекс(НоваяСтрока); 		
		ИндексСдвига = Индекс - ИндексСтроки;
		ИндексСдвига = ?(ИндексСдвига > 0, ИндексСдвига - 1, ИндексСдвига + 1);
		
		Если ИндексСдвига <> 0 Тогда
			ТаблицаЭтапов.Сдвинуть(ИндексСтроки, ИндексСдвига);
		КонецЕсли;		
	КонецЕсли;
	
	// ключевая строка!
	// наша операция не выполнится без предыдущих операций, в частности - 
	// отражения документов в регл. учете
	НоваяСтрока.ПредшествующиеЭтапы.Добавить(Перечисления.ОперацииЗакрытияМесяца.ОтражениеДокументовВРегламентированномУчете);
	НоваяСтрока.ВыполняетсяВручную = ложь;
	НоваяСтрока.ТекстВыполнить = НСтр("ru='Выполнить'");
	НоваяСтрока.ДействиеИспользование = ОписаниеДействия_СервернаяПроцедура(
		"ЗакрытиеМесяцаСервер.Использование_ВыполнитьРеклассификациюДоговоровКредитаИДепозита");
	НоваяСтрока.ДействиеВыполнить  = ОписаниеДействия_ВыполнитьРасчет(
		"ЗакрытиеМесяцаСервер.Выполнить_ВыполнитьРеклассификациюДоговоровКредитаИДепозита");
	
	// по действию "Подробнее" - открываем журнал документов "Реклассификация",
	// с отбором по периоду и организации.
	НоваяСтрока.ДействиеПодробнее = ОписаниеДействия_ОткрытьСписокДокументовРеклассификация();
	
	#КонецОбласти //РеклассификацияЗадолженности
		
КонецПроцедуры

 

Как это выглядит:

Рис 3. Добавленная операция «Реклассификации договоров кредита и депозита»

 

Если операция успешно выполнена, то по гиперссылке будет открыт список документов:

Рис 4. Список документов с отбором по организациям и периоду

 

Резюмируя все что было описано в статье:

  1. Добавить свои операции в закрытие месяца – достаточно легко и осуществляется с минимальными изменениями конфигурации.
  1. Мы описываем только необходимые «триггеры»: выполнения, расшифровки. А также алгоритмы выполнения операции. Все остальное берет на себя механизм закрытия месяца, который все это исполняет в фоновом режиме.
  1. Можно добавлять как информационные операции (например, как описанный выше вызов отчета), так и какие-либо сложные механизмы. Так же можно добавить, например, оповещение в виде sms или письма ответственным по результатам выполнения операции, да даже той же задачи будет достаточно. Тут возможности безграничны.

 

ERP закрытие месяца операции закрытия месяца реклассификация контроль операций своя операция закрытия месяца

См. также

Анализ учета Закрытие периода Бухгалтер Платформа 1С v8.3 Бухгалтерский учет 1С:ERP Управление предприятием 2 1С:Бухгалтерия 3.0 1С:Комплексная автоматизация 2.х Россия Бухгалтерский учет Налоговый учет Налог на прибыль НДС Платные (руб)

Каждый бухгалтер не раз сталкивался с требованием от налоговой инспекции пояснить расхождения в показателях декларации по Налогу на прибыль («Доходы от реализации» + «Внереализационные доходы») и налоговой базой по НДС за год. Являются ли ошибкой подобные расхождения? Как пояснить налоговой их причину? Отчет «Анализ расхождений выручки НДС и Налога на прибыль в декларациях» для 1С (БП 3.0 ПРОФ и КОРП, КА 2, ЕRP) поможет найти все расхождения.

7200 руб.

21.10.2017    87894    320    172    

288

Закрытие периода Инструменты администратора БД Корректировка данных Бухгалтер Пользователь Бухгалтерский учет 1С:Бухгалтерия 3.0 Россия Бухгалтерский учет Платные (руб)

Расширение «Оперативное проведение» в 4 раза уменьшает время проведения документов и закрытия месяца. Является комплексным решением проблем 62 и 60 счетов. Оптимизирует проведение при включенной функциональной опции «Раздельный учет НДС». Используется в более 10 организациях уже 2 года. Совместимо с конфигурацией Бухгалтерия 3.0 (+КОРП).

14400 руб.

29.04.2020    32668    106    152    

73

Закрытие периода Оптовая торговля Розничная торговля Кассовые операции Учет доходов и расходов Бухгалтер Платформа 1С v8.3 Бухгалтерский учет 1С:Управление торговлей 10 1С:Розница 2 1С:Управление производственным предприятием 1С:Управление нашей фирмой 1.6 1С:ERP Управление предприятием 2 1С:Бухгалтерия 3.0 1С:Управление торговлей 11 1С:Комплексная автоматизация 2.х 1С:CRM ПРОФ, КОРП Розничная и сетевая торговля (FMCG) Оптовая торговля, дистрибуция, логистика Гостиничный бизнес Пищевая промышленность Россия Бухгалтерский учет Налоговый учет ЕНВД ЕСХН ИП, ПБОЮЛ, КФХ Налог на прибыль НДС УСН Платные (руб)

Внешняя обработка для ведения в электронной форме КУДиР в 1С - книги учёта доходов и расходов для предприятий на УСН, ПСН, ЕСХН. Заполнение раздела 1 - "доходы и расходы" из журнала документов вашей ИБ (любой конфигурации 1С:Предприятие 8). Формирование отчета Кассовая книга КО-4 по данным раздела 1.

7788 руб.

15.03.2016    116983    288    157    

278

Закрытие периода Бухгалтер Пользователь Платформа 1С v8.3 1С:Управление нашей фирмой 1.6 1С:Управление нашей фирмой 3.0 Россия Управленческий учет Платные (руб)

Закрытие месяца в конфигурации 1С:Управлении нашей фирмой — это очень важная задача, которую необходимо выполнять на постоянной основе. Однако, как зачастую бывает, важные и регулярные задачи могут быть упущены из виду. В связи с этим, нами было разработано решение для автоматического закрытия месяца в 1С:УНФ для оптимизации данного процесса.

3600 руб.

30.09.2022    8032    18    0    

18

Закрытие периода Бухгалтер Платформа 1С v8.3 1С:ERP Управление предприятием 2 1С:Управление торговлей 11 1С:Комплексная автоматизация 2.х Управленческий учет Платные (руб)

В современных конфигурациях УТ 11, КА 2, ERP 2 и их аналогах присутствует механизм закрытия периода. Но при ошибках учета закрыть период корректно становится практически невозможно! Давайте попробуем разобраться, как можно устранить ошибки и закрыть корректно месяц!

18000 руб.

20.03.2018    74109    274    76    

301

Закрытие периода Оптовая торговля Розничная торговля Логистика, склад и ТМЦ Бухгалтер Пользователь Платформа 1С v8.3 Оперативный учет 1С:Управление торговлей 11 Управленческий учет Платные (руб)

Менеджер забывает перемещать товар между складами, а в УТ отключен контроль остатков ? Бухгалтер готов застрелиться при закрытии месяца и выравнивании отрицательных остатков по складам и фирмам ? Используй автоматическое перемещение товаров между складами и организациями для 1С УТ 11.

5000 руб.

30.05.2019    29235    32    10    

36
Комментарии
Подписаться на ответы Инфостарт бот Сортировка: Древо развёрнутое
Свернуть все
1. murzilka88 84 06.09.18 11:15 Сейчас в теме
А еще у нас в ERP РБП автоматически распределяются!
2. PerlAmutor 155 06.09.18 16:32 Сейчас в теме
А у нас франч добавил так свою операцию при внедрении, в результате операция закрытия месяца увеличилась на +8 часов, пока я не выявил причину спустя несколько месяцев и не исправил.
Alexwarsis; +1 Ответить
3. Shmell 546 06.09.18 19:47 Сейчас в теме
(2) Поэтому нужно добавлять операции, которые достаточно быстро выполняются по отношению ко всему закрытию месяца. Иначе есть смысл их выносить за контур закрытия месяца. Если нужно, чтобы это было в закрытии месяца, то код такой операции должен быть оптимальным, не перегруженым лишними действиями. Я так подозреваю - в Вашем случае сыграл злую шутку не оптимальный код или "перегруженная" логика самой операции.
G.Shatrov; Vladimir Litvinenko; zeegin; +3 Ответить
4. rpgshnik 3795 15.09.20 06:25 Сейчас в теме
Спасибо за точку входа и хорошие примеры реализации, очень помогло 👍

От себя добавлю, что ещё помогло мне при решение задачи:

ОперацииЗакрытияМесяца.ИнициализироватьТаблицуОписанияЭтапов() // описание параметров таблицы "ТаблицаЭтапов", а вообще конечно скудное описание у всех параметров :)

Пояснение вызовов:

ДействиеИспользование - Это процедура - проверка статусов при формирование дерева закрытие месяца, допустим можно заложить ошибку используя функцию УстановитьСостояниеВыполненСОшибками() или просто добавить информацию через ДобавитьПоясняющуюИнформациюКЭтапу().

ДействиеВыполнить - Это процедура фонового последовательного выполнения закрытия месяца.
G.Shatrov; demONx7; Shmell; +3 Ответить
5. Bob_Dobr 07.09.23 11:46 Сейчас в теме
А есть статья, где "Убрать операцию в закрытии месяца - Легко!"))
Оставьте свое сообщение