Element_Test_V2/Koncept/Testovoe/Общие/КурсыВалют/КурсыВалютСервер.xbsl
Vladislav_k0ncept f16c003f46 Initial commit
2025-02-20 15:05:58 +00:00

315 lines
19 KiB
Plaintext
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

конст КЛЮЧ_ЗАДАНИЯ_ЗАГРУЗКИ_КУРСОВ = "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}, ИсполнятьПропущенное = Истина),
Описание = "Загрузка курсов валют")
.ЗапланироватьБезТранзакции()
;
@ВПодсистеме
метод ПриостановитьЗагрузкуКурсовВалют()
ЗапланированныеЗадания.Приостановить(КЛЮЧ_ЗАДАНИЯ_ЗАГРУЗКИ_КУРСОВ)
;
@ВПодсистеме
метод ВозобновитьЗагрузкуКурсовВалют()
если ЗапланированныеЗадания.Возобновить(КЛЮЧ_ЗАДАНИЯ_ЗАГРУЗКИ_КУРСОВ) == Неопределено
ЗапланироватьЗагрузкуКурсовВалют()
;
;
@ВПодсистеме
метод ЗагрузкаКурсовВалютЗапланирована(): Булево
знч Дескриптор = ЗапланированныеЗадания.ПолучитьПоКлючу(КЛЮЧ_ЗАДАНИЯ_ЗАГРУЗКИ_КУРСОВ)
если Дескриптор != Неопределено
возврат Дескриптор.Статус == СтатусЗадания.Ожидает или Дескриптор.Статус == СтатусЗадания.Выполняется
иначе
возврат Ложь
;
;