Всем привет.
Есть одна не большая задача. Я нашёл один путь её решения, но возможно такую же задачу кто-то решал и нашёл другой путь.
Итак, у нас есть несколько сайтов, возвращающих рублёвый курс валюты:
юань - XXX.XXX.XXX.XXX:8081
евро - XXX.XXX.XXX.XXX:8082
доллар - XXX.XXX.XXX.XXX:8083
У каждого сайт есть описанный WSDL с одинаковой функцией getCurrency. Все эти сайты не "наши" и попросить "их" сделать как-то по другому - нельзя. Один раз в сутки, карета превращается в тыкву и меняет свой адрес на YYY.YYY.YYY.YYY и каждый раз этот ip новый.
Сама задача - хочется автоматически в серверном режиме менять настройки данных адресов.
Для начала создадим описание наших WSDL:
Нам присылают текстовый файл, с текущими IP, обходим его в цикле и создаём ServiceReference вот такими строчками:
X++:
SysReference::createServiceReference('CurrencyU', 'XXX.XXX.XXX.XXX:8081?WSDL', 'CurrencyU', 'юань');
SysReference::createServiceReference('CurrencyE', 'XXX.XXX.XXX.XXX:8082?WSDL', 'CurrencyE', 'евро');
SysReference::createServiceReference('CurrencyD', 'XXX.XXX.XXX.XXX:8083?WSDL', 'CurrencyD', 'доллар');
В результате, в AOT в разделе References, появятся следующие объекты: CurrencyU, CurrencyE, CurrencyD.
Теперь мы сможем к ним обратиться таким кодом:
X++:
CurrencyU.AxCurrencyTypeClient webService = new CurrencyU.AxCurrencyTypeClient("AxCurrencySoap");
currentCurrency = webService.getCurrency();
Всё отлично, текущий курс получили. Теперь мы хотим это дело как-то автоматизировать. Если написать вот такой код в job:
X++:
string command = '%1 webService = %1("AxCurrencySoap");';
currentCurrency = webService.getCurrency();
runBuf(command, 'CurrencyU.AxCurrencyTypeClient');
То она работает, всё замечательно. Но, как мы знаем, job выполняется на клиенте, если же поместить это на сервер, то получим ошибку: Unable to compile. Круто, интересно почему. Пихаем наш код в xppCompiler и видим ошибку: У таблицы не существует поля. Строчку не пишет, но однозначно ругается на CurrencyU.AxCurrencyTypeClient, даже если его записать жёстко. Вот тут и наступает беда - нам нужно работать в серверном режиме, а тут такой облом и беда вся в том, что объект составной. В других случаях всё работает.
В результате написал код, который в X++ изменяет метод возврата объектов, т.е. есть класс Currency, и у него есть метод getReference, который генерируется автоматически, по приблизительно следующему коду:
X++:
classBuild = new ClassBuild(classStr(Currency), true);
getServiceReference =
'// Внимание! Данный метод генерируется автоматически Currency::buildReferences()' + '\n' +
'public static server object getServiceReference(str _referenceName)' + '\n' +
'{' + '\n' +
' Object object;' + '\n' +
' ;' + '\n';
while select currencies
{
getServiceReference +=
' case "' + currencies.ServiceReferenceName +'" :' + '\n' +
' object = new ' + currencies.ServiceReferenceName + '.AxCurrencyPortTypeClient("AxCurrencySoap");' + '\n' +
' break;' + '\n';
}
getServiceReference +=
' }' + '\n';
}
getServiceReference +=
' return object;' + '\n' +
'}';
classBuild.overrideMethod('getServiceReference', getServiceReference);
Собственно вопрос -
есть еще какие-нибудь способы обойти данную ошибку в серверной версии? Я думаю что это баг, т.к. в клиентском режиме он нормально проглатывает весь код.
P.S. Это только общий смысл и код приведён лишь частично.