В данном примере мы рассмотрим ситуацию, когда в одном прикладном решении существуют заказы товаров, а в другом прикладном решении на основании этих заказов, не дожидаясь сеанса обмена данными, должны быть созданы расходные накладные. При этом нормативно-справочная информация у этих решений общая.
Для этого в прикладном решении поставщика Web-сервиса нам нужно разработать Web-сервис, который будет получать незакрытые заказы товаров и возвращать всю информацию о таких заказах. И затем опубликовать этот сервис на веб-сервере. А в прикладном решении потребителя Web-сервиса нам нужно реализовать функциональность (например, команду), при выполнении которой на основании полученных от Web-сервиса заказов будут сформированы соответствующие документы продаж.
Итак, приступим.
Сначала для описания типов параметров и возвращаемых значений Web-сервиса в ветке Общие > XDTO-пакеты добавим пакет XDTO ДанныеПередачи с пространством имен http://localhost/REST. В свойстве URI пространства имен содержится http://localhost – адрес веб-сервера, установленного на локальном компьютере, /REST – каталог, в который будет опубликован Web-сервис.
Пакет XDTO будет содержать следующие типы объектов XDTO (рис. 1.34):
Рис. 1.34. Структура пакета XDTO «ДанныеПередачи»
Рис. 1.35. Свойства свойства «Состав» типа объекта XDTO «Заказ»
Теперь, когда необходимые типы объектов XDTO созданы, в ветке Общие > Web-сервисы добавим Web-сервис с именем Заказы со следующими свойствами (рис. 1.36):
Рис. 1.36. Свойства Web-сервиса «Заказы»
На закладке Операции в окне свойств Web-сервиса определим операцию ПолучитьНезакрытыеЗаказы со следующими свойствами (рис. 1.37):
Рис. 1.37. Свойства операции «ПолучитьНезакрытыеЗаказы»
Эта операция будет возвращать список всех незакрытых заказов на товары, т. е. тех заказов, у которых признак закрытия еще не установлен и, следовательно, на их основании еще не создавались расходные накладные.
Нажмем на кнопку открытия со значком лупы у свойства Имя процедуры. В результате в модуле Web-сервиса будет создан шаблон функции-обработчика ПолучитьНезакрытыеЗаказы(), которая будет выполняться при его вызове. Заполним эту функцию следующим образом (листинг 1.139).
Листинг 1.139. Функция «ПолучитьНезакрытыеЗаказы()»
Функция ПолучитьНезакрытыеЗаказы()
// Сформировать запрос к списку незакрытых заказов.
Запрос = Новый Запрос;
Запрос.Текст = "ВЫБРАТЬ
| Заказ.Ссылка КАК Ссылка,
| Заказ.Дата КАК Дата,
| Заказ.Клиент КАК Клиент,
| Заказ.Товары.(
| Товар КАК Товар,
| Количество КАК Количество,
| Цена КАК Цена,
| Сумма КАК Сумма
| ) КАК Товары,
| Заказ.Представление КАК ПредставлениеЗаказа
|ИЗ
| Документ.Заказ КАК Заказ
|ГДЕ
| Заказ.Закрыт = ЛОЖЬ
| И Заказ.Проведен = ИСТИНА";
РезультатЗапроса = Запрос.Выполнить();
Если РезультатЗапроса.Пустой() Тогда
Возврат Неопределено;
КонецЕсли;
Выборка = РезультатЗапроса.Выбрать();
// Получить типы объектов XDTO.
ТоварТип = ФабрикаXDTO.Тип("http://localhost/REST", "Товар");
КлиентТип = ФабрикаXDTO.Тип("http://localhost/REST", "Клиент");
СтрокаЗаказаТип = ФабрикаXDTO.Тип("http://localhost/REST", "СтрокаЗаказа");
ЗаказТип = ФабрикаXDTO.Тип("http://localhost/REST", "Заказ");
ЗаказыТип = ФабрикаXDTO.Тип("http://localhost/REST", "Заказы");
// Создать объект XDTO список заказов.
Заказы = ФабрикаXDTO.Создать(ЗаказыТип);
// В цикле обхода выборки получить список и содержимое незакрытых заказов.
Пока Выборка.Следующий() Цикл
// Создать объект XDTО Заказ и Клиент.
Заказ = ФабрикаXDTO.Создать(ЗаказТип);
Клиент = ФабрикаXDTO.Создать(КлиентТип);
// Заполнить свойства клиента и заказа.
Клиент.Наименование = Выборка.Клиент.Наименование;
Заказ.Клиент = Клиент;
Заказ.Дата = Выборка.Дата;
Заказ.Представление = Выборка.ПредставлениеЗаказа;
ВыборкаСостав = Выборка.Товары.Выбрать();
// В цикле обхода состава выборки получить состав заказа
Пока ВыборкаСостав.Следующий() Цикл
// Создать объекты XDTO строки заказа и товара.
СтрокаЗаказа = ФабрикаXDTO.Создать(СтрокаЗаказаТип);
Товар = ФабрикаXDTO.Создать(ТоварТип);
// Заполнить свойства товара и строки заказа.
Товар.Наименование = ВыборкаСостав.Товар.Наименование;
СтрокаЗаказа.Товар = Товар;
СтрокаЗаказа.Цена = ВыборкаСостав.Цена;
СтрокаЗаказа.Количество = ВыборкаСостав.Количество;
СтрокаЗаказа.Сумма = ВыборкаСостав.Сумма;
// Добавить строку заказа.
Заказ.Состав.Добавить(СтрокаЗаказа);
КонецЦикла;
// Добавить заказ в список заказов.
Заказы.Список.Добавить(Заказ);
// Закрыть заказ.
Документ = Выборка.Ссылка.ПолучитьОбъект();
Документ.Закрыт = Истина;
Документ.Записать();
КонецЦикла;
Возврат Заказы;
КонецФункции
Прокомментируем код функции.
Сначала мы выполняем запрос, получающий информацию обо всех незакрытых заказах.
После этого с помощью глобальной фабрики XDTO получаем типы объектов XDTO, ранее описанные нами в пакете XDTO ДанныеПередачи: ТоварТип, КлиентТип, СтрокаЗаказаТип, ЗаказТип и ЗаказыТип. На основе последнего типа мы создаем объект XDTO Заказы.
В цикле обхода выборки из результата запроса мы создаем объект XDTO Клиент, заполняем его наименование и объект XDTO Заказ и заполняем его свойства: Клиент, Представление и Дата.
Затем мы обходим табличную часть заказа Товары. В цикле обхода выборки состава заказа мы создаем объект XDTO Товар, заполняем его наименование и объект XDTO СтрокаЗаказа и заполняем его свойства: Товар, Количество, Цена и Сумма. После этого объект СтрокаЗаказа добавляем в список значений XDTO Заказ – Заказ.Состав.Добавить(СтрокаЗаказа).
А при завершении цикла обхода родительской выборки объект Заказ добавляем в список значений XDTO Заказы – Заказы.Список.Добавить(Заказ).
После этого от ссылки на заказ получается объект, признак заказа Закрыт устанавливается в Истина, заказ записывается. И, таким образом, заказ закрывается – следовательно, при следующем вызове Web-сервиса на основании этого заказа уже не будет создаваться расходная накладная.
В заключение функция возвращает объект XDTO Заказы. Тип этого объекта был описан в свойстве Тип возвращаемого значения операции ПолучитьНезакрытыеЗаказы созданного нами Web-сервиса Заказы.
Теперь осталось только опубликовать созданный Web-сервис на веб-сервере – например, расположенном на локальном компьютере http://localhost в каталоге /REST. Для этого в диалоге публикации информационной базы на веб-сервере на закладке Web-сервисы установим флажок Публиковать Web-сервисы по умолчанию и флажок Публиковать Web-сервисы и отметим имеющиеся Web-сервисы, к которым мы хотим предоставить доступ из внешних систем (рис. 1.38).
Рис. 1.38. Диалог публикации на веб-сервере
Теперь посмотрим, как используется функциональность, предоставляемая Web-сервисом Заказы, в прикладном решении «1С:Предприятия».
Например, при нажатии кнопки Закрыть заказы в форме демонстрационной обработки вызывается серверная процедура ЗакрытьЗаказыНаСервере() (листинг 1.140).
Листинг 1.140. Функция «ЗакрытьЗаказыНаСервере()»
&НаСервереБезКонтекста
Процедура ЗакрытьЗаказыНаСервере()
// Создать WS-прокси на основании WS-ссылки.
Прокси = WSСсылки.ДанныеЗаказов.СоздатьWSПрокси("http://localhost/REST", "Заказы", "ЗаказыSoap");
// Выполнить операцию Веб-сервиса Заказы.
СписокЗаказов = Прокси.ПолучитьНезакрытыеЗаказы();
Если СписокЗаказов = Неопределено Тогда
Возврат;
КонецЕсли;
Для Каждого Заказ Из СписокЗаказов.Список Цикл
// Создать расходную накладную на основании заказа.
ДокументОбъект = Документы.РасходнаяНакладная.СоздатьДокумент();
ДокументОбъект.Дата = Заказ.Дата;
// Найти клиента по наименованию.
ДокументОбъект.Клиент = Справочники.Клиенты.НайтиПоНаименованию(Заказ.Клиент.Наименование);
ДокументОбъект.Основание = Заказ.Представление;
// Заполнить ТЧ расходной накладной данными заказа.
Для Каждого СтрокаСостава Из Заказ.Состав Цикл
НоваяСтрока = ДокументОбъект.Товары.Добавить();
НоваяСтрока.Количество = СтрокаСостава.Количество;
НоваяСтрока.Цена = СтрокаСостава.Цена;
НоваяСтрока.Сумма = СтрокаСостава.Сумма;
// Найти товар по наименованию.
НоваяСтрока.Товар = Справочники.Товары.НайтиПоНаименованию(СтрокаСостава.Товар.Наименование);
КонецЦикла;
ДокументОбъект.Записать(, РежимПроведенияДокумента.Неоперативный);
КонецЦикла;
КонецПроцедуры
В данной процедуре используется статическая ссылка на Web-сервис. Для этого в дерево объектов конфигурации в ветку Общие > WS-ссылки мы добавили объект WSСсылка с именем ДанныеЗаказов, ссылающийся на опубликованный Web-сервис. При создании ссылки мы выполнили импорт WSDL-описания Web-сервиса, указав в качестве URL http://localhost/REST/ws/wsorders.1cws?wsdl (рис. 1.39).
Рис. 1.39. Создание статической WS-ссылки
На основе статической ссылки на Web-сервис создается объект WSПрокси, с помощью которого выполняется операция Web-сервиса ПолучитьНезакрытыеЗаказы().
В результате список незакрытых заказов возвращается Web-сервисом в виде списка XDTO в переменную СписокЗаказов.
Далее в цикле обхода этого списка (СписокЗаказов.Список) на основании каждого заказа создается расходная накладная, и ее реквизиты: Дата, Клиент, Основание, а также табличная часть Товары заполняются данными заказа (рис. 1.40, 1.41).
Рис. 1.40. Заказы товаров и соответствующие им расходные накладные
Рис. 1.41. Заказы товаров и соответствующие им расходные накладные
Таким образом, в прикладном решении потребителя Web-сервиса появятся расходные накладные, соответствующие заказам товаров, которые существуют у поставщика этого Web-сервиса.