315 lines
19 KiB
Plaintext
315 lines
19 KiB
Plaintext
конст КЛЮЧ_ЗАДАНИЯ_ЗАГРУЗКИ_КУРСОВ = "RatesLoadTask"
|
||
|
||
@ВПодсистеме
|
||
исключение ИсключениеЗагрузкиКурсовВалют
|
||
обз знч Валюта: Валюты.Ссылка
|
||
;
|
||
|
||
/**
|
||
Описание:
|
||
Загружает курсы валют из справочника Валюты за заданный период
|
||
Параметры:
|
||
НачалоПериода - дата начала периода загрузки
|
||
КонецПериода - дата конца периода загрузки
|
||
*/
|
||
@ВПроекте
|
||
метод ЗагрузитьКурсыВалют(НачалоПериода: Дата, КонецПериода: Дата)
|
||
знч Событие = новый ОперацияЗагрузкиКурсовВалют(
|
||
НачалоПериодаЗагрузки = НачалоПериода.Представление(),
|
||
КонецПериодаЗагрузки = КонецПериода.Представление()
|
||
)
|
||
|
||
исп Событие.ЗаписатьНачало()
|
||
|
||
знч МассивВалют = Валюты.ПолучитьВсе()
|
||
для Валюта из МассивВалют
|
||
попытка
|
||
ЗагрузитьКурсыВалюты(Валюта, НачалоПериода, КонецПериода)
|
||
поймать Искл: ИсключениеЗагрузкиКурсовВалют
|
||
новый ОшибкаЗагрузкиКурсовВалюты(
|
||
Валюта = Искл.Валюта.Представление(),
|
||
ОписаниеОшибки = "%{Искл.Описание}",
|
||
ХарактерОшибки = ХарактерОшибки.ДляПользователя,
|
||
Важность = ВажностьСобытияЖурналаСобытий.Высокая
|
||
).Записать()
|
||
|
||
выбросить новый ИсключениеВыполнения(Искл.Описание, Искл)
|
||
;
|
||
;
|
||
;
|
||
|
||
/**
|
||
Описание:
|
||
Загружает курсы валют из справочника Валюты начиная с последней даты курса и по текущую дату
|
||
*/
|
||
@ВПроекте
|
||
метод ЗагрузитьКурсыВалют()
|
||
знч ТекущаяДата = Дата.Сейчас()
|
||
|
||
знч Событие = новый ОперацияЗагрузкиКурсовВалют(
|
||
НачалоПериодаЗагрузки = "",
|
||
КонецПериодаЗагрузки = ТекущаяДата.Представление()
|
||
)
|
||
|
||
исп Событие.ЗаписатьНачало()
|
||
|
||
знч ДатыКурсов = ПолучитьКурсыВалют()
|
||
|
||
для ДатаКурса из ДатыКурсов
|
||
попытка
|
||
ЗагрузитьКурсыВалюты(ДатаКурса.Валюта, ДатаКурса.Период == Неопределено ? ТекущаяДата : ДатаКурса.Период, ТекущаяДата)
|
||
поймать Искл: ИсключениеЗагрузкиКурсовВалют
|
||
новый ОшибкаЗагрузкиКурсовВалюты(
|
||
Валюта = Искл.Валюта.Представление(),
|
||
ОписаниеОшибки = "%{Искл.Описание}",
|
||
ХарактерОшибки = ХарактерОшибки.ДляПользователя,
|
||
Важность = ВажностьСобытияЖурналаСобытий.Высокая
|
||
).Записать()
|
||
|
||
выбросить новый ИсключениеВыполнения(Искл.Описание)
|
||
;
|
||
;
|
||
;
|
||
|
||
/**
|
||
Описание:
|
||
Получение курса валюты на дату
|
||
Параметры:
|
||
Валюта - валюта, курс которой требуется получить
|
||
ДатаКурса - дата, на которую требуется получить курс
|
||
Возвращает:
|
||
Структура КурсВалюты или Неопределено, если курс не установлен
|
||
*/
|
||
@ВПроекте
|
||
метод ПолучитьКурсВалюты(Валюта: Валюты.Ссылка, ДатаКурса: Дата): КурсВалюты?
|
||
знч Запрос = Запрос{
|
||
ВЫБРАТЬ
|
||
КурсыВалютСрезПоследних.Валюта КАК Валюта,
|
||
КурсыВалютСрезПоследних.Период КАК Период,
|
||
КурсыВалютСрезПоследних.Курс КАК Курс,
|
||
КурсыВалютСрезПоследних.Кратность КАК Кратность
|
||
ЗАПОЛНИТЬ КурсВалюты
|
||
ИЗ
|
||
КурсыВалют.СрезПоследних(%ДатаКурса) КАК КурсыВалютСрезПоследних
|
||
ГДЕ
|
||
КурсыВалютСрезПоследних.Валюта == %Валюта
|
||
}
|
||
|
||
возврат Запрос.Выполнить().ЕдинственныйИлиУмолчание()
|
||
;
|
||
|
||
/**
|
||
Описание:
|
||
Получение курсов валют из справочника Валюты
|
||
Возвращает:
|
||
Массив структур КурсВалюты
|
||
Замечания:
|
||
Если для валюты не загружен курс, значением поля Период структуры будет Неопределено
|
||
*/
|
||
@ВПроекте
|
||
метод ПолучитьКурсыВалют(): Массив<КурсВалюты>
|
||
знч Курсы = <КурсВалюты>[]
|
||
|
||
знч Запрос = Запрос{
|
||
ВЫБРАТЬ
|
||
Валюты.Ссылка КАК Валюта,
|
||
Валюты.Код КАК Код,
|
||
Курсы.Период.ЗаменитьNull(Неопределено) КАК Период,
|
||
Курсы.Курс.ЗаменитьNull(0) КАК Курс,
|
||
Курсы.Кратность.ЗаменитьNull(0) КАК Кратность
|
||
ИЗ
|
||
Валюты КАК Валюты
|
||
ЛЕВОЕ СОЕДИНЕНИЕ КурсыВалют.СрезПоследних() КАК Курсы
|
||
ПО Валюты.Ссылка == Курсы.Валюта
|
||
ГДЕ
|
||
Валюты.Код != %{Валюты.КОД_БАЗОВОЙ_ВАЛЮТЫ}
|
||
}
|
||
|
||
для СтрокаРезультата из Запрос.Выполнить()
|
||
знч Курс = новый КурсВалюты(
|
||
Валюта = СтрокаРезультата.Валюта,
|
||
Код = СтрокаРезультата.Код,
|
||
Период = СтрокаРезультата.Период,
|
||
Курс = СтрокаРезультата.Курс,
|
||
Кратность = СтрокаРезультата.Кратность
|
||
)
|
||
|
||
Курсы.Добавить(Курс)
|
||
;
|
||
|
||
возврат Курсы
|
||
;
|
||
|
||
/**
|
||
Описание:
|
||
Пересчитывает сумму в базовую валюту
|
||
Параметры:
|
||
Сумма - сумма, которую требуется пересчитать
|
||
Валюта - пересчитываемая валюта
|
||
Возвращает:
|
||
Сумма, пересчитанная по курсу
|
||
*/
|
||
@ВПроекте
|
||
метод ПересчитатьПоКурсу(Сумма: Число, Валюта: Валюты.Ссылка): Число
|
||
знч КурсВалюты = ПолучитьКурсВалюты(Валюта, Дата.Сейчас())
|
||
если КурсВалюты != Неопределено и КурсВалюты.Кратность != 0
|
||
возврат (Сумма * КурсВалюты.Курс / КурсВалюты.Кратность).Округлить(2)
|
||
иначе
|
||
возврат 0
|
||
;
|
||
;
|
||
|
||
/**
|
||
Описание:
|
||
Загружает курсы определенной валюты за заданный период с сайта ЦБ
|
||
Параметры:
|
||
ВалютаСсылка - валюта, курсы которой требуется загрузить
|
||
НачалоПериода - дата начала периода загрузки
|
||
КонецПериода - дата конца периода загрузки
|
||
Исключения:
|
||
ОшибкаЗагрузкиКурсовВалют -
|
||
если не удалось найти валюту во внешнем справочнике и при других ошибках загрузки
|
||
Замечания:
|
||
Идентификатор валюты во внешнем справочнике определяется по коду валюты
|
||
и сохраняется в поле ВнешнийИдентификатор объекта Валюты
|
||
*/
|
||
@ВПодсистеме
|
||
метод ЗагрузитьКурсыВалюты(ВалютаСсылка: Валюты.Ссылка, НачалоПериода: Дата, КонецПериода: Дата)
|
||
знч Клиент = КлиентHttp.СБазовымUrl("https://www.cbr.ru/scripts/").СМаксимумомПеренаправлений(0)
|
||
|
||
знч Валюта = ВалютаСсылка.ЗагрузитьОбъект()
|
||
|
||
// Получение идентификатора валюты во внешнем справочнике
|
||
|
||
если Валюта.ВнешнийИдентификатор.Пусто()
|
||
знч ЗапросСправочникаВалют = Клиент.ЗапросGet("XML_valFull.asp")
|
||
попытка
|
||
исп Ответ = ЗапросСправочникаВалют.Выполнить()
|
||
если Ответ.КодСостояния == 200
|
||
знч ЧтениеXml = новый ЧтениеXml(Ответ.Тело, Кодировка = "windows-1251")
|
||
пер ТекущийИд: Строка
|
||
пер ЭтоЭлементКода: Булево
|
||
пока ЧтениеXml.Следующий()
|
||
если ЧтениеXml.ВидУзла == ВидУзлаXml.НачалоЭлемента и ЧтениеXml.Имя == "Item"
|
||
ТекущийИд = ЧтениеXml.ЗначениеАтрибутаПоИндексу(0)
|
||
;
|
||
если ЭтоЭлементКода и ЧтениеXml.ВидУзла == ВидУзлаXml.Текст и Валюта.Код == ЧтениеXml.Значение
|
||
Валюта.ВнешнийИдентификатор = ТекущийИд
|
||
прервать
|
||
;
|
||
ЭтоЭлементКода = ЧтениеXml.ВидУзла == ВидУзлаXml.НачалоЭлемента и ЧтениеXml.Имя == "ISO_Char_Code"
|
||
;
|
||
иначе
|
||
выбросить новый ИсключениеЗагрузкиКурсовВалют(
|
||
"Ошибка при получении внешнего справочника валют. Код %{Ответ.КодСостояния}",
|
||
ВалютаСсылка)
|
||
;
|
||
поймать Искл: ИсключениеHttp
|
||
выбросить новый ИсключениеЗагрузкиКурсовВалют("Ошибка при выполнении запроса к сервису курсов валют", ВалютаСсылка, Искл)
|
||
поймать Искл: ИсключениеЧтенияXml
|
||
выбросить новый ИсключениеЗагрузкиКурсовВалют("Ошибка при чтении внешнего справочника валют", ВалютаСсылка, Искл)
|
||
;
|
||
|
||
если не Валюта.ВнешнийИдентификатор.Пусто()
|
||
исп КонтекстДоступа.Дополнить(Тип<Валюты.Объект>, [Сущность.Право.Изменение])
|
||
Валюта.Записать()
|
||
иначе
|
||
выбросить новый ИсключениеЗагрузкиКурсовВалют("Во внешнем справочнике не удалось найти валюту с кодом %{Валюта.Код}", ВалютаСсылка)
|
||
;
|
||
;
|
||
|
||
// Загрузка курсов валюты
|
||
|
||
знч Url = "XML_dynamic.asp?date_req1=${НачалоПериода|дд/ММ/гггг}&date_req2=${КонецПериода|дд/ММ/гггг}&VAL_NM_RQ=%{Валюта.ВнешнийИдентификатор}"
|
||
знч ЗапросКурсов = Клиент.ЗапросGet(Url)
|
||
|
||
пер КурсыВалюты = <КурсВалюты>[]
|
||
попытка
|
||
исп Ответ = ЗапросКурсов.Выполнить()
|
||
если Ответ.КодСостояния == 200
|
||
знч ЧтениеXml = новый ЧтениеXml(Ответ.Тело, Кодировка = "windows-1251")
|
||
|
||
пер ДатаКурса: Дата?
|
||
пер Кратность: Число
|
||
|
||
пер ЭтоЭлементКурса: Булево
|
||
пер ЭтоЭлементКратности: Булево
|
||
|
||
пока ЧтениеXml.Следующий()
|
||
если ЧтениеXml.ВидУзла == ВидУзлаXml.НачалоЭлемента и ЧтениеXml.Имя == "Record"
|
||
ДатаКурса = новый Дата(ЧтениеXml.ЗначениеАтрибутаПоИндексу(0))
|
||
;
|
||
если ЭтоЭлементКратности и ЧтениеXml.ВидУзла == ВидУзлаXml.Текст
|
||
Кратность = новый Число(ЧтениеXml.Значение)
|
||
;
|
||
если ЭтоЭлементКурса и ЧтениеXml.ВидУзла == ВидУзлаXml.Текст
|
||
знч Курс = новый Число(ЧтениеXml.Значение.Заменить(",","."))
|
||
|
||
знч КурсВалюты = новый КурсВалюты(
|
||
Валюта = ВалютаСсылка,
|
||
Период = ДатаКурса,
|
||
Курс = Курс,
|
||
Кратность = Кратность
|
||
)
|
||
|
||
КурсыВалюты.Добавить(КурсВалюты)
|
||
;
|
||
ЭтоЭлементКурса = ЧтениеXml.ВидУзла == ВидУзлаXml.НачалоЭлемента и ЧтениеXml.Имя == "Value"
|
||
ЭтоЭлементКратности = ЧтениеXml.ВидУзла == ВидУзлаXml.НачалоЭлемента и ЧтениеXml.Имя == "Nominal"
|
||
;
|
||
иначе
|
||
выбросить новый ИсключениеЗагрузкиКурсовВалют("Ошибка при получении курсов валют. Код %{Ответ.КодСостояния}", ВалютаСсылка)
|
||
;
|
||
поймать Искл: ИсключениеHttp
|
||
выбросить новый ИсключениеЗагрузкиКурсовВалют("Ошибка при выполнении запроса к сервису курсов валют", ВалютаСсылка, Искл)
|
||
поймать Искл: ИсключениеЧтенияXml
|
||
выбросить новый ИсключениеЗагрузкиКурсовВалют("Ошибка при чтении курсов валют", ВалютаСсылка, Искл)
|
||
;
|
||
|
||
// Запись полученных данных в регистр сведений
|
||
|
||
если не КурсыВалюты.Пусто()
|
||
для КурсВалюты из КурсыВалюты
|
||
знч НоваяЗапись = новый КурсыВалют.Запись(
|
||
Период = КурсВалюты.Период,
|
||
Валюта = ВалютаСсылка,
|
||
Курс = КурсВалюты.Курс,
|
||
Кратность = КурсВалюты.Кратность
|
||
)
|
||
|
||
КурсыВалют.Записать(НоваяЗапись)
|
||
;
|
||
;
|
||
;
|
||
|
||
@ВПроекте
|
||
метод ЗапланироватьЗагрузкуКурсовВалют()
|
||
ЗапланированныеЗадания.Создать(&КурсыВалютСервер.ЗагрузитьКурсыВалют)
|
||
.Настроить(Ключ = КЛЮЧ_ЗАДАНИЯ_ЗАГРУЗКИ_КУРСОВ,
|
||
СтратегияПубликации = СтратегияПубликацииЗадания.Отбросить,
|
||
Расписание = Расписание.Ежедневно(ЗапуститьВ = Время{12:00}, ИсполнятьПропущенное = Истина),
|
||
Описание = "Загрузка курсов валют")
|
||
.ЗапланироватьБезТранзакции()
|
||
;
|
||
|
||
@ВПодсистеме
|
||
метод ПриостановитьЗагрузкуКурсовВалют()
|
||
ЗапланированныеЗадания.Приостановить(КЛЮЧ_ЗАДАНИЯ_ЗАГРУЗКИ_КУРСОВ)
|
||
;
|
||
|
||
@ВПодсистеме
|
||
метод ВозобновитьЗагрузкуКурсовВалют()
|
||
если ЗапланированныеЗадания.Возобновить(КЛЮЧ_ЗАДАНИЯ_ЗАГРУЗКИ_КУРСОВ) == Неопределено
|
||
ЗапланироватьЗагрузкуКурсовВалют()
|
||
;
|
||
;
|
||
|
||
@ВПодсистеме
|
||
метод ЗагрузкаКурсовВалютЗапланирована(): Булево
|
||
знч Дескриптор = ЗапланированныеЗадания.ПолучитьПоКлючу(КЛЮЧ_ЗАДАНИЯ_ЗАГРУЗКИ_КУРСОВ)
|
||
если Дескриптор != Неопределено
|
||
возврат Дескриптор.Статус == СтатусЗадания.Ожидает или Дескриптор.Статус == СтатусЗадания.Выполняется
|
||
иначе
|
||
возврат Ложь
|
||
;
|
||
; |