Исправление ТТН в бухгалтерии для Украины 2.0 и подключение доп. отчетом

Задача: исправить товарно-транспортную накладную, поставляемую в 1С:Бухгалтерии для Украины 2.0. Необходимо вывести детальные реквизиты контрагента и дать возможность вручную указать лицо, ответственное за отгрузку ТМЦ.

Документ "Реализация товаров и услуг" позволяет напечатать из него товарно-транспортную накладную. Для печати ТТН ревизитов документов не достаточно и требуется уточнение некоторых параметров у пользователя. Поэтому, в конфигурации присутствует Обработка.ПечатьТТН, которая вызывается из УправлениеПечатьюБРКлиент.ОткрытьФормуПечатиТТН по команде печати и позволяет указать на форме реквизиты заполнения ТТН.

Команда печати в документе "Реализация товаров и услуг"

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

Подготовка внешней обработки

Копируем обработку "ПечатьТТН" с помощью команды "Сохранить как внешнюю обработку, отчет".

Сохраняем как внешнюю обработку

Копируем все функции (Печать, ЗаполнитьТТН и др.) из модуля менеджера обработки в модуль объекта внешней обработки (модуля менеджера для внешних обработок не существует по понятным причинам).

Копируем содержимое модуля менеджера в модуль объекта

Конфигурация "Бухгалтерия для Украины 2.0" (2.0.8.2) использует встроенную Библиотеку Стандартных Подсистем вер. 2.2.3.29. Для подключения обработки в качестве внешнего отчета нам нужно добавить в модуль объекта экспортную функцию СведенияОВнешнейОбработке(), в которой указать параметры подключения.

Функция СведенияОВнешнейОбработке() Экспорт

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

	Возврат ПараметрыРегистрации;
	
КонецФункции

НоваяКоманда.Использование - строка с названием типа команды. Она указывает БСП каким образом запускать внешнюю обработку. Для обработки вида "Печатная форма" самые частые варианты:

  1. ВызовСерверногоМетода. В модуле объекта должна присутствовать серверная процедура "Печать", которая формирует печатную форму и передает ее в УправлениеПечатью.ВывестиТабличныйДокументВКоллекцию. Взаимодействия с пользователем не предполагается.
  2. ВызовКлиентскогоМетода.  При запуске внешней обработки с этим типом использования, происходит открытие ее формы и вызов из модуля формы клиентской процедуры "Печать". Предполагается что в она формирует табличный документ. (см. ДополнительныеОтчетыИОбработкиКлиент.ВыполнитьКлиентскийМетодОбработки() )
  3. ОткрытиеФормы. Открывается форма обработки и дальнейших действий не производится. (см. ДополнительныеОтчетыИОбработкиКлиент.ВыполнитьОткрытиеФормыОбработки() )

Поскольку нужно запрашивать у пользователя доп. данные, и, следовательно, открывать форму, нам подойдет вариант "ОткрытиеФормы".

Редактируем форму обработки

Реквизит "Документ"

При вызове внешней печатной формы открывается форма внешней обработки и в нее передается несколько параметров:

  • ДополнительнаяОбработкаСсылка - ссылка на элемент справочника "Дополнительные отчеты и обработки"
  • ИдентификаторКоманды - строка
  • ИмяФормы - строка
  • КлючСессии
  • ОбъектыНазначения - массив. Самый важный для нас параметр. Содержит массив ссылок на документы, для которых вызвана команда печати внешней печатной формы.

Параметры, которые передаются в форму внешней обработки

Поэтому в модуле формы в процедуре ПриСозданииНаСервере меняем блок

Если ЗначениеЗаполнено(Параметры.Свойство("Документ")) Тогда
Объект.Документ = Параметры.Документ;	
КонецЕсли;

на

Если Параметры.Свойство("ОбъектыНазначения") Тогда
	Попытка
		Объект.Документ = Параметры.ОбъектыНазначения[0];	
	Исключение
	КонецПопытки;
КонецЕсли;

Т.е. реквизиту "Документ" объекта обработки мы присваиваем первый элемент в массиве ОбъектыНазначения. Наша задача не предполагает одновременный вывод ТТН для нескольких документов.

Добавляем 2 новых реквизита в обработку и на форму

Добавляем в обработку 2 реквизита:

  • ОтпускРазрешил (Справочник.ФизическиеЛица)
  • ОтпускРазрешилДолжность (Справочник.Должности);

Размещаем их на форме:

Добавляем на форму 2 новых реквизита

Для упрощения кода, добавляем параметры в качестве ключевых:

Добавляем параметры формы и назначаем их ключевыми

Клиентская процедура "Печать"

В клиентской процедуре "Печать" все реквизиты формы помещаются в структуру "ПараметрыПечати". После чего вызывается процедура:

УправлениеПечатьюКлиент.ВыполнитьКомандуПечати(
	"Обработка.ПечатьТТН",
	"ТТН",
	ПараметрКоманды,
	ЭтаФорма,
	ПараметрыПечати
);

Этот метод открывает форму "ОбщаяФорма.ПечатьДокументов" и передает в нее имя менеджера печати, имя макета и параметры. В нашем случае, он не подходит. Решение которое нам подойдет найдено здесь:

//УправлениеПечатьюКлиент.ВыполнитьКомандуПечати(
//	"Справочник.ДополнительныеОтчетыИОбработки.ПечатьТТН",
//	"ПечатьТТН",
//	ПараметрКоманды,
//	ЭтаФорма,
//	ПараметрыПечати
//);

ВыполняемаяКоманда = Параметры;

//Определение и заполнение штатных параметров для общей формы ПечатьДокументов
ПараметрыОткрытия = Новый Структура("ИсточникДанных, ПараметрыИсточника");
ПараметрыОткрытия.ИсточникДанных    = ВыполняемаяКоманда.ДополнительнаяОбработкаСсылка;
ПараметрыОткрытия.ПараметрыИсточника = Новый Структура("ИдентификаторКоманды, ОбъектыНазначения");
ПараметрыОткрытия.ПараметрыИсточника.ИдентификаторКоманды = ВыполняемаяКоманда.ИдентификаторКоманды;

//Здесь передаём наши значения в модуль обработки.
//Структура для передачи параметров или значений в процедуру Печать обработки
//В процедуре печати она будет доступна в качестве первого элемента массива МассивОбъектовНазначения
ДополнительныеПараметры = Новый Структура();
//Значения для передачи
ДополнительныеПараметры.Вставить("ПараметрыПечати", ПараметрыПечати);

//Еще какие-то значения
//ДополнительныеПараметры.Вставить("РеквизитФормы1", РеквизитФормы1);
//ДополнительныеПараметры.Вставить("РеквизитФормы2", РеквизитФормы2);

//В массиве ОбъектыНазначения будут содержаться ссылки на вызвавший форму объект (документ, справочник)
// и наши значения из реквизитов формы или обработки
ОбъектыНазначения = Новый СписокЗначений;
ОбъектыНазначения.Добавить(ДополнительныеПараметры);

//Ссылки на вызвавшие форму объекты
Попытка
    Для каждого ОбъектНазначения Из ВыполняемаяКоманда.ОбъектыНазначения Цикл
        ОбъектыНазначения.Добавить(ОбъектНазначения);
    КонецЦикла; //Для каждого ОбъектНазначения Из
    ПараметрыОткрытия.ПараметрыИсточника.ОбъектыНазначения = ОбъектыНазначения;
Исключение
    //ОписаниеОшибки()
КонецПопытки;

//Вывод сформированного табличного документа в штатную форму.
ОткрытьФорму("ОбщаяФорма.ПечатьДокументов", ПараметрыОткрытия);

В этом коде структуру с нашими данными ПараметрыПечати мы помещаем в структуру ДополнительныеПараметры, которая, в свою очередь, вставляется в качестве первого элемента в массив ОбъектыНазначения. После чего открывается общая форма ПечатьДокументов и в нее передаются ПараметрыОткрытия.

Структура Параметры открытая в обработчике в процедуре "ОбщиеФормы.ПечатьДокументов.МодульФормы.ПриСозданииНаСервере"

Далее следует такая цепочка вызовов:

(1) ОбщиеФормы.ПечатьДокументов.МодульФормы.ПриСозданииНаСервере() ->
(2) ОбщиеФормы.ПечатьДокументов.МодульФормы.СформироватьПечатныеФормы() ->
(3) ОбщиеМодули.ДополнительныеОтчетыИОбработки.ПечатьПоВнешнемуИсточнику() ->
(4) ВнешняяОбработка.ПечатьТТН.МодульОбъекта.Печать() 

Редактируем модуль объекта

Таким образом мы возвращаемся в модуль объекта в серверную процедуру Печать() и извлекаем ПараметрыПечати с нашими данными из МассиваОбъектов с последующим его удалением из массиваМодифицированная процедура Печать (количество принимаемых параметров функции уменьшилось):

// Сформировать печатные формы объектов
//
// ВХОДЯЩИЕ:
//   ИменаМакетов    - Строка    - Имена макетов, перечисленные через запятую
//   МассивОбъектов  - Массив    - Массив ссылок на объекты которые нужно распечатать
//   ПараметрыПечати - Структура - Структура дополнительных параметров печати
//
// ИСХОДЯЩИЕ:
//   КоллекцияПечатныхФорм - Таблица значений - Сформированные табличные документы
//   ПараметрыВывода       - Структура        - Параметры сформированных табличных документов
//
Процедура Печать(МассивОбъектов, КоллекцияПечатныхФорм, ОбъектыПечати, ПараметрыВывода) Экспорт
    
    //Получаем переданные из формы параметры для печати документа
    //Из формы МассивОбъектовНазначения передаётся как список значений, поэтому преобразуем его в массив
    Если ТипЗнч(МассивОбъектов) = Тип("СписокЗначений") Тогда
        МассивОбъектов = МассивОбъектов.ВыгрузитьЗначения();
    КонецЕсли;

    //Присваиваем значение по умолчанию нашему параметру, переданному из формы
    ПечататьСкидки = Истина;

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

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

Макет = УправлениеПечатью.ПолучитьМакет("Обработка.ПечатьТТН.ПФ_MXL_ТТН2014");

на

Макет = ЭтотОбъект.ПолучитьМакет("ПФ_MXL_ТТН2014");

Выводим в макет ответственное лицо, если оно указано

В процедуре ЗаполнитьТТН2014 получаем из структуры ПараметрыПечати 2 наших добавленных реквизита ОтпускРазрешил и ОтпускРазрешилДолжность. 

ОтпускРазрешил            = ПараметрыПечати.ОтпускРазрешил;
ОтпускРазрешилДолжность	= ПараметрыПечати.ОтпускРазрешилДолжность;

Если оба эти реквизита заполнены - мы будем использовать их вместо стандартных значений, получаемых из ОтветственныеЛицаБП.ОтветственныеЛица. Поэтому заменяем код:

Руководители = ОтветственныеЛицаБП.ОтветственныеЛица(Шапка.Руководители, Шапка.ДатаДокумента);
	
// Отпуск товара разрешил
ФИООтпускРазрешил       = Руководители.РуководительПредставление;
ДолжностьОтпускРазрешил = Руководители.РуководительДолжность;

на

Если ЗначениеЗаполнено(ОтпускРазрешил) И ЗначениеЗаполнено(ОтпускРазрешилДолжность) Тогда	
	Запрос = Новый Запрос;
	Запрос.Текст = 
		"ВЫБРАТЬ
		|	ФИОФизЛицСрезПоследних.Фамилия,
		|	ФИОФизЛицСрезПоследних.Имя,
		|	ФИОФизЛицСрезПоследних.Отчество
		|ИЗ
		|	РегистрСведений.ФИОФизическихЛиц.СрезПоследних КАК ФИОФизЛицСрезПоследних
		|ГДЕ
		|	ФИОФизЛицСрезПоследних.ФизическоеЛицо = &ФизЛицо";
		
	Запрос.УстановитьПараметр("ФизЛицо", ОтпускРазрешил);
	
	РезультатЗапроса = Запрос.Выполнить();
	
	ВыборкаДетальныеЗаписи = РезультатЗапроса.Выбрать();
	
	Пока ВыборкаДетальныеЗаписи.Следующий() Цикл
		ФИООтпускРазрешил = ОбщегоНазначенияБПВызовСервера.ПолучитьФамилиюИмяОтчество(ВыборкаДетальныеЗаписи.Фамилия, ВыборкаДетальныеЗаписи.Имя, ВыборкаДетальныеЗаписи.Отчество);
	КонецЦикла;
		
	ДолжностьОтпускРазрешил 	= Строка(ОтпускРазрешилДолжность);	
Иначе
	Руководители = ОтветственныеЛицаБП.ОтветственныеЛица(Шапка.Руководители, Шапка.ДатаДокумента);
	// Отпуск товара разрешил
	ФИООтпускРазрешил       = Руководители.РуководительПредставление;
	ДолжностьОтпускРазрешил = Руководители.РуководительДолжность;	
КонецЕсли; 

Заменяем представление грузополучателя

Это не сложно. В процедуре ЗаполнитьТТН2014 меняем код

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

на нужное нам

ОбластьМакета.Параметры.ГрузополучательПредставление  = ОбщегоНазначенияБПВызовСервера.ОписаниеОрганизации(СведенияОГрузополучателе,  "ПолноеНаименование,ЮридическийАдрес,ИНН,Телефоны,НомерСчета,Банк,МФО,КодПоЕДРПОУ,",, КодЯзыкаПечать);

Проверяем результат

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

Форма настроек товарно-транспортной накладной

Сформированная ТТН:

Готовая сформированная ТТН


Похожие материалы

Комментарии