понедельник, 23 марта 2015 г.

1c специалист задача 3.28

Решение:
Основные моменты задачи.

  • "Тарифная ставка в расчетном периоде может меняться не чаще, чем один раз в день." -  и больше ничего. Значит если значение часового тарифа менялось n раз в течении периода действия вида расчета "по тарифу", то значение вида расчета необходимо разбить на n+1 записей.
  • Опять сменные графики. Значит необходимо заполнить 3 графика для бригад. В условии не говорится что работа в бригаде вытесняет работу по пятидневке( например) значит предполагаю что для работы по пятидневке и по сменам будет  использоваться ВР "По тарифу"

1) ПВР. Здесь все очевидно:

"По тарифу", "Больничные" и невыход  - в Основные.
Невыход вытесняет ВР "По тарифу". Больничный вытесняет остальные ВР.
База для больничного все начисления прошлого месяца.
Профсоюз в ПВР "Удержания", база все начисления текущего месяца.

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

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

КонецПроцедуры

&НаКлиенте
Процедура Заполнить(Команда)
ЗаполнитьНаСервере(Период, График);
КонецПроцедуры

&НаСервере
Функция ПолучитьЗачениеПоДате(ТекДата,ДатаНачала)
 Разность = (ТекДата - ДатаНачала) / 86400;
Индекс = Разность % ШаблонЗаполнения.Количество();
Возврат ?(ШаблонЗаполнения[Индекс].Пометка, 24, 0);


КонецФункции


4) Создаем регистры расчета.
5) Дорабатываем документ "Начисление ЗП", в обработке проведения формируем первичные записи.

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

Процедура ОбработкаПроведения(Отказ, РежимПроведения)
Движения.ОсновныеНачисления.Записывать = Истина;
Движения.Удержания.Записывать = Истина;

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

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

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

Если  ВыборкаСтрока.ВидРасчета =ПланыВидовРасчета.ОсновныеНачисления.ПоТарифу   и ДатаНачала < ДатаКон Тогда //последняя запись
Движение = Движения.ОсновныеНачисления.Добавить();
ЗаполнитьЗначенияСвойств(Движение, ВыборкаСтрока);
Движение.ИсходныеДанные = ТекТариф;
Движение.ПериодДействияНачало = ДатаНачала;
Движение.ПериодДействияКонец = ДатаКон;
Движение.ПериодРегистрации = ПериодРегистрации;
КонецЕсли;
КонецЦикла;
КонецЕсли;
Результат = ПакетРезультатов[3];
Если Не Результат.Пустой() Тогда
Выборка = Результат.Выбрать();
Пока Выборка.Следующий() Цикл
Движение = Движения.Удержания.Добавить();
ЗаполнитьЗначенияСвойств(Движение, Выборка);
Движение.БазовыйПериодНачало = НачалоМесяца(ПериодРегистрации);
Движение.БазовыйПериодКонец  = КонецМесяца(ПериодРегистрации);
КонецЦикла;
КонецЕсли;

Движения.ОсновныеНачисления.Записать();
Движения.Удержания.Записать();
СотрудникиОсн =  ПакетРезультатов[2].Выгрузить().ВыгрузитьКолонку("Сотрудник");
СотрудникиУд =  ПакетРезультатов[3].Выгрузить().ВыгрузитьКолонку("Сотрудник");
Если ОсновныеНачисления.Найти(ПланыВидовРасчета.ОсновныеНачисления.ПоТарифу,"ВидРасчета")<> Неопределено Тогда 
Рассчет.РассчитатьНачисления(Движения.ОсновныеНачисления,ПланыВидовРасчета.ОсновныеНачисления.ПоТарифу,СотрудникиОсн);   
Движения.ОсновныеНачисления.Записать(,Истина);
КонецЕсли;
Если ОсновныеНачисления.Найти(ПланыВидовРасчета.ОсновныеНачисления.Больничный,"ВидРасчета")<> Неопределено Тогда 
Рассчет.РассчитатьНачисления(Движения.ОсновныеНачисления,ПланыВидовРасчета.ОсновныеНачисления.Больничный,СотрудникиОсн);   
Движения.ОсновныеНачисления.Записать(,Истина);
КонецЕсли;
Если Не ПакетРезультатов[3].Пустой() Тогда
Рассчет.РассчитатьУдержания(Движения.Удержания,ПланыВидовРасчета.Удержания.Профсоюз,СотрудникиУд);   
Движения.Удержания.Записать(,Истина);
КонецЕсли;

КонецПроцедуры

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

 Непосредственный расчет в общем модуле:

Процедура РассчитатьНачисления(НаборЗаписей,ВидРасчета,МассивСотрудников) Экспорт
Регистратор = НаборЗаписей.Отбор.Регистратор.Значение;

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

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

КонецЦикла;


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

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

КонецЦикла;


КонецЕсли;

КонецПроцедуры

Процедура РассчитатьУдержания(НаборЗаписей,ВидРасчета,МассивСотрудников) Экспорт
Регистратор = НаборЗаписей.Отбор.Регистратор.Значение;

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

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

КонецПроцедуры

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

Скачать решение задачи 3.28 (1с специалист по платформе)

Комментариев нет:

Отправить комментарий