Сборник задач 1С Специалист 8. Задача 3.1

Материал из КинтВики
Перейти к: навигация, поиск


Материалы

Конфигурации

Задача 3.1 (стр 98)

Задача 3 1 Специалист 1С.jpg


Решение

Текущая версия: Медиа:Задача 3_1.dt (История)

Готовность: 100%

Сущности

График

График представляет собой регистр сведений, на который ссылается регистр расчета. В ресурсе этого регистра сведений "ГрафикРаботы" хранится значение отработанного времени. Кроме того, у графика должно быть измерение типа "Дата", по которому регистр расчета извлекает нужное значение.

Для реализации требования задания "возможность работы по нескольким графикам" нужно еще добавить (вернее использовать из каркасной конфигурации) справочник "ГрафикиРаботы".

Ссылку на справочник "ГрафикиРаботы" надо добавить как измерение регистра сведений "ГрафикРаботы". Кроме того, такую же ссылку надо добавить в реквизиты (измерения?) регистра расчета и связать (указать в поле "Связь с графиком" измерения регистра расчета) соответствующее измерение регистра сведений "ГрафикРаботы".

Оклад

В каркасной конфигурации есть регистр сведений "Сотрудник" с измерениями "Сотрудник,Подразделение,Должность" и ресурсами "Оклад" и "Состояние"={Принят,Уволен}. Регистр периодический с перодом "День".

Логично использовать этот ресурс.

Начисление зарплаты

По условиям задания начисление зарплаты производится документом "Начисление зарплаты" один раз в месяц.

В каркасной конфигурации у документа есть табличная часть "ОсновныеНачисления".

По условиям задания необходимо добавить начисление премий сотрудникам

  • премия начисляется как процент от начисленного в этом же периоде оклада
  • непонятно, всем сразу или индивидуально
  • можно добавить процент премии в шапку документа
  • можно добавить процент премии в ТЧ "ОсновныеНачисления", но вроде это не основные..
  • можно добавить ТЧ, например, "ДополнительныеНачисления", где указать процент премии

Видимо, это должен быть вид начисления "Премия" в ТЧ "ОсновныеНачисления". В "Размер" заносится процент премии. (см. Профессиональная разработка в системе 1С:Предприятие 8, стр 346)

Формирование документа

  • например, документ должен быть сформирован (кнопка), при этом заполняется ТЧ "ОсновныеНачисления".
    •  ? по всем сотрудникам (с учетом состояния сотрудника Принят/Уволен)
  • по данным задания достаточно ручного ввода начислений

В шапку документа надо добавить "ПеродРегистрации" типа Дата.

Командировки

По условиям задания начисление (строка в ТЧ "ОсновныеНачисления") может быть двух видов - оклад и командировка.

Данные о командировках вводятся только в периоде начисления.

Вид расчета "Командировка" должен вытеснять вид расчета "Оклад".

Проведение расчета начисления

В примере решения делается так:

  • В обработке проведения формируются движения по данным ТЧ "ОсновныеНачисления" (простой перенос)
  • В конце обработки проведения вызывается функция глобального модуля "Рассчитать", в которой
    • производится перебор всех созданных движений
    • в соответствии со значениями вида расчета и реквизита "Размер" формируются значения ресурса "Результат", которые записываются в тот же набор движений
    • для получения данных графика используется виртуальная таблица регистра расчета "ДанныеГрафика"
    • в запросах используется ссылка проводимого документа (регистратор)

В Профессиональная разработка в системе 1С:Предприятие 8, стр 350, рекомендуется выносить в общий модуль процедуры расчета набора записей регистра расчета, так как начисления/удержания могут формироваться разными документами.

Метаданные

"/Документы/НачислениеЗарплаты"

  • добавлен реквизит шапки "ПериодРегистрации" типа "Дата"

"/Планы видов расчета/ОсновныеНачисления":

  • нужно установить флаг "Расчет/Использует период действия"
  • добавить предопределенный элемент "Премия"
    • установить флаги Базовые/Оклад
    • установить флаги Ведущие/Оклад
    • установить флаг "Период действия является базовым периодом"
  • добавить предопределенный элемент "Командировка"
    • установить флаги Базовые/Оклад,Премия
    • установить флаги Ведущие/Оклад,Премия


"/Регистры сведений/ГрафикиРаботы":

  • добавлено измерение "График" типа "СправочникСсылка.ГрафикиРаботы"

"/Регистры сведений/Сотрудники":

  • добавлено измерение "ГрафикРаботы" типа "СправочникСсылка.ГрафикиРаботы"


Добавлен "/Регистры расчета/ОсновноеНачисление"

  • значение "Основные/План видов расчета" установлено в "/Планы видов расчета/ОсновныеНачисления"
  • установлен флаг "Основные/Период действия"
  • установлен флаг "Основные/Базовый период"
    • это означает что у каждой записи регистра есть интервал действия
  • значение "Основные/График" установлено в "/Справочники/ГрафикиРаботы"
  • значение "Основные/Значение графика" установлено в "/Регистры сведений/ГрафикиРаботы/Ресурсы/Значение"
  • значение "Основные/Дата графика" установлено в "/Регистры сведений/ГрафикиРаботы/Измерения/Дата"
  • добавлено измерение "Данные/Измерения/Сотрудник" типа "СправочникСсылка.ФизическоеЛицо"
  • добавлен ресурс "Данные/Ресурсы/Результат" типа "Число.12.2"
  • добавлен реквизит "Данные/Реквизиты/График" типа "СправочникСсылка.ГрафикиРаботы"
    • свойство реквизита "Связь с графиком" установлено в "/Регистры сведений/ГрафикиРаботы/Измерения/График"
  • добавлен реквизит "Данные/Ресурсы/Размер" типа "Число.12.2"
  • установлен регистратор "Регистраторы/Регистраторы/НачислениеЗарплаты"

Модуль проведения документа "НачислениеЗарплаты"

Процедура ОбработкаПроведения(Отказ, Режим)
	
	Для каждого строка из ОсновныеНачисления Цикл
		движение = Движения.ОсновныеНачисления.Добавить();
		движение.Сотрудник = строка.Сотрудник;
		движение.ВидРасчета = строка.ВидРасчета;
		движение.График = строка.ГрафикРаботы;
		движение.ПериодДействияНачало = строка.ДатаНачала;
		движение.ПериодДействияКонец = КонецДня(строка.ДатаОкончания);
		движение.ПериодРегистрации = ПериодРегистрации;
		движение.Размер = строка.Размер;
		движение.Сторно = ложь;
		движение.Результат = строка.Размер;
		Если строка.ВидРасчета = ПланыВидовРасчета.ОсновныеНачисления.Командировка Тогда
			движение.БазовыйПериодНачало = НачалоМесяца(ДобавитьМесяц(строка.ДатаНачала, -2));
			движение.БазовыйПериодКонец = КонецМесяца(ДобавитьМесяц(строка.ДатаНачала, -1));
		Иначе
			движение.БазовыйПериодНачало = строка.ДатаНачала;
			движение.БазовыйПериодКонец = строка.ДатаОкончания;
		КонецЕсли;
		
	КонецЦикла;
	
	Движения.ОсновныеНачисления.Записать();
	
	Зарплата.РассчитатьНачисления(Ссылка, Движения);
	
КонецПроцедуры

Общий модуль "Зарплата"

Процедура РассчитатьНачисления(Ссылка, Движения) Экспорт
	Перем НормаВремени, ОтработаноВремени;
	Для каждого запись из Движения.ОсновныеНачисления Цикл
		Если запись.ВидРасчета = ПланыВидовРасчета.ОсновныеНачисления.Оклад Тогда
			ПолучитьОтработанноеВремя(запись, НормаВремени, ОтработаноВремени);
			запись.Результат = ?(НормаВремени = 0, 0, запись.Размер * ОтработаноВремени / НормаВремени);
		КонецЕсли;
	КонецЦикла;
	Движения.ОсновныеНачисления.Записать(, Истина);
	Для каждого запись из Движения.ОсновныеНачисления Цикл
		Если запись.ВидРасчета = ПланыВидовРасчета.ОсновныеНачисления.Премия Тогда
			оклад = ПолучитьОкладЗаПериодДействия(запись);
			запись.Результат = оклад * запись.Размер / 100;
		КонецЕсли;
	КонецЦикла;
	Движения.ОсновныеНачисления.Записать(, Истина);
	Для каждого запись из Движения.ОсновныеНачисления Цикл
		Если запись.ВидРасчета = ПланыВидовРасчета.ОсновныеНачисления.Командировка Тогда
			ПолучитьОтработанноеВремя(запись, НормаВремени, ОтработаноВремени);
			размер = запись.Размер;
			Если размер = 0 Тогда
				ставка = СтавкаКомандировки(запись.Сотрудник, запись.БазовыйПериодНачало, запись.БазовыйПериодКонец);
				запись.Результат = ОтработаноВремени * ставка;
			Иначе	
				запись.Результат = ?(НормаВремени = 0, 0, размер * ОтработаноВремени / НормаВремени);
			КонецЕсли;
				
		КонецЕсли;
	КонецЦикла;
	Движения.ОсновныеНачисления.Записать(, Истина);
КонецПроцедуры

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

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

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

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

Функция СтавкаКомандировки(ссСотрудник, НачалоПериода, КонецПериода) Экспорт
	часы = РабочиеЧасыЗаПериод(ссСотрудник, НачалоПериода, КонецПериода);
	Если часы = 0 Тогда
		Возврат 0;
	КонецЕсли;
	начисления = НачисленияЗаПериод(ссСотрудник, НачалоПериода, КонецПериода);
	Возврат Окр(начисления / часы, 2);
КонецФункции


Модуль тестирования

Перем НачалоПериода;
Перем КонецПериода;
Перем ссСотрудник;
Перем ссГрафик;
Перем СекундВСутках;
Перем ЧасовВПериоде;
Перем ссНачислениеЗарплаты;


Процедура КнопкаВыполнитьНажатие(Кнопка)
	ТестОсновноеНачислениеНажатие(Кнопка);
	ТестНачислениеОдинДеньНажатие(Кнопка);
	ТестНачислениеДваДняНажатие(Кнопка);
	ТестНачислениеПремииНажатие(Кнопка);
	ТестКомандировкаНажатие(Кнопка);
	ТестНачисленияЗаПериодНажатие(Кнопка);
	ТестЧасыЗаПериодНажатие(Кнопка);
	ТестНачисленияСКомандировкойНажатие(Кнопка);
	ЧасыСКомандировкойНажатие(Кнопка);
	СтавкаКомандировкиНажатие(Кнопка);
	РасчетКомандировкиНажатие(Кнопка);
	ТестОдинДокументНажатие(Кнопка);
КонецПроцедуры

Процедура СоздатьЭлементы()
	НачалоПериода = НачалоМесяца(ДобавитьМесяц(ТекущаяДата(), -1));
	КонецПериода = КонецМесяца(ДобавитьМесяц(ТекущаяДата(), -1));
	
	обСотрудник = Справочники.ФизическиеЛица.СоздатьЭлемент();
	обСотрудник.Наименование = "Тестов Тест Тестович";
	обСотрудник.Записать();
	ссСотрудник = обСотрудник.Ссылка;
	
	обГрафик = Справочники.ГрафикиРаботы.СоздатьЭлемент();
	обГрафик.Наименование = "5-дневка";
	обГрафик.Записать();
	ссГрафик = обГрафик.Ссылка;
КонецПроцедуры

Процедура ЗаполнитьГрафик(Начало = Неопределено, Конец = Неопределено)
	Если Начало = Неопределено Тогда Начало = НачалоПериода; КонецЕсли;
	Если Конец = Неопределено Тогда Конец = КонецПериода; КонецЕсли;
	набор = РегистрыСведений.ГрафикиРаботы.СоздатьНаборЗаписей();
	набор.Отбор.График.Значение = ссГрафик;
	набор.Отбор.График.Использование = ложь;
	СекундВСутках = 60 * 60 * 24;
	ЧасовВПериоде = 0;
	дата = Начало;
	Пока дата <= Конец Цикл
		запись = набор.Добавить();
		запись.График = ссГрафик;
		запись.Период = Начало;
		запись.Дата = дата;
		запись.Значение = ? (ДеньНедели(дата) = 6 Или ДеньНедели(дата) = 7, 0, 8);
		ЧасовВПериоде = ЧасовВПериоде + запись.Значение;
		
		дата = дата + СекундВСутках;
	КонецЦикла;
	
	набор.Записать();
КонецПроцедуры

Процедура ПроверитьРавенство(об1, об2);
	Если об1 <> об2 Тогда
		ВызватьИсключение "<" + об1 + "> не равен <" + об2 + ">";
	КонецЕсли;
КонецПроцедуры

Процедура СоздатьНачисление(ВидРасчета, Размер, ДатаНачала, ДатаОкончания)
	обНачислениеЗарплаты = Документы.НачислениеЗарплаты.СоздатьДокумент();
	обНачислениеЗарплаты.Дата = ТекущаяДата();
	обНачислениеЗарплаты.ПериодРегистрации = ТекущаяДата();
	
	строка = обНачислениеЗарплаты.ОсновныеНачисления.Добавить();
	строка.Сотрудник = ссСотрудник;
	строка.ВидРасчета = ВидРасчета;
	строка.ГрафикРаботы = ссГрафик;
	строка.Размер = Размер;
	строка.ДатаНачала = ДатаНачала;
	строка.ДатаОкончания = ДатаОкончания;
	
	обНачислениеЗарплаты.Записать(РежимЗаписиДокумента.Проведение);
	ссНачислениеЗарплаты = обНачислениеЗарплаты.Ссылка;
КонецПроцедуры

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


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

Функция ДобавитьДень(дата, дней)
	Возврат дата + 60 * 60 * 24 * дней;
КонецФункции

Процедура ТестОсновноеНачислениеНажатие(Элемент)
	НачатьТранзакцию();
	Попытка
		СоздатьЭлементы();
		ЗаполнитьГрафик();
		СоздатьНачисление(ПланыВидовРасчета.ОсновныеНачисления.Оклад, 1000, НачалоПериода, КонецПериода);
		
		тзРезультат = ПолучитьФактическиеОсновныеНачисления();
		ПроверитьРавенство(1, тзРезультат.Количество());
		ПроверитьРавенство(ссСотрудник, тзРезультат[0].Сотрудник);
		ПроверитьРавенство(НачалоПериода, тзРезультат[0].ПериодДействияНачало);
		ПроверитьРавенство(КонецДня(КонецПериода), тзРезультат[0].ПериодДействияКонец);
		ПроверитьРавенство(ПланыВидовРасчета.ОсновныеНачисления.Оклад, тзРезультат[0].ВидРасчета);
		ПроверитьРавенство(1000, тзРезультат[0].Результат);
		ПроверитьРавенство(1000, тзРезультат[0].Размер);
		ПроверитьРавенство(ссГрафик, тзРезультат[0].График);
		
		
	Исключение
		Сообщить("ТестОсновноеНачислениеНажатие не пройден", СтатусСообщения.ОченьВажное);
	КонецПопытки;
	ОтменитьТранзакцию();
КонецПроцедуры

Процедура ТестНачислениеОдинДеньНажатие(Элемент)
	НачатьТранзакцию();
	Попытка
		СоздатьЭлементы();
		ЗаполнитьГрафик();
		датаРабочийДень = НачалоНедели(НачалоПериода + СекундВСутках * 10);
		
		СоздатьНачисление(ПланыВидовРасчета.ОсновныеНачисления.Оклад, 1000, датаРабочийДень, датаРабочийДень);
		
		тзРезультат = ПолучитьФактическиеОсновныеНачисления();
		ПроверитьРавенство(1, тзРезультат.Количество());
		ПроверитьРавенство(ссСотрудник, тзРезультат[0].Сотрудник);
		ПроверитьРавенство(датаРабочийДень, тзРезультат[0].ПериодДействияНачало);
		ПроверитьРавенство(КонецДня(датаРабочийДень), тзРезультат[0].ПериодДействияКонец);
		ПроверитьРавенство(ПланыВидовРасчета.ОсновныеНачисления.Оклад, тзРезультат[0].ВидРасчета);
		ПроверитьРавенство(1000, тзРезультат[0].Размер);
		ПроверитьРавенство(ссГрафик, тзРезультат[0].График);
		ПроверитьРавенство(Окр(1000 * 8 / ЧасовВПериоде, 2), тзРезультат[0].Результат);
	Исключение
		Сообщить("ТестНачислениеОдинДеньНажатие не пройден", СтатусСообщения.ОченьВажное);
	КонецПопытки;
	ОтменитьТранзакцию();
КонецПроцедуры

Процедура ТестНачислениеДваДняНажатие(Элемент)
	НачатьТранзакцию();
	Попытка
		СоздатьЭлементы();
		ЗаполнитьГрафик();
		датаРабочийДень = НачалоНедели(НачалоПериода + СекундВСутках * 10);
		датаВторойРабочийДень = НачалоНедели(НачалоПериода + СекундВСутках * 18);
		
		СоздатьНачисление(ПланыВидовРасчета.ОсновныеНачисления.Оклад, 1000, датаРабочийДень, датаРабочийДень);
		СоздатьНачисление(ПланыВидовРасчета.ОсновныеНачисления.Оклад, 1000, датаВторойРабочийДень, датаВторойРабочийДень);
		
		тзРезультат = ПолучитьФактическиеОсновныеНачисления();
		ПроверитьРавенство(2, тзРезультат.Количество());
		ПроверитьРавенство(ссСотрудник, тзРезультат[0].Сотрудник);
		ПроверитьРавенство(датаРабочийДень, тзРезультат[0].ПериодДействияНачало);
		ПроверитьРавенство(КонецДня(датаРабочийДень), тзРезультат[0].ПериодДействияКонец);
		ПроверитьРавенство(ПланыВидовРасчета.ОсновныеНачисления.Оклад, тзРезультат[0].ВидРасчета);
		ПроверитьРавенство(1000, тзРезультат[0].Размер);
		ПроверитьРавенство(ссГрафик, тзРезультат[0].График);
		ПроверитьРавенство(Окр(1000 * 8 / ЧасовВПериоде, 2), тзРезультат[0].Результат);
		
		ПроверитьРавенство(ссСотрудник, тзРезультат[1].Сотрудник);
		ПроверитьРавенство(датаВторойРабочийДень, тзРезультат[1].ПериодДействияНачало);
		ПроверитьРавенство(КонецДня(датаВторойРабочийДень), тзРезультат[1].ПериодДействияКонец);
		ПроверитьРавенство(ПланыВидовРасчета.ОсновныеНачисления.Оклад, тзРезультат[1].ВидРасчета);
		ПроверитьРавенство(1000, тзРезультат[1].Размер);
		ПроверитьРавенство(ссГрафик, тзРезультат[1].График);
		ПроверитьРавенство(Окр(1000 * 8 / ЧасовВПериоде, 2), тзРезультат[1].Результат);
	Исключение
		Сообщить("ТестНачислениеДваДняНажатие не пройден", СтатусСообщения.ОченьВажное);
	КонецПопытки;
	ОтменитьТранзакцию();
КонецПроцедуры

Процедура ТестНачислениеПремииНажатие(Элемент)
	НачатьТранзакцию();
	Попытка
		СоздатьЭлементы();
		ЗаполнитьГрафик();
		СоздатьНачисление(ПланыВидовРасчета.ОсновныеНачисления.Оклад, 1000, НачалоПериода, КонецПериода);
		СоздатьНачисление(ПланыВидовРасчета.ОсновныеНачисления.Премия, 30, НачалоПериода, КонецПериода);
		
		тзРезультат = ПолучитьФактическиеОсновныеНачисления();
		ПроверитьРавенство(2, тзРезультат.Количество());
		ПроверитьРавенство(ссСотрудник, тзРезультат[0].Сотрудник);
		ПроверитьРавенство(НачалоПериода, тзРезультат[0].ПериодДействияНачало);
		ПроверитьРавенство(КонецДня(КонецПериода), тзРезультат[0].ПериодДействияКонец);
		ПроверитьРавенство(ПланыВидовРасчета.ОсновныеНачисления.Оклад, тзРезультат[0].ВидРасчета);
		ПроверитьРавенство(1000, тзРезультат[0].Результат);
		ПроверитьРавенство(1000, тзРезультат[0].Размер);
		ПроверитьРавенство(ссГрафик, тзРезультат[0].График);
		
		ПроверитьРавенство(ссСотрудник, тзРезультат[1].Сотрудник);
		ПроверитьРавенство(НачалоПериода, тзРезультат[1].ПериодДействияНачало);
		ПроверитьРавенство(КонецДня(КонецПериода), тзРезультат[1].ПериодДействияКонец);
		ПроверитьРавенство(ПланыВидовРасчета.ОсновныеНачисления.Премия, тзРезультат[1].ВидРасчета);
		ПроверитьРавенство(30, тзРезультат[1].Размер);
		ПроверитьРавенство(ссГрафик, тзРезультат[1].График);
		ПроверитьРавенство(300, тзРезультат[1].Результат);
		
		
	Исключение
		Сообщить("ТестНачислениеПремииНажатие не пройден", СтатусСообщения.ОченьВажное);
	КонецПопытки;
	ОтменитьТранзакцию();
КонецПроцедуры

Процедура ТестКомандировкаНажатие(Элемент)
	НачатьТранзакцию();
	Попытка
		СоздатьЭлементы();
		ЗаполнитьГрафик();
		датаРабочийДень = НачалоНедели(НачалоПериода + СекундВСутках * 10);
		СоздатьНачисление(ПланыВидовРасчета.ОсновныеНачисления.Командировка, 900, датаРабочийДень, ДобавитьДень(датаРабочийДень, 0));
		СоздатьНачисление(ПланыВидовРасчета.ОсновныеНачисления.Оклад, 1000, НачалоПериода, КонецПериода);
		
		тзРезультат = ПолучитьФактическиеОсновныеНачисления();
		ПроверитьРавенство(3, тзРезультат.Количество());
		ПроверитьРавенство(ссСотрудник, тзРезультат[0].Сотрудник);
		ПроверитьРавенство(НачалоПериода, тзРезультат[0].ПериодДействияНачало);
		ПроверитьРавенство(КонецДня(ДобавитьДень(датаРабочийДень, -1)), тзРезультат[0].ПериодДействияКонец);
		ПроверитьРавенство(ПланыВидовРасчета.ОсновныеНачисления.Оклад, тзРезультат[0].ВидРасчета);
		ПроверитьРавенство(1000, тзРезультат[0].Размер);
		ПроверитьРавенство(ссГрафик, тзРезультат[0].График);
		ПроверитьРавенство(1000 - Окр(1000 * 8 / ЧасовВПериоде, 2), тзРезультат[2].Результат);
		
		ПроверитьРавенство(ссСотрудник, тзРезультат[1].Сотрудник);
		ПроверитьРавенство(датаРабочийДень, тзРезультат[1].ПериодДействияНачало);
		ПроверитьРавенство(КонецДня(датаРабочийДень), тзРезультат[1].ПериодДействияКонец);
		ПроверитьРавенство(ПланыВидовРасчета.ОсновныеНачисления.Командировка, тзРезультат[1].ВидРасчета);
		ПроверитьРавенство(900, тзРезультат[1].Размер);
		ПроверитьРавенство(ссГрафик, тзРезультат[1].График);
		ПроверитьРавенство(Окр(900 * 8 / ЧасовВПериоде, 2), тзРезультат[1].Результат);
		
		ПроверитьРавенство(ссСотрудник, тзРезультат[2].Сотрудник);
		ПроверитьРавенство(ДобавитьДень(датаРабочийДень, 1), тзРезультат[2].ПериодДействияНачало);
		ПроверитьРавенство(КонецДня(КонецПериода), тзРезультат[2].ПериодДействияКонец);
		ПроверитьРавенство(ПланыВидовРасчета.ОсновныеНачисления.Оклад, тзРезультат[2].ВидРасчета);
		ПроверитьРавенство(1000, тзРезультат[2].Размер);
		ПроверитьРавенство(ссГрафик, тзРезультат[2].График);
		ПроверитьРавенство(1000 - Окр(1000 * 8 / ЧасовВПериоде, 2), тзРезультат[2].Результат);
		
		
		
	Исключение
		Сообщить("ТестНачислениеПремииНажатие не пройден", СтатусСообщения.ОченьВажное);
	КонецПопытки;
	ОтменитьТранзакцию();
КонецПроцедуры

Процедура ТестНачисленияЗаПериодНажатие(Элемент)
	НачатьТранзакцию();
	Попытка
		СоздатьЭлементы();
		ЗаполнитьГрафик();
		СоздатьНачисление(ПланыВидовРасчета.ОсновныеНачисления.Оклад, 1000, НачалоПериода, КонецПериода);
		СоздатьНачисление(ПланыВидовРасчета.ОсновныеНачисления.Премия, 30, НачалоПериода, КонецПериода);
		
		сумма = Зарплата.НачисленияЗаПериод(ссСотрудник, НачалоПериода, КонецПериода);
		ПроверитьРавенство(1300, сумма);
		
	Исключение
		Сообщить("ТестНачисленияЗаПериодНажатие не пройден", СтатусСообщения.ОченьВажное);
	КонецПопытки;
	ОтменитьТранзакцию();
КонецПроцедуры

Процедура ТестЧасыЗаПериодНажатие(Элемент)
	НачатьТранзакцию();
	Попытка
		СоздатьЭлементы();
		ЗаполнитьГрафик();
		СоздатьНачисление(ПланыВидовРасчета.ОсновныеНачисления.Оклад, 1000, НачалоПериода, КонецПериода);
		СоздатьНачисление(ПланыВидовРасчета.ОсновныеНачисления.Премия, 30, НачалоПериода, КонецПериода);
		
		часы = Зарплата.РабочиеЧасыЗаПериод(ссСотрудник, НачалоПериода, КонецПериода);
		ПроверитьРавенство(ЧасовВПериоде, часы);
		
	Исключение
		Сообщить("ТестНачисленияЗаПериодНажатие не пройден", СтатусСообщения.ОченьВажное);
	КонецПопытки;
	ОтменитьТранзакцию();
КонецПроцедуры

Процедура ТестНачисленияСКомандировкойНажатие(Элемент)
	НачатьТранзакцию();
	Попытка
		СоздатьЭлементы();
		ЗаполнитьГрафик();
		датаРабочийДень = НачалоНедели(НачалоПериода + СекундВСутках * 10);
		СоздатьНачисление(ПланыВидовРасчета.ОсновныеНачисления.Командировка, 900, датаРабочийДень, ДобавитьДень(датаРабочийДень, 0));
		СоздатьНачисление(ПланыВидовРасчета.ОсновныеНачисления.Оклад, 1000, НачалоПериода, КонецПериода);
		СоздатьНачисление(ПланыВидовРасчета.ОсновныеНачисления.Премия, 30, НачалоПериода, КонецПериода);
		
		сумма = Зарплата.НачисленияЗаПериод(ссСотрудник, НачалоПериода, КонецПериода);
		тзРезультат = ПолучитьФактическиеОсновныеНачисления();
		
		суммаЭталон = 
			(Окр(900 * 8 / ЧасовВПериоде, 2))				//Сумма за командировку
			+ (1000 - Окр(1000 * 8 / ЧасовВПериоде, 2))		//Оклад
			+ (300 - Окр(300 * 8 / ЧасовВПериоде, 2))		//Премия
			;
		ПроверитьРавенство(суммаЭталон, сумма);
		
	Исключение
		Сообщить("ТестНачисленияСКомандировкойНажатие не пройден", СтатусСообщения.ОченьВажное);
	КонецПопытки;
	ОтменитьТранзакцию();
КонецПроцедуры

Процедура ЧасыСКомандировкойНажатие(Элемент)
	НачатьТранзакцию();
	Попытка
		СоздатьЭлементы();
		ЗаполнитьГрафик();
		датаРабочийДень = НачалоНедели(НачалоПериода + СекундВСутках * 10);
		СоздатьНачисление(ПланыВидовРасчета.ОсновныеНачисления.Командировка, 900, датаРабочийДень, ДобавитьДень(датаРабочийДень, 0));
		СоздатьНачисление(ПланыВидовРасчета.ОсновныеНачисления.Оклад, 1000, НачалоПериода, КонецПериода);
		СоздатьНачисление(ПланыВидовРасчета.ОсновныеНачисления.Премия, 30, НачалоПериода, КонецПериода);
		
		часы = Зарплата.РабочиеЧасыЗаПериод(ссСотрудник, НачалоПериода, КонецПериода);
		ПроверитьРавенство(ЧасовВПериоде, часы);
		
	Исключение
		Сообщить("ЧасыСКомандировкойНажатие не пройден", СтатусСообщения.ОченьВажное);
	КонецПопытки;
	ОтменитьТранзакцию();
КонецПроцедуры

Процедура СтавкаКомандировкиНажатие(Элемент)
	НачатьТранзакцию();
	Попытка
		СоздатьЭлементы();
		ЗаполнитьГрафик();
		датаРабочийДень = НачалоНедели(НачалоПериода + СекундВСутках * 10);
		СоздатьНачисление(ПланыВидовРасчета.ОсновныеНачисления.Командировка, 900, датаРабочийДень, ДобавитьДень(датаРабочийДень, 0));
		СоздатьНачисление(ПланыВидовРасчета.ОсновныеНачисления.Оклад, 1000, НачалоПериода, КонецПериода);
		СоздатьНачисление(ПланыВидовРасчета.ОсновныеНачисления.Премия, 30, НачалоПериода, КонецПериода);
		
		сумма = Зарплата.НачисленияЗаПериод(ссСотрудник, НачалоПериода, КонецПериода);
		
		суммаЭталон = 
			(Окр(900 * 8 / ЧасовВПериоде, 2))				//Сумма за командировку
			+ (1000 - Окр(1000 * 8 / ЧасовВПериоде, 2))		//Оклад
			+ (300 - Окр(300 * 8 / ЧасовВПериоде, 2))		//Премия
		;
			
		ставкаЭталон = Окр(суммаЭталон / ЧасовВПериоде, 2);
		
		ставка = Зарплата.СтавкаКомандировки(ссСотрудник, НачалоПериода, КонецПериода);
		
		ПроверитьРавенство(ставкаЭталон, ставка);
		
	Исключение
		Сообщить("СтавкаКомандировкиНажатие не пройден", СтатусСообщения.ОченьВажное);
	КонецПопытки;
	ОтменитьТранзакцию();
КонецПроцедуры

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

Процедура РасчетКомандировкиНажатие(Элемент)
	НачатьТранзакцию();
	Попытка
		СоздатьЭлементы();
		ЗаполнитьГрафик(НачалоМесяца(ДобавитьМесяц(НачалоПериода, -2)), КонецПериода);
		датаРабочийДень = НачалоНедели(НачалоПериода + СекундВСутках * 10);
		СоздатьНачисление(ПланыВидовРасчета.ОсновныеНачисления.Оклад, 1000, НачалоМесяца(ДобавитьМесяц(НачалоПериода, -2)), КонецМесяца(ДобавитьМесяц(НачалоПериода, -2)));
		СоздатьНачисление(ПланыВидовРасчета.ОсновныеНачисления.Оклад, 800, НачалоМесяца(ДобавитьМесяц(НачалоПериода, -1)), КонецМесяца(ДобавитьМесяц(НачалоПериода, -1)));
		
		СоздатьНачисление(ПланыВидовРасчета.ОсновныеНачисления.Командировка, 0, датаРабочийДень, ДобавитьДень(датаРабочийДень, 0));
		
		сумма = Зарплата.НачисленияЗаПериод(ссСотрудник, НачалоПериода, КонецПериода);
		
		ДатаНачалаБазыКомандировки = НачалоМесяца(ДобавитьМесяц(НачалоПериода, -2));
		ДатаКонцаБазыКомандировки = КонецМесяца(ДобавитьМесяц(НачалоПериода, -1));
		ставкаКомандировки = Окр(1800 / КоличествоЧасовВПериоде(ДатаНачалаБазыКомандировки, ДатаКонцаБазыКомандировки), 2);
		суммаЭталон = ставкаКомандировки * 8;
		
		ставка = Зарплата.СтавкаКомандировки(ссСотрудник, НачалоМесяца(ДобавитьМесяц(НачалоПериода, -2)), КонецМесяца(ДобавитьМесяц(НачалоПериода, -1)));	
		ПроверитьРавенство(ставкаКомандировки, ставка);
			
		ПроверитьРавенство(суммаЭталон, сумма);
		
	Исключение
		Сообщить("РасчетКомандировкиНажатие не пройден", СтатусСообщения.ОченьВажное);
	КонецПопытки;
	ОтменитьТранзакцию();
КонецПроцедуры

Процедура ТестОдинДокументНажатие(Элемент)
	НачатьТранзакцию();
	Попытка
		СоздатьЭлементы();
		ЗаполнитьГрафик();
		датаРабочийДень = НачалоНедели(НачалоПериода + СекундВСутках * 10);
		СоздатьНачислениеСПремиейИКомандировкой(1000, 30, 900, НачалоПериода, КонецПериода,  датаРабочийДень, ДобавитьДень(датаРабочийДень, 0));
		
		сумма = Зарплата.НачисленияЗаПериод(ссСотрудник, НачалоПериода, КонецПериода);
		тзРезультат = ПолучитьФактическиеОсновныеНачисления();
		
		суммаЭталон = 
			(Окр(900 * 8 / ЧасовВПериоде, 2))				//Сумма за командировку
			+ (1000 - Окр(1000 * 8 / ЧасовВПериоде, 2))		//Оклад
			+ (300 - Окр(300 * 8 / ЧасовВПериоде, 2))		//Премия
			;
		ПроверитьРавенство(суммаЭталон, сумма);
		
	Исключение
		Сообщить("ТестОдинДокументНажатие не пройден", СтатусСообщения.ОченьВажное);
	КонецПопытки;
	ОтменитьТранзакцию();
КонецПроцедуры

Процедура ОтчетНачисленияСотрудниковНажатие(Элемент)
	форма = Отчеты.НачисленияСотрудникам.ПолучитьФорму();
	форма.Открыть();
КонецПроцедуры

Процедура ЗаполнениеГрафикаНажатие(Элемент)
	форма = Обработки.ЗаполнениеГрафика.ПолучитьФорму();
	форма.Открыть();
КонецПроцедуры

Процедура ДокументыНачисленияНажатие(Элемент)
	форма = Документы.НачислениеЗарплаты.ПолучитьФормуСписка();
	форма.Открыть();
КонецПроцедуры

Процедура ДанныеСотрудниковНажатие(Элемент)
	форма = РегистрыСведений.Сотрудники.ПолучитьФормуСписка();
	форма.Открыть();
КонецПроцедуры

Форма документа "Начисление зарплаты"

В форме надо реализовать:

  • заполнение реквизита "ПериодРегистрации"
  • при выборе сотрудника в ТЧ желательно автоматическое заполнение
    • подразделение
    • должность
    • график работы
  • при выборе вида расчета в ТЧ желательно автоматическое заполнение
    • поля "Размер" (для Оклада - это размер оклада, для премии - процент премии)
    • периода действия начисления


Функция ОкладСотрудника(НаДату, ссСотрудник, ссПодразделение, ссДолжность)
	стИзмерения = Новый Структура("Сотрудник,Подразделение,Должность", ссСотрудник, ссПодразделение, ссДолжность);
	стРесурсы = РегистрыСведений.Сотрудники.ПолучитьПоследнее(НаДату, стИзмерения);
	Возврат стРесурсы.Оклад;
КонецФункции                                                 

Процедура ОсновныеНачисленияВидРасчетаПриИзменении(Элемент)
	строка = Элементыформы.ОсновныеНачисления.ТекущаяСтрока;
	датаНачала = НачалоМесяца(ДобавитьМесяц(ПериодРегистрации, -1));
	датаОкончания = КонецМесяца(ДобавитьМесяц(ПериодРегистрации, -1));
	Если (строка.ВидРасчета = ПланыВидовРасчета.ОсновныеНачисления.Оклад) Тогда
		Если строка.Размер = 0 Тогда
			строка.Размер = ОкладСотрудника(датаНачала, строка.Сотрудник, строка.Подразделение, строка.Должность);
			строка.ДатаНачала = датаНачала;
			строка.ДатаОкончания = датаОкончания;
		КонецЕсли;
	ИначеЕсли (строка.ВидРасчета = ПланыВидовРасчета.ОсновныеНачисления.Премия) Тогда
		Если строка.Размер = 0 Тогда
			строка.ДатаНачала = датаНачала;
			строка.ДатаОкончания = датаОкончания;
			строка.Размер = 30;
		КонецЕсли;
	ИначеЕсли (строка.ВидРасчета = ПланыВидовРасчета.ОсновныеНачисления.Командировка) Тогда
		Если строка.ДатаНачала = '00010101' Тогда
			строка.ДатаНачала = датаНачала;
			строка.ДатаОкончания = датаНачала;
		КонецЕсли;
	КонецЕсли;
КонецПроцедуры

Процедура ПередЗаписью(Отказ, РежимЗаписи, РежимПроведения)
КонецПроцедуры

Процедура ОсновныеНачисленияСотрудникПриИзменении(Элемент)
	строка = Элементыформы.ОсновныеНачисления.ТекущаяСтрока;
	Если строка.Сотрудник.Пустая() Тогда
		Возврат;
	КонецЕсли;
	тзЗаписи = РегистрыСведений.Сотрудники.СрезПоследних(Дата, Новый Структура("Сотрудник", строка.Сотрудник));
	Если тзЗаписи.Количество() > 0 Тогда
		строка.Подразделение = тзЗаписи[0].Подразделение;
		строка.Должность = тзЗаписи[0].Должность;
		строка.ГрафикРаботы = тзЗаписи[0].ГрафикРаботы;
	КонецЕсли;
	
КонецПроцедуры

Процедура ДатаПриИзменении(Элемент)
	ПериодРегистрации = НачалоМесяца(Дата);
КонецПроцедуры

Процедура ПриОткрытии()
	Если ДокументОбъект.Ссылка.Пустая() Тогда
		ПериодРегистрации = НачалоМесяца(Дата);
	КонецЕсли;
КонецПроцедуры

Обработка "Заполнение графика"

Для интерактивной проверки надо заполнить регистр "ГрафикРаботы".

В каркасную конфигурацию входит обработка "ЗаполнениеГрафика", но ее надо доработать:

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

Доработанный модуль формы

Процедура СформироватьНажатие(Элемент)
	
	Если График.Пустая() Тогда
		Сообщить("Не заполнено поле График!", СтатусСообщения.Важное);
		Возврат;
	КонецЕсли;
	
	Набор = РегистрыСведений.ГрафикиРаботы.СоздатьНаборЗаписей();
	Набор.Отбор.График.Значение = График;
	Набор.Отбор.График.Использование = Истина;
	Набор.Прочитать();
	Набор.Очистить();
	
	ЧислоСекундВСутках = 60 * 60 * 24;
	
	Дат = ДатаНачала;
	
	Пока Дат <= ДатаОкончания Цикл
		Запись = Набор.Добавить();
		Запись.График = График;
		Запись.Дата = Дат;
		Если Найти(ПолеВвода1,Строка(ДеньНедели(Дат))) Тогда
			Запись.Значение = 0;
		Иначе	          
			Запись.Значение = 8;
		КонецЕсли; 
		Дат = Дат + ЧислоСекундВСутках;
	КонецЦикла; 
	Набор.Записать();
КонецПроцедуры

Процедура ПриОткрытии()
	ДатаНачала = НачалоКвартала(ДобавитьМесяц(ТекущаяДата(),-3));
	ДатаОкончания = КонецКвартала(ТекущаяДата());
	ПолеВвода1 = "6, 7";
КонецПроцедуры

Формы списка и записи регистра "Сотрудники"

В формы надо добавить поле "ГрафикРаботы" и заполнить в предприятии выбранным графиком.

Отчет "Начисления сотрудникам"

Запрос СКД:

ВЫБРАТЬ
	ОсновныеНачисления.Сотрудник,
	ОсновныеНачисления.Результат,
	ОсновныеНачисления.ПериодДействия,
	ОсновныеНачисления.ВидРасчета,
	СотрудникиСрезПоследних.Подразделение
ИЗ
	РегистрРасчета.ОсновныеНачисления КАК ОсновныеНачисления
		ЛЕВОЕ СОЕДИНЕНИЕ РегистрСведений.Сотрудники.СрезПоследних(&НачалоПериода, ) КАК СотрудникиСрезПоследних
		ПО ОсновныеНачисления.Сотрудник = СотрудникиСрезПоследних.Сотрудник
ГДЕ
	ОсновныеНачисления.ПериодДействия МЕЖДУ &НачалоПериода И &КонецПериода

Задание периода:

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

На закладке "Ресурсы" добавляем "Сумма(Результат)".

Развороты отчета:

  • Отчет
    • Таблица
      • Строки
        • Подразделения
          • Сотрудники
            • ВидРасчета
      • Колонки
        • ПериодДействия

Значение "Настройки/ДругиеНастройки/РасположениеПолейГруппировки" устанавливаем в "Отдельно".

Перерасчеты

Хотя по условиям задачи использовать перерасчеты не требуется, они очень удобны при определении, какие документы должны быть перепроведены.

Например, при добавлении документа "Начисление зарплаты" с видом расчета "Командировка", нужно перепровести документы, в которых начисляется оклад и/или премия за тот же период.

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

Для получения списка документов, требующих перерасчета, можно использовать простейший отчет "Перерасчеты"

Запрос СКД отчета "Перерасчеты":

ВЫБРАТЬ
	ОсновныеНачисленияПерерасчет1.ОбъектПерерасчета,
	ОсновныеНачисленияПерерасчет1.ВидРасчета,
	ОсновныеНачисленияПерерасчет1.Сотрудник
ИЗ
	РегистрРасчета.ОсновныеНачисления.Перерасчет1 КАК ОсновныеНачисленияПерерасчет1

В группировки отчета добавляем "Детальные записи", в поля отчета - ОбъектПерерасчета,ВидРасчета,Сотрудник.