В типовой конфигурации для индивидуальных предпринимателей "Отчетность предпринимателя, редакция 2.0" отсутствует возможность печати счет-фактуры. Также в конфигурации отсутствует механизм внедрения внешних печатных форм. Поделюсь опытом внедрения возможности печати счет-фактуры для документа "Оказание услуг (акт)".
В качетстве примера взята последняя на данный момент версия конфигурации "Отчетность предпринимателя, редакция 2.0 (2.0.3.22)".
Последовательность действий
1. Включаем возможность редактирования конфигурации
Для этого в конфигураторе открываем Конфигурация - Поддержка - Настройка поддержки... Нажимаем "Включить возможность изменения" и выбираем пункты "Объект поставщика редактируется с сохранением поддержки". Нажимаем ОК и сохраняем конфигурацию.
2. Раскрываем в конфигурации документ "ОказаниеУслуг" и добавляем для него макет с именем "ПФ_MXL_СчетФактура1137".
3. Копируем в макет содержимое типового макета счет-фактуры (можно взять из любой типовой конфигурации, либо скачать ниже во вложениях к этой статье).
4. В форме документа "ОказаниеУслуг" добавляем кнопку печати счет-фактуры (например, в выпадающем меню "Экспорт и печать") и создаем команду для нее с выполнением на клиенте.
5. Вставляем следующий код для команды печати счет-фактуры из формы:
Макет = "ПФ_MXL_СчетФактура1137";
УправлениеПечатьюДокументовКлиент.ПроверитьИРаспечатать(Макет, Объект.Ссылка, Новый Структура("Источник,Уникальность,Окно"));
Если Не Объект.Проведен Тогда
ПолучитьДокументНаСервере(Объект.Ссылка);
КонецЕсли;
6. Открываем модуль менеджера для объекта "ОказаниеУслуг", и в конце модуля добавляем следующий код:
//+ПечатьСчетФактуры
Функция СформироватьПечатнуюФормуСчетФактуры(МассивОбъектов, ОбъектыПечати) Экспорт
Возврат СоздатьТабличныйДокументСчетФактура(МассивОбъектов, ОбъектыПечати);
КонецФункции
Функция ФормаМножественногоЧисла(Слово1, Слово2, Слово3, Знач ЦелоеЧисло) Экспорт
// Изменим знак целого числа, иначе отрицательные числа будут неправильно преобразовываться
Если ЦелоеЧисло < 0 Тогда
ЦелоеЧисло = -1 * ЦелоеЧисло;
КонецЕсли;
Если ЦелоеЧисло <> Цел(ЦелоеЧисло) Тогда
// для нецелых чисел - всегда вторая форма
Возврат Слово2;
КонецЕсли;
// остаток
Остаток = ЦелоеЧисло%10;
Если (ЦелоеЧисло >10) И (ЦелоеЧисло<20) Тогда
// для второго десятка - всегда третья форма
Возврат Слово3;
ИначеЕсли Остаток=1 Тогда
Возврат Слово1;
ИначеЕсли (Остаток>1) И (Остаток<5) Тогда
Возврат Слово2;
Иначе
Возврат Слово3;
КонецЕсли;
КонецФункции
Функция ПроверитьВыводТабличногоДокумента(ТабДокумент, ВыводимыеОбласти, РезультатПриОшибке = Истина) Экспорт
Попытка
Возврат ТабДокумент.ПроверитьВывод(ВыводимыеОбласти);
Исключение
ОписаниеОшибки = ИнформацияОбОшибке();
ЗаписьЖурналаРегистрации(
НСТр("ru = 'Невозможно получить информацию о текущем принтере (возможно, в системе не установлено ни одного принтера)'"),
УровеньЖурналаРегистрации.Ошибка,,, ОписаниеОшибки.Описание);
Возврат РезультатПриОшибке;
КонецПопытки;
КонецФункции // ПроверитьВыводТабличногоДокумента()
Функция ПроверитьВыводСчетаФактурыНаСтраницу(ТабДокумент, ОбластьТекСтроки, ЭтоПоследняяСтрока, Макет, НомерЛиста, НомерСчетаФактуры, ЭтоУниверсальныйПередаточныйДокумент = Ложь)
// Проверим возможность вывода табличного документа
СтрокаСПодвалом = Новый Массив;
СтрокаСПодвалом.Добавить(ОбластьТекСтроки);
Если ЭтоПоследняяСтрока Тогда
// Если последняя строка, то должен поместиться еще итог и подвал
СтрокаСПодвалом.Добавить(Макет.ПолучитьОбласть("Итого"));
СтрокаСПодвалом.Добавить(Макет.ПолучитьОбласть("Подвал"));
Если ЭтоУниверсальныйПередаточныйДокумент Тогда
СтрокаСПодвалом.Добавить(Макет.ПолучитьОбласть("ПодвалНакладной"));
КонецЕсли;
КонецЕсли;
РезультатПроверки = ПроверитьВыводТабличногоДокумента(ТабДокумент, СтрокаСПодвалом);
Если НЕ РезультатПроверки Тогда
// Вывод разделителя и заголовка таблицы на новой странице
НомерЛиста = НомерЛиста + 1;
ОбластьНумерацияЛистов = Макет.ПолучитьОбласть("НумерацияЛистов");
ОбластьНумерацияЛистов.Параметры.Номер = НомерСчетаФактуры;
ОбластьНумерацияЛистов.Параметры.НомерЛиста = НомерЛиста;
ТабДокумент.ВывестиГоризонтальныйРазделительСтраниц();
ТабДокумент.Вывести(ОбластьНумерацияЛистов);
ТабДокумент.Вывести(Макет.ПолучитьОбласть("ЗаголовокТаблицы"));
КонецЕсли;
Возврат РезультатПроверки;
КонецФункции
Функция СоздатьТабличныйДокументСчетФактура(МассивОбъектов, ОбъектыПечати)
ТабДокумент = Новый ТабличныйДокумент;
ТабДокумент.ИмяПараметровПечати = "ПАРАМЕТРЫ_ПЕЧАТИ_РеализацияТоваровУслуг_СчетФактура";
Макет = ПолучитьМакет("ПФ_MXL_СчетФактура1137");
Запрос = Новый Запрос(
"ВЫБРАТЬ
| ОказаниеУслуг.Ссылка,
| ОказаниеУслуг.Номер,
| ОказаниеУслуг.Дата,
| ОказаниеУслуг.Организация КАК Поставщик,
| ОказаниеУслуг.Организация.НаименованиеПолное КАК ОрганизацияНаименованиеПолное,
| ОказаниеУслуг.Организация.Наименование КАК ОрганизацияНаименование,
| ОказаниеУслуг.Организация.ИНН КАК ИННПоставщика,
| ОказаниеУслуг.Организация.КПП КАК КПППоставщика,
| ЕСТЬNULL(ОрганизацияАдрес.ЗначенияПолей, """") КАК ЮрАдресОрганизации,
| ЕСТЬNULL(ПочтовыйАдресКонтрагента.ЗначенияПолей, """") КАК ПочтовыйАдресКонтрагента,
| ЕСТЬNULL(ФактАдресКонтрагента.ЗначенияПолей, """") КАК ФактАдресКонтрагента,
| ЕСТЬNULL(ЮрАдресКонтрагента.ЗначенияПолей, """") КАК ЮрАдресКонтрагента,
| ОказаниеУслуг.Контрагент КАК Покупатель,
| ОказаниеУслуг.Контрагент.Наименование КАК КонтрагентНаименование,
| ОказаниеУслуг.Контрагент.НаименованиеПолное КАК КонтрагентНаименованиеПолное,
| ОказаниеУслуг.Контрагент.ИНН КАК ИННПокупателя,
| ОказаниеУслуг.Контрагент.КПП КАК КПППокупателя,
| ВЫБОР
| КОГДА ОказаниеУслуг.Организация.ВидОрганизации = ЗНАЧЕНИЕ(Перечисление.ВидыОрганизаций.Организация)
| ТОГДА ЕСТЬNULL(ОтветственныеЛицаОрганизацийСрезПоследних.ФизическоеЛицо.Наименование, ""<<рукводитель не указан>>"")
| ИНАЧЕ ОказаниеУслуг.Организация.НаименованиеПолное
| КОНЕЦ КАК РуководительОрганизации,
| ОказаниеУслуг.Услуги.(
| Номенклатура.Наименование КАК ТоварНаименование,
| Номенклатура.НаименованиеПолное КАК ТоварНаименованиеПолное,
| Количество,
| Цена,
| Сумма,
| Номенклатура.ЕдиницаИзмерения КАК ЕдиницаИзмерения,
| Номенклатура.ЕдиницаИзмерения.Код КАК ЕдиницаИзмеренияКод
| ) КАК Услуги
|ИЗ
| Документ.ОказаниеУслуг КАК ОказаниеУслуг
| ЛЕВОЕ СОЕДИНЕНИЕ Справочник.Организации.КонтактнаяИнформация КАК ОрганизацияАдрес
| ПО ОказаниеУслуг.Организация = ОрганизацияАдрес.Ссылка
| И (ОрганизацияАдрес.Вид = ЗНАЧЕНИЕ(Справочник.ВидыКонтактнойИнформации.ЮрАдресОрганизации))
| ЛЕВОЕ СОЕДИНЕНИЕ Справочник.Контрагенты.КонтактнаяИнформация КАК ПочтовыйАдресКонтрагента
| ПО (ПочтовыйАдресКонтрагента.Вид = ЗНАЧЕНИЕ(Справочник.ВидыКонтактнойИнформации.ПочтовыйАдресКонтрагента))
| И ОказаниеУслуг.Контрагент = ПочтовыйАдресКонтрагента.Ссылка
| ЛЕВОЕ СОЕДИНЕНИЕ Справочник.Контрагенты.КонтактнаяИнформация КАК ФактАдресКонтрагента
| ПО (ФактАдресКонтрагента.Вид = ЗНАЧЕНИЕ(Справочник.ВидыКонтактнойИнформации.ФактАдресКонтрагента))
| И ОказаниеУслуг.Контрагент = ФактАдресКонтрагента.Ссылка
| ЛЕВОЕ СОЕДИНЕНИЕ Справочник.Контрагенты.КонтактнаяИнформация КАК ЮрАдресКонтрагента
| ПО (ЮрАдресКонтрагента.Вид = ЗНАЧЕНИЕ(Справочник.ВидыКонтактнойИнформации.ЮрАдресКонтрагента))
| И ОказаниеУслуг.Контрагент = ЮрАдресКонтрагента.Ссылка
| ЛЕВОЕ СОЕДИНЕНИЕ РегистрСведений.ОтветственныеЛицаОрганизаций.СрезПоследних(&Дата, ОтветственноеЛицо = ЗНАЧЕНИЕ(Перечисление.ОтветственныеЛицаОрганизаций.Руководитель)) КАК ОтветственныеЛицаОрганизацийСрезПоследних
| ПО ОказаниеУслуг.Организация = ОтветственныеЛицаОрганизацийСрезПоследних.Организация
|ГДЕ
| ОказаниеУслуг.Ссылка В(&МассивОбъектов)");
Запрос.УстановитьПараметр("МассивОбъектов", МассивОбъектов);
Запрос.УстановитьПараметр("Дата", ТекущаяДата());
ДанныеШапки = Запрос.Выполнить().Выбрать();
Пока ДанныеШапки.Следующий() Цикл
СведенияОПоставщике = УправлениеПечатьюДокументов.СведенияОЮрФизЛице(ДанныеШапки.Поставщик, ДанныеШапки.Дата);
СведенияОПолучателе = УправлениеПечатьюДокументов.СведенияОЮрФизЛице(ДанныеШапки.Покупатель, ДанныеШапки.Дата);
НомерСтрокиНачало = ТабДокумент.ВысотаТаблицы + 1;
ОбластьМакета = Макет.ПолучитьОбласть("Шапка");
ОбластьМакета.Параметры.Заполнить(ДанныеШапки);
НомерСчетаФактуры = "Счет-фактура № " + ДанныеШапки.Номер + " от " + Формат(ДанныеШапки.Дата, "ДЛФ='ДД'");
ОбластьМакета.Параметры.Номер = НомерСчетаФактуры;
ОбластьМакета.Параметры.НомерИсправления = "Исправление № ---- от ----";
ОбластьМакета.Параметры.ПредставлениеПоставщика = "Продавец: " + ?(ПустаяСтрока(ДанныеШапки.ОрганизацияНаименованиеПолное),
ДанныеШапки.ОрганизацияНаименование,
ДанныеШапки.ОрганизацияНаименованиеПолное);
ОбластьМакета.Параметры.АдресПоставщика = "Адрес: " + УправлениеПечатьюДокументов.ОписаниеОрганизации(СведенияОПоставщике, "ЮридическийАдрес");
ОбластьМакета.Параметры.ИННПоставщика = "ИНН/КПП продавца: " + ДанныеШапки.ИННПоставщика + ?(ЗначениеЗаполнено(ДанныеШапки.КПППоставщика), "/" + ДанныеШапки.КПППоставщика, "");
ОбластьМакета.Параметры.ПредставлениеГрузоотправителя = "Грузоотправитель и его адрес: ----";
ОбластьМакета.Параметры.ПредставлениеГрузополучателя = "Грузополучатель и его адрес: ----";
ОбластьМакета.Параметры.ПоДокументу = "К платежно-расчетному документу № от";
ОбластьМакета.Параметры.ПредставлениеПокупателя = "Покупатель: " + ?(ПустаяСтрока(ДанныеШапки.КонтрагентНаименованиеПолное),
ДанныеШапки.КонтрагентНаименование,
ДанныеШапки.КонтрагентНаименованиеПолное);
ОбластьМакета.Параметры.АдресПокупателя = "Адрес: " + УправлениеПечатьюДокументов.ОписаниеОрганизации(СведенияОПолучателе, "ЮридическийАдрес");
ОбластьМакета.Параметры.ИННПокупателя = "ИНН/КПП покупателя: " + ДанныеШапки.ИННПокупателя + ?(ЗначениеЗаполнено(ДанныеШапки.КПППокупателя), "/" + ДанныеШапки.КПППокупателя, "");
ОбластьМакета.Параметры.Валюта = "Валюта: наименование, код Российский рубль, 643";
ТабДокумент.Вывести(ОбластьМакета);
ОбластьМакета = Макет.ПолучитьОбласть("ЗаголовокТаблицы");
ТабДокумент.Вывести(ОбластьМакета);
ОбластьМакета = Макет.ПолучитьОбласть("Строка");
Выборка = ДанныеШапки.Услуги.Выбрать();
КоличествоСтраниц = 1;
СчетФактураБезНДС = Истина;
НДСНеВыставляетя = Истина;
НомерСтроки = 0;
НомерЛиста = 1;
КоличествоСтрок = Выборка.Количество();
// ради одного поля не пользуемся запросом и выгрузками, просто накопим
СуммаВсего = 0;
Пока Выборка.Следующий() Цикл
НомерСтроки = НомерСтроки + 1;
СуммаВсего = СуммаВсего + Выборка.Сумма;
ОбластьМакета.Параметры.Заполнить(Выборка);
ОбластьМакета.Параметры.СтавкаНДС = "Без НДС";
ОбластьМакета.Параметры.Стоимость = Выборка.Сумма;
ОбластьМакета.Параметры.Всего = Выборка.Сумма;
ОбластьМакета.Параметры.СуммаНДС = "без НДС";
ОбластьМакета.Параметры.Акциз = "без акциза";
ОбластьМакета.Параметры.СтранаПроисхожденияКод = "-----";
ОбластьМакета.Параметры.ПредставлениеСтраны = "-----";
ОбластьМакета.Параметры.ПредставлениеГТД = "-----";
Если НЕ ПроверитьВыводСчетаФактурыНаСтраницу(ТабДокумент, ОбластьМакета, (НомерСтроки = КоличествоСтрок), Макет, НомерЛиста, НомерСчетаФактуры) Тогда
КоличествоСтраниц = КоличествоСтраниц + 1;
КонецЕсли;
ТабДокумент.Вывести(ОбластьМакета);
КонецЦикла;
ТабДокумент.Область(ТабДокумент.ВысотаТаблицы,,ТабДокумент.ВысотаТаблицы,).ВместеСоСледующим = Истина;
// Вывод итоговых сумм
ОбластьМакета = Макет.ПолучитьОбласть("Итого");
ОбластьМакета.Параметры.ИтогоСтоимость = СуммаВсего;
ОбластьМакета.Параметры.ИтогоСуммаНДС = "без НДС";
ОбластьМакета.Параметры.ИтогоВсего = СуммаВсего;
ТабДокумент.Вывести(ОбластьМакета);
// Вывод подвала
КоличествоЛистов = СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(
НСтр("ru = 'Документ составлен на%1%2 %3'"), Символы.ПС, КоличествоСтраниц,
ФормаМножественногоЧисла(
НСтр("ru = 'листе'"), НСтр("ru = 'листах'"), НСтр("ru = 'листах'"), КоличествоСтраниц));
ОбластьМакета = Макет.ПолучитьОбласть("Подвал");
ОбластьМакета.Параметры.ФИОПБОЮЛ = ДанныеШапки.ОрганизацияНаименование;
ТабДокумент.Вывести(ОбластьМакета);
ТабДокумент.ВывестиГоризонтальныйРазделительСтраниц();
// В табличном документе зададим имя области, в которую был
// выведен объект. Нужно для возможности печати покомплектно.
УправлениеПечатью.ЗадатьОбластьПечатиДокумента(ТабДокумент,
НомерСтрокиНачало, ОбъектыПечати, ДанныеШапки.Ссылка);
КонецЦикла;
Возврат ТабДокумент;
КонецФункции // ПечатьСчетФактуры()
//-ПечатьСчетФактуры
7. Для процедуры Печать этого же модуля менеджера объекта перед "КонецЕсли" добавляем следующий код:
//+ПечатьСчетФактуры
ИначеЕсли УправлениеПечатью.НужноПечататьМакет(КоллекцияПечатныхФорм, "ПФ_MXL_СчетФактура1137") Тогда
УправлениеПечатью.ВывестиТабличныйДокументВКоллекцию(
КоллекцияПечатныхФорм,
"ПФ_MXL_СчетФактура1137",
"Счет-фактура по Постановлению № 1137", СформироватьПечатнуюФормуСчетФактуры(МассивОбъектов, ОбъектыПечати));
//-ПечатьСчетФактуры
В результате чего процедура будет выглядеть следующим образом:
Запускаем конфигурацию и проверяем.
P.S. Не забываем ставить "+" статье, если она вам пригодилась! ;)