Доработка типовой конфигурации УТ, для нужд управленческого учета

Зачастую, функциональности типовых решений недостаточно, и конфигурации приходится дорабатывать. К примеру возникла задача: «Организация занимается оптовой торговлей в рамках холдинга. Товар, закупленный одним из подразделений посредством купли-продажи, передается другим подразделениям и далее покупателям. В целях ведения управленческого учета необходимо организовать возможность введения в документ «Поступление товаров, услуг» величины «Управленческая себестоимость» (назначается вручную на каждую партию товара).

Необходимо, чтобы данная колонка табличной части была видна и доступна только пользователям с определенными на это полномочиями.

В системе должна быть реализована возможность оценки состояния склада (с помощью соответствующих отчетов) по управленческой себестоимости.»

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

  1. Необходимо реализовать механизм ограничения просмотра колонки «Управленческая себестоимоть». Для этого добавляем в План видов характеристик ПраваПользователей предопределенный элемент «ВидимостьКолонкиУправленческаяСебестоимость» с типом «булево». В документе Поступление товаров и услуг есть функция ПриОткрытии(). В ней в свою очередь вызывается функция УстановитьВидимость(). Именно в этой функции определяется какие колонки будут видны при открытии документа, а какие нет. Здесь же и добавим проверку на возможность просмотра колонки «Управленческая себестоимость»:

  2. ВидимостьКолонкиУпрСебестоимость = 
    УправлениеДопПравамиПользователей.РазрешитьРедактированиеУправленческойСебестоимости();
    ОбработкаТабличныхЧастей.УстановитьВидимостьКолонкиТабЧасти
         (мКолонкиТовары.УправленческаяСебестоимость, ВидимостьКолонкиУпрСебестоимость);

    Поясним. Сначала присваиваем переменной ВидимостьКолонкиУпрСебестоимость текущее значение флага Плана видов характеристик «ВидимостьКолонкиУправленческаяСебестоимость». Для этого пришлось создать функцию РазрешитьРедактированиеУправленческойСебестоимости в общем модуле УправлениеДопПравамиПользователей.

    
    // Функция возвращает признак доступности управленческой себестоимости.
    //
    // Параметры:
    // нет.
    //
    // Возвращаемое значение:
    // Истина - если можно менятьи просмптривать себестоимость, иначе Ложь.
    //
    Функция РазрешитьРедактированиеУправленческойСебестоимости() Экспорт
            СписокФильтров = 
            УправлениеПользователями.ПолучитьЗначениеПраваДляТекущегоПользователя
                       (ПланыВидовХарактеристик.ПраваПользователей.ВидимостьКолонкиУправленческаяСебестоимость, Ложь);
            Если СписокФильтров.Количество() = 0 Тогда
                 Возврат Ложь;
            ИначеЕсли СписокФильтров.Количество() > 1 Тогда
                 Возврат Истина;
            Иначе
                 Возврат СписокФильтров[0].Значение;
            КонецЕсли;
    КонецФункции
    

    Вообще говоря, можно было выполнить проверку наличие записей в списке значений переменной СписокФильтров и в процедуре «УстановитьВидимость()», однако конфигурация типовая и требует типового подхода к решению задач. Интересный факт, если посмотреть функции этого модуля, можно обнаружить, что в очень многих из них (я насчитал 10) тело функции практически одинаковое, и выполняют они одно и тоже действие…

    Вторая строка кода, собственно устанавливает видимость нашей колонки. В глобальной переменной модуля мКолонкиТовары содержится коллекция колонок табличной части Товары, документа ПТиУ, ну а функция ОбработкаТабличныхЧастей.УстановитьВидимостьКолонкиТабЧасти() – типовая и совсем не хитрая:

    
    // Изменяет видимость колонки табличного поля (напрмер, табличной части документа).
    // Параметры:
    // Колонка - колонка табличного поля,
    // Видимость - булево, устанавливаемый флаг видимости колонки.
    Процедура УстановитьВидимостьКолонкиТабЧасти(Колонка, Видимость) Экспорт
             Колонка.Видимость = Видимость;
    КонецПроцедуры // УстановитьВидимостьКолонкиТабЧасти()

    Вот таким образом решается первая часть задания

  3. Добавить Управленческую себестоимость в движения документа по регистру совсем не сложно. При проведении документа ПТиУ формируется таблица по товарам, с помощью функции ПодготовитьТаблицыДокумента(СтруктураШапкиДокумента, ТаблицаПоТоварам, ТаблицаПоУслугам, ТаблицаПоТаре); Вот в этой процедуре формируется структура полей табличной части, которая в последствии передается в качестве параметра функции РезультатЗапросаПоТоварам = ОбщегоНазначения.СформироватьЗапросПоТабличнойЧасти(ЭтотОбъект, "Товары", СтруктураПолей,СтруктураСложныхПолей);

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

    СтруктураПолей = УправлениеЗапасами.СформироватьСтруктуруПолейТовары();
    СтруктураПолей.Вставить("Услуга" , "Номенклатура.Услуга");
    СтруктураПолей.Вставить("Набор" , "Номенклатура.Набор");
    СтруктураПолей.Вставить("УправленческаяСебестоимость" , "УправленческаяСебестоимость");
    
  4. Для того что бы добавить созданный нами ресурс регистра «ПартииТоваровНаСкладах» в отчеты, нам понадобится слегка эти отчеты поправить. К примеру, отчет «ВедомостьПоПартиямНаСкладах» строится с помощью универсального отчета. Надо заметить, что это справедливо для большинства отчетов в УТ. Однако в данном отчете текст запроса формируется не автоматически (в зависимости от измерений и ресурсов регистра), а прописан в модуле самого отчета, в функции УстановитьНачальныеНастройкиУпр(). Ключевым отличием в данном случае является строка УниверсальныйОтчет.ПостроительОтчета.Текст = ТекстЗапроса;, где переменная ТекстЗапроса содержит текст запроса, определенный в модуле отчета чуть выше. В несложных отчетах, строимых на одном регистре, вроде отчета «Продажи» текст запроса формируется уже в самом модуле универсального отчета, в функции УстановитьНачальныеНастройкиПоМетаданнымРегистра(). Наша задача добавить в запрос отчета «ВедомостьПоПартиямТоваровНаСкладах» новое поле «УправленческаяСебестоимость». Точнее 4 новых поля:
  5. ИсточникДанных.УправленческаяСебестоимостьНачальныйОстаток,
    ИсточникДанных.УправленческаяСебестоимостьКонечныйОстаток, 
    ИсточникДанных.УправленческаяСебестоимостьПриход,
    ИсточникДанных.УправленческаяСебестоимостьРасход.
    

    Стоит обратить внимание (если Вы пользуетесь конструктором запросов) на вкладку «Построитель». Там определяются инструкции передаваемые построителю отчета. Так вот добавленные нами поля обязательно должны быть выбраны на вкладке «Поля». Теперь нам необходимо добавить показатель «Управленческая себестоимость» в Универсальный отчет. Делается это с помощью стоки:

    УниверсальныйОтчет.ДобавитьПоказатель("УправленческаяСебестоимостьКонечныйОстаток", "Себестоимость", Истина, "ЧЦ=15; ЧДЦ=3", "КонечныйОстаток", "Конечный остаток");

    Немного поясню. Первый переданный нами параметр – Имя показателя (т.е. название поля в запросе), второй – представление (т.е. то как он будет называться в самом отчете),третий – признак включения этого показателя в отчет по умолчанию, четвертый – формат(определяет количество знаков после запятой и т.д.), пятый – название группы к которой будет принадлежать показатель, а шестой представление этой группы. Те же действия необходимо произвести с 3-мя другими полями добавленными нами в запрос. Необходимо отметить, что анализ регистра «ПартииТоваровНаСкладах» происходит не только в отчете «Ведомость по партиям», а по сути, везде, где отображается себестоимость купленных нами товаров (например, отчет «Стоимостная оценка склада в ценах номенклатуры»). Выводить управленческую себестоимость в этих отчетах, решать, конечно же, Вам, но при наличии оставшегося времени на экзамене, я бы советовал предусмотреть максимально возможное число вариантов использования нового показателя.

  6. Осталось последняя часть. Организовать списание по новому ресурсу регистра «Партии товаров на складах». Само по себе, списание партий происходит в процедуре СписаниеПартий() общего модуля УправлениеЗапасамиПартионныйУчет. В ней мы и добавим строку: Движение.УправленческаяСебестоимость = Окр(СтрокаПартии.УправленческаяСебестоимость * КоэффСписания,2,1);

    Однако, что бы движения сформировались, необходимо добавить колонку в ТаблицаОстатковПартий, именно оттуда берется значение выражения УправленческаяСебестоимость. ТаблицаОстатковПартий в свою очередь заполняется на основании переменной СтруктураПараметров, передаваемой сюда из процедуры ВыполнитьСписание. В ней в свою очередь определена процедура

    ПолучитьОстаткиПартийНаСкладахУпр, и вот именно в ней мы должны проинициализировать нашу новую колонку ТаблицаОстатковПартий.Колонки.Добавить("УправленческаяСебестоимость"); И последнее. В процедурах ЗаполнитьЗапросПартийНаСкладахУпр() и ПолучитьДеревоПартийПереданныеУпр(), в запросе, необходимо выбрать ресурс регистра «УправленческаяСебестоимость». Вот и все… Задача решена