Программирование, и жизнь

Автоматический расчет показателей норм по производственному календарю + Определение пола | Хакни ЗУП 3.1

Хакни ЗУП 3.1 без изменений конфигурации. 
Зарплата и управление персоналом 3.1.
Раздел 2. Автоматические показатели для расчета зарплаты
  • Пол человека (домашнее задание)
  • Норма по производственному календарю
  • Среднегодовая месячная норма
Быстрый переход по статьям:
Решение №2
Порой возникает необходимость считать стоимость часа для окладников по производственной норме, но если заведен документ "Индивидуальный график" то норма часов берется оттуда.
Можно конечно же завести показатель например норма по производственному календарю,
но норма для мужчин и женщин может отличаться.
Хорошо, заведем два показателя: Норма36 и Норма 40, теперь нам нужно каждый месяц вносить через данные для расчета зарплаты, но как привязать их автоматом к более чем 100 человек, а если тысяча?
Хорошо, а если надо среднегодовую месячную норму? Уже 4 показателя, и все забивать руками.
Исправим недоразумение.
Нужно воспользоваться данным решением создаем показатели НормаПК,СредняяНорма
Копируем в свое расширение обработку МенеджерРасчетаЗарплаты.
Модуль объекта:


    Функция ПолучитьНормуДней(Период)
        Норма = Новый Массив;
        //{{КОНСТРУКТОР_ЗАПРОСА_С_ОБРАБОТКОЙ_РЕЗУЛЬТАТА
        // Данный фрагмент построен конструктором.
        // При повторном использовании конструктора, внесенные вручную изменения будут утеряны!!!
       
        Запрос = Новый Запрос;
        Запрос.Текст =
        "ВЫБРАТЬ ПЕРВЫЕ 1
        |    ДанныеПроизводственногоКалендаряПомесячно.РабочихЧасовДлительностьНедели40Часов КАК Норма40,
        |    ДанныеПроизводственногоКалендаряПомесячно.РабочихЧасовДлительностьНедели36Часов КАК Норма36
        |ИЗ
        |    РегистрСведений.ДанныеПроизводственногоКалендаряПомесячно КАК ДанныеПроизводственногоКалендаряПомесячно
        |ГДЕ
        |    ДанныеПроизводственногоКалендаряПомесячно.Год = &Год
        |    И ДанныеПроизводственногоКалендаряПомесячно.Месяц = &Месяц";
       
        Запрос.УстановитьПараметр("Год", ГОД(Период));
        Запрос.УстановитьПараметр("Месяц", НАЧАЛОМЕСЯЦА(Период));
       
        РезультатЗапроса = Запрос.Выполнить();
       
        ВыборкаДетальныеЗаписи = РезультатЗапроса.Выбрать();
       
        Пока ВыборкаДетальныеЗаписи.Следующий() Цикл
            // Вставить обработку выборки ВыборкаДетальныеЗаписи
            Норма.Добавить(ВыборкаДетальныеЗаписи.Норма40);
            Норма.Добавить(ВыборкаДетальныеЗаписи.Норма36);
        КонецЦикла;
       
        Возврат Норма;
       
        //}}КОНСТРУКТОР_ЗАПРОСА_С_ОБРАБОТКОЙ_РЕЗУЛЬТАТА
    КонецФункции
   
   
    Функция ПолучитьСреднемесячнуюНорму(Период)
       
        Средний = Новый Массив;
        //{{КОНСТРУКТОР_ЗАПРОСА_С_ОБРАБОТКОЙ_РЕЗУЛЬТАТА
        // Данный фрагмент построен конструктором.
        // При повторном использовании конструктора, внесенные вручную изменения будут утеряны!!!
       
        Запрос = Новый Запрос;
        Запрос.Текст =
        "ВЫБРАТЬ ПЕРВЫЕ 1
        |    ВЫРАЗИТЬ(ВложенныйЗапрос.Средний40 / 12 КАК ЧИСЛО(10, 2)) КАК Средний40,
        |    ВЫРАЗИТЬ(ВложенныйЗапрос.Средний36 / 12 КАК ЧИСЛО(10, 2)) КАК Средний36
        |ИЗ
        |    (ВЫБРАТЬ ПЕРВЫЕ 1
        |        ДанныеПроизводственногоКалендаряПомесячно.Год КАК Год,
        |        СУММА(ДанныеПроизводственногоКалендаряПомесячно.РабочихЧасовДлительностьНедели40Часов) КАК Средний40,
        |        СУММА(ДанныеПроизводственногоКалендаряПомесячно.РабочихЧасовДлительностьНедели36Часов) КАК Средний36
        |    ИЗ
        |        РегистрСведений.ДанныеПроизводственногоКалендаряПомесячно КАК ДанныеПроизводственногоКалендаряПомесячно
        |    ГДЕ
        |        ДанныеПроизводственногоКалендаряПомесячно.Год = &Год
        |   
        |    СГРУППИРОВАТЬ ПО
        |        ДанныеПроизводственногоКалендаряПомесячно.Год) КАК ВложенныйЗапрос";
       
        Запрос.УстановитьПараметр("Год", ГОД(Период));
       
        РезультатЗапроса = Запрос.Выполнить();
       
        ВыборкаДетальныеЗаписи = РезультатЗапроса.Выбрать();
       
        Пока ВыборкаДетальныеЗаписи.Следующий() Цикл
            // Вставить обработку выборки ВыборкаДетальныеЗаписи
            Средний.Добавить(ВыборкаДетальныеЗаписи.Средний40);
            Средний.Добавить(ВыборкаДетальныеЗаписи.Средний36);
        КонецЦикла;
       
        Возврат Средний;
        //}}КОНСТРУКТОР_ЗАПРОСА_С_ОБРАБОТКОЙ_РЕЗУЛЬТАТА
       
    КонецФункции
   
    &Вместо("РезультатПоФормуле")
    Функция Расш1_РезультатПоФормуле(ИсходныеДанные, ФормулаДляВыполнения, ФормулаДляПредставления, СтрокаРасчета, ИмяПоляВидРасчета = "Начисление")
       
        ФормулаДляВычисления = СтрЗаменить(ФормулаДляВыполнения, "ИсходныеДанные.", "Параметры.");
       
        Попытка
            //Обертка для определения пола сотрудника
            //Строка расчета.Начисление содержит то что надо,
            //исходные данные несут в себе значения показателя
           
            Если ИсходныеДанные.Свойство("ПолСотрудника1")  = ИСТИНА Тогда
                Пол = СтрокаРасчета.Сотрудник.ФизическоеЛицо.Пол;
                Если Пол = Перечисления.ПолФизическогоЛица.Мужской Тогда
                    ИсходныеДанные["ПолСотрудника1"] = 1;
                Иначе
                    ИсходныеДанные["ПолСотрудника1"] = 0;
                КонецЕсли;   
            КонецЕсли;
            Если ИсходныеДанные.Свойство("НормаПК")  = ИСТИНА Тогда
                Пол = СтрокаРасчета.Сотрудник.ФизическоеЛицо.Пол;
                Если Пол = Перечисления.ПолФизическогоЛица.Мужской Тогда
                    Норма = ПолучитьНормуДней(СтрокаРасчета.ДатаНачала);
                    ИсходныеДанные["НормаПК"] = Норма[0];
                Иначе
                    Норма = ПолучитьНормуДней(СтрокаРасчета.ДатаНачала);
                    ИсходныеДанные["НормаПК"] = Норма[1];
                КонецЕсли;   
            КонецЕсли;   
            Если ИсходныеДанные.Свойство("СредняяНорма")  = ИСТИНА Тогда
                Пол = СтрокаРасчета.Сотрудник.ФизическоеЛицо.Пол;
                Если Пол = Перечисления.ПолФизическогоЛица.Мужской Тогда
                    Норма = ПолучитьСреднемесячнуюНорму(СтрокаРасчета.ДатаНачала);
                    ИсходныеДанные["СредняяНорма"] = Норма[0];
                Иначе
                    Норма = ПолучитьСреднемесячнуюНорму(СтрокаРасчета.ДатаНачала);
                    ИсходныеДанные["СредняяНорма"] = Норма[1];
                КонецЕсли;   
            КонецЕсли;   
            Если ИсходныеДанные.Свойство("СуммированныйУчет")  = ИСТИНА Тогда
                Если СтрокаРасчета.ОбщийГрафик.СуммированныйУчетРабочегоВремени = ИСТИНА Тогда
                    ИсходныеДанные["СуммированныйУчет"] = 1;   
                Иначе
                    ИсходныеДанные["СуммированныйУчет"] = 0;
                КонецЕсли;
            КонецЕсли;   
           
                       
            Возврат ОбщегоНазначения.ВычислитьВБезопасномРежиме(ФормулаДляВычисления, ИсходныеДанные);
        Исключение
            Если Не ВызыватьИсключение Тогда
                Возврат 0;
            Иначе
                ТекстСообщения = СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(
                НСтр("ru = 'При расчете начисления «%1» за %5 для сотрудника %2 возникла ошибка: %4
                |Формула, используемая при расчете: %3'"),
                СтрокаРасчета[ИмяПоляВидРасчета],
                СтрокаРасчета.ФизическоеЛицо,
                ФормулаДляПредставления,
                ИнформацияОбОшибке().Описание,
                Формат(СтрокаРасчета.ДатаНачала, "ДФ='ММММ гггг'"));
                ВызватьИсключение ТекстСообщения;
            КонецЕсли;
        КонецПопытки;
       
    КонецФункции

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

Внимание.
Я так-же могу предоставить консультации, оказать помощь в интеграции моих решений, или разработать новое, пишите ( protsenko@pm.me ) - договоримся.

Email: cHJvdHNlbmtvQHBtLm1l