Загрузка данных
## Причины, почему не окрашивается календарь по умолчанию
Календарь не окрашивается (или сбрасывает фон в белый цвет) на годы, для которых в регистре нет записей, по трем основным причинам в текущем коде:
1. **Очистка соответствия в `ЗаполнитьПоШаблонуНаСервере**`
В процедуре `ОбработатьИзменениеГода` последовательно вызываются:
```bsl
ЗаполнитьДаннымиТекущегоГода();
ЗаполнитьПоШаблонуНаСервере();
```
В `ЗаполнитьПоШаблонуНаСервере` выполняется цикл по всем дням года:
```bsl
Пока ДатаДня <= ДатаОкончания Цикл
ДеньВключенВГрафик = ДниВключенныеВГрафик[ДатаДня];
Если ДеньВключенВГрафик = Неопределено Тогда
ДниГрафикаСоответствие.Удалить(ДатаДня);
...
```
Если `ДниВключенныеВГрафик` возвращает пустое значение (например, когда `Объект.Код` не заполнен или в шаблоне `Объект.РабочиеДни` нет включенных дней), то цикл полностью удаляет все даты из `ДниГрафикаСоответствие`. Соответствие `ДниГрафика` становится пустым, и в событии `КалендарьПриВыводеПериода` постоянно срабатывает ветка `Иначе`:
```bsl
Если ДниГрафика.Получить(СтрокаОформленияПериода.Дата) <> Неопределено Тогда
ЦветФонаДня = WebЦвета.Роса;
Иначе
ЦветФонаДня = WebЦвета.Белый; // <--- Всегда устанавливается белый цвет
КонецЕсли;
```
2. **Незаполненный `Объект.Код**`
Если у элемента реквизит `Объект.Код` или `Объект.ПроизводственныйКалендарь` пуст, `ПараметрыЗаполнения.КодПроизводственногоКалендаря` передается пустым в функцию `ДниВключенныеВГрафик`. Из-за этого функция не может рассчитать рабочие дни года по умолчанию и возвращает пустую коллекцию.
3. **Сравнение дат со временем**
В событии `КалендарьПриВыводеПериода` обращение к `ДниГрафика.Получить(СтрокаОформленияПериода.Дата)` и `ВидыДней.Получить(СтрокаОформленияПериода.Дата)` идет по точной дате. Если в `СтрокаОформленияПериода.Дата` присутствуют секунды/часы, отличные от `00:00:00`, соответствие не найдет ключ. Поиск необходимо делать через `НачалоДня(СтрокаОформленияПериода.Дата)`.
---
## Исправление логики окрашивания по умолчанию
Для корректного отображения цвета фона и текста при смене года без записей в регистре необходимо обновить получение даты в событии вывода периода:
```bsl
&НаКлиенте
Процедура КалендарьПриВыводеПериода(Элемент, ОформлениеПериода)
Для Каждого СтрокаОформленияПериода Из ОформлениеПериода.Даты Цикл
ТекущаяДата = НачалоДня(СтрокаОформленияПериода.Дата);
ВидДня = ВидыДней.Получить(ТекущаяДата);
ЦветОформленияДня = ЦветаВидовДней.Получить(ВидДня);
Если ЦветОформленияДня = Неопределено Тогда
ЦветОформленияДня = WebЦвета.Черный;
КонецЕсли;
СтрокаОформленияПериода.ЦветТекста = ЦветОформленияДня;
Если ДниГрафика.Получить(ТекущаяДата) <> Неопределено Тогда
СтрокаОформленияПериода.ЦветФона = WebЦвета.Роса;
Иначе
СтрокаОформленияПериода.ЦветФона = WebЦвета.Белый;
КонецЕсли;
Если НерабочиеДаты.Найти(ТекущаяДата) <> Неопределено Тогда
СтрокаОформленияПериода.ЦветФона = WebЦвета.Фиолетовый;
КонецЕсли;
КонецЦикла;
КонецПроцедуры
```
---
## Подтягивание данных из регистра по другим элементам
В текущей функции `ЗаполнитьДаннымиТекущегоГода` чтение регистра выполняется следующим образом:
```bsl
ДниГрафика = Новый ФиксированноеСоответствие(
РегистрыСведений.КалендарныеГрафики.ПрочитатьДанныеГрафикаИзРегистра(Объект.Ссылка, НомерТекущегоГода));
```
Данные из регистра читаются с отбором по `Объект.Ссылка`.
* Если создается **новый** элемент справочника (`Объект.Ссылка.Пустая()`), из регистра прочитаются только те записи, у которых измерение `ГрафикРаботы` равно пустой ссылке.
* Если у другого элемента справочника созданы свои записи в регистре, в текущий (новый) элемент они **не подтянутся**, так как у них другой владелец (`ГрафикРаботы`).
---
## Проверка существования графика на выбранный год и всплывающее оповещение
Чтобы при смене года проверять, существует ли уже не помеченный на удаление график на этот год в справочнике `ГрафикРаботы`, и выводить всплывающее сообщение снизу экрана (`ПоказатьОповещениеПользователя`), необходимо добавить серверную функцию проверки и вызвать ее в обработчике `НомерТекущегоГодаПриИзменении`.
### 1. Серверная функция проверки в модуле формы
```bsl
&НаСервере
Функция ГрафикНаГодУжеСуществует(Знач ВыбранныйГод, Знач ТекущаяСсылка)
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ Первые 1
| ГрафикРаботы.Ссылка КАК Ссылка
|ИЗ
| Справочник.ГрафикРаботы КАК ГрафикРаботы
|ГДЕ
| ГрафикРаботы.Год = &Год
| И НЕ ГрафикРаботы.ПометкаУдаления
| И ГрафикРаботы.Ссылка <> &ТекущаяСсылка";
Запрос.УстановитьПараметр("Год", ВыбранныйГод);
Запрос.УстановитьПараметр("ТекущаяСсылка", ТекущаяСсылка);
Возврат НЕ Запрос.Выполнить().Пустой();
КонецФункции
```
### 2. Изменения в обработчиках на клиенте
В процедуру `НомерТекущегоГодаПриИзменении` и в процедуру завершения диалога `НомерТекущегоГодаПриИзмененииЗавершение` добавляется вызов проверки:
```bsl
&НаКлиенте
Процедура НомерТекущегоГодаПриИзменении(Элемент)
ЗаписыватьДанныеГрафика = Ложь;
Если Модифицированность Тогда
ТекстСообщения = СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(
НСтр("ru = 'Записать измененные данные за %1 год?'"),
Формат(НомерПредыдущегоГода, "ЧГ=0")
);
Оповещение = Новый ОписаниеОповещения("НомерТекущегоГодаПриИзмененииЗавершение", ЭтотОбъект);
ПоказатьВопрос(Оповещение, ТекстСообщения, РежимДиалогаВопрос.ДаНет);
Возврат;
КонецЕсли;
ПроверитьИОбработатьИзменениеГода(ЗаписыватьДанныеГрафика);
КонецПроцедуры
&НаКлиенте
Процедура НомерТекущегоГодаПриИзмененииЗавершение(Ответ, ДополнительныеПараметры) Экспорт
ПроверитьИОбработатьИзменениеГода(Ответ = КодВозвратаДиалога.Да);
КонецПроцедуры
&НаКлиенте
Процедура ПроверитьИОбработатьИзменениеГода(ЗаписыватьДанныеГрафика)
Если ГрафикНаГодУжеСуществует(НомерТекущегоГода, Объект.Ссылка) Тогда
ТекстПредупреждения = СтрШаблон("На %1 год уже создан график работы!", Формат(НомерТекущегоГода, "ЧГ=0"));
ПоказатьОповещениеПользователя(
"Внимание",
,
ТекстПредупреждения,
КартинкаОповещенияПользователя.Предупреждение
);
КонецЕсли;
ОбработатьИзменениеГода(ЗаписыватьДанныеГрафика);
Модифицированность = Ложь;
Элементы.Календарь.Обновить();
КонецПроцедуры
```