Интеграция УАТ с топливными сервисами

Публикация № 1226815

Разработка - Системная интеграция - Интеграция с WEB

УАТ Интеграция Лукойл Веб-сервисы

Интеграция конфигурации Управление автотранспортом с топливными веб-сервисами.

Всем привет! В прошлой статье я описывал основные возможности топливного веб-сервиса Лукойл ЛИКАРД. В этой, на примере конфигурации Управление автотранспортом Проф, редакция 2.2 (2.2.2.1), покажу, как можно использовать полученные данные, для автоматического создания документов заправок и сливок, автоматического сопоставления путевым листам, созданных документов, исходя из информации топливной системы, тем самым обеспечив саму простую синхронизацию с топливным веб-сервисом, исключив ручную работу и человеческий фактор при создании документов, обеспечив 100% актуальную информацию в отчетах по расходу топлива.

Будем рассматривать пример интеграции с сервисом Лукойл ЛИКАРД, но статья универсальна и подойдет для любого другого сервиса, отличаться будет только часть с получением массива данных с сервиса, далее обработку данных можно без проблем подогнать под любой сервис.

Начнем.

Создаем внешнюю обработку, создаем для нее форму, в реквизиты объекта, будем добавлять все, что необходимо для получения данных сайта и для определения параметров синхронизации. В моем примере, я добавил следующие реквизиты:

  • ИдентификаторДоговораЛукойл – Тип Строка
  • ПутьКФайлуSSLСертификата – Тип Строка
  • ПарольSSLСертификата – Тип Строка
  • ГлубинаПоискаПЛДоВыездаЛукойл – Тип число
  • ГлубинаПоискаПЛПослеВозвращения – тип число
  • ПроводитьСозданныеЗаправкиГСМЛукойл – тип булево
  • ПересчитатьПутевыеЛистыЛукойл – Булево
  • АЗС – тип СправочникСсылка.уатАЗС

Добавляем все реквизиты на формы, и добавляем команду “Синхронизировать” к которой привязываем процедуру Синхронизировать()

Привожу код модуля формы:


&НаСервере
Процедура СинхронизироватьНаСервере()
	
	УстановитьПривилегированныйРежим(Истина);
	
	Попытка
		// получаем массив с данными веб-сервиса, эта процедура будет немного отличаться для каждого веб-сервсиса, далее все универсально	
		МассивРезультатЗапроса = ПолучитьМассивСРезультатомЗапросаНаСайт();
		Если ЗначениеЗаполнено(МассивРезультатЗапроса) Тогда
			// обрабатываем полученные даные, здесь будем создавать документы заправок и сливов
			ОбработатьРезультатЗапросаНаСайт(МассивРезультатЗапроса);
			// здесь будем сопоставлять созданные заправки и сливы с имеющимися путевыми листами
			ПересопоставитьГСМ();
		КонецЕсли;
		
	Исключение;
		Сообщить(ОписаниеОшибки());
	КонецПопытки;
	
	УстановитьПривилегированныйРежим(Ложь);
	
КонецПроцедуры

&НаКлиенте
Процедура Синхронизировать(Команда)
	СинхронизироватьНаСервере();
КонецПроцедуры

&НаСервере
Функция ПолучитьМассивСРезультатомЗапросаНаСайт()
// подробнее о том, откуда получаются данные в этой функции, можно почитать в прошлой моей статье	
	ЗаписьJSON = Новый ЗаписьJSON;
	ДатаНачала = НачалоДня(Объект.НачалоПериода);
	ДатаКонец = КонецДня(Объект.КонецПериода);
	ИдентификаторДоговора = Объект.ИдентификаторДоговораЛукойл;
	ПутьКФайлуSSLСертификата = Объект.ПутьКФайлуSSLСертификата; 
	ПарольSSLСертификата = Объект.ПарольSSLСертификата;
	
	СтруктураПараметров = Новый Структура;
	СтруктураПараметров.Вставить("contractId", ИдентификаторДоговора);
	СтруктураПараметров.Вставить("dateFrom", ДатаНачала);
	СтруктураПараметров.Вставить("dateTo", ДатаКонец);
	СтруктураПараметров.Вставить("reportMode", "");
	СтруктураПараметров.Вставить("cardNumberIn", "");
	СтруктураПараметров.Вставить("vehicleNumberIn", "");
	СтруктураПараметров.Вставить("cityIn", "");
	СтруктураПараметров.Вставить("transMatterIn", "");
	СтруктураПараметров.Вставить("countryCodeIn", "");
	СтруктураПараметров.Вставить("regionIdIn", "");
	СтруктураПараметров.Вставить("operationTypeId", 35271);
	СтруктураПараметров.Вставить("goodsGroupCodeIn", "");
	СтруктураПараметров.Вставить("minQuantity", "");
	СтруктураПараметров.Вставить("maxQuantity", "");
	СтруктураПараметров.Вставить("maxRowsThreshold", "");
	
	ЗаписьJSON.УстановитьСтроку();
	ЗаписатьJSON(ЗаписьJSON, СтруктураПараметров);
	ТекстПараметровJSON = ЗаписьJSON.Закрыть();
		
	Сервер = "11.111.11.11";
	
	ssl = Новый ЗащищенноеСоединениеOpenSSL(Новый СертификатКлиентаФайл(ПутьКФайлуSSLСертификата, ПарольSSLСертификата)); 
	Попытка			
		HTTPСоединение =  Новый HTTPСоединение(Сервер, 443 ,,,,30, ssl); 
	Исключение
		Сообщить(ОписаниеОшибки());
		Возврат
	КонецПопытки;
	
	Заголовки = Новый Соответствие;
	Заголовки.Вставить("Content-Type", "application/json;charset=utf-8");
	
	HTTPЗапрос = Новый HTTPЗапрос("/solar-bridge-ext/ext/json-services/getContractTransactions", Заголовки);

	HTTPЗапрос.УстановитьТелоИзСтроки(ТекстПараметровJSON, КодировкаТекста.UTF8, ИспользованиеByteOrderMark.НеИспользовать);

	HTTPОтвет = HTTPСоединение.ОтправитьДляОбработки(HTTPЗапрос);
	
	МассивРезультатЗапроса = Новый Массив;
		
	Попытка
		ЧтениеJSON = Новый ЧтениеJSON;
		ЧтениеJSON.УстановитьСтроку(HTTPОтвет.ПолучитьТелоКакСтроку());
		СтруктураJSON = ПрочитатьJSON(ЧтениеJSON);
		ЧтениеJSON.Закрыть();
		МассивРезультатЗапроса = СтруктураJSON.getContractTransactionsRs.getContractTransactionsPayload.contractTransactions;
	Исключение
		флгРезультатЧтенияФайла = Ложь;
	КонецПопытки;		
	
	Возврат МассивРезультатЗапроса;
	
КонецФункции



//Процедура обрабатывает полуенный результат сайта
Процедура ОбработатьРезультатЗапросаНаСайт(мсвРезультатЗапроса) Экспорт
	Перем мДокументЗаправкаСлив, СтавкаНДС, СуммаНДС, СуммаВключаетНДС, УчитыватьНДС; 
	
	ГлубинаПоискаПЛДоВыезда = Объект.ГлубинаПоискаПЛДоВыездаЛукойл;	
	ГлубинаПоискаПЛПослеВозвращения = Объект.ГлубинаПоискаПЛПослеВозвращенияЛукойл;
	ПроводитьСозданныеЗаправкиГСМ = Объект.ПроводитьСозданныеЗаправкиГСМЛукойл;
	ПересчитатьПутевыеЛисты = Объект.ПересчитатьПутевыеЛистыЛукойл;
	АЗС = Объект.АЗСЛукойл;


	Индекс             = 0;
	мсвВыборкаЗаправки = Новый Массив();
	мсвВыборкаСливы    = Новый Массив();
	
	тзТопливныеКарты = ПолучитьТопливныеКарты();
	Если НЕ ЗначениеЗаполнено(тзТопливныеКарты) Тогда
		Сообщить("Ошибка", "Топливные карты не найдены в базе");
		Возврат;
	КонецЕсли;
	
	тзТопливныеКартыМенеджеров = ПолучитьТопливныеКарты("Сотрудники");
	
	Для Инд = 0 по мсвРезультатЗапроса.Количество() - 1 Цикл
		эл = мсвРезультатЗапроса[Инд];
		СтруктураСтроки = Новый Структура();			
				
		стзПластиковаяКарта = тзТопливныеКарты.Найти(Формат(эл.cardNumberOut, "ЧН=0; ЧГ=0"), "НовыйКод");
		
		Если стзПластиковаяКарта = Неопределено  Тогда
			Сообщить("Ошибка", "Топливная карта не найдена. " + Строка(эл.cardNumberOut));
			Продолжить;
		КонецЕсли;
		
		ПластиковаяКарта = стзПластиковаяКарта.Ссылка;
		Если ПластиковаяКарта.ПометкаУдаления Тогда
			Сообщить("Предупреждение", "Топливная карта помечена на удаление. " + Строка(эл.cardNumberOut));
			Продолжить;				
		КонецЕсли;
		
		СтруктураСтроки.Вставить("ПластиковаяКарта", ПластиковаяКарта);
		СтруктураСтроки.Вставить("ТС",               ПластиковаяКарта.КомуВыдана);
		
		ТС = ПластиковаяКарта.КомуВыдана;
		
		Если ТС.ПометкаУдаления Тогда
			Сообщить("Предупреждение", "ТС помечено на удаление. " + Строка(ТС));
			Продолжить;				
		КонецЕсли;
		
		//Проставляем ГСМ или основное или то, что указанов в соответствии в тч АЗС
		ПараметрыОтбора = Новый Структура;
		ПараметрыОтбора.Вставить("ГСМизФайла", эл.goodsName);
		НайденныеСтроки = АЗС.СоответствиеГСМ.НайтиСтроки(ПараметрыОтбора);
		Если НайденныеСтроки.Количество() > 0 Тогда
			СтруктураСтроки.Вставить("ГСМ", НайденныеСтроки[0].ГСМ);					
		Иначе
			СтруктураСтроки.Вставить("ГСМ", ТС.Модель.ОсновноеТопливо);
		КонецЕсли;
		
		
		//Валюта
		Если эл.clientCurrName = "RUR" Тогда
			СтруктураСтроки.Вставить("Валюта", Справочники.Валюты.НайтиПоКоду("643"));				
		КонецЕсли;
		
		СтруктураСтроки.Вставить("Количество",       Число(эл.quantity));
		СтруктураСтроки.Вставить("Стоимость",        эл.sourceAmount);
		
		стрДата = эл.transDate;
		Год_ = Лев(стрДата, 4);
		Месяц_ = Сред(стрДата, 6, 2);
		День_ = Сред(стрДата, 9, 2);
		Час_ = Сред(стрДата, 12, 2);
		Минута_ = Сред(стрДата, 15, 2);
		Секунда_ = Прав(стрДата, 2);
		
		СтруктураСтроки.Вставить("Период",           Дата(Год_, Месяц_, День_, Час_, Минута_, Секунда_));
		
		СтруктураСтроки.Вставить("СтавкаНДС",        СтавкаНДС);
		СтруктураСтроки.Вставить("СуммаНДС",         СуммаНДС);
		СтруктураСтроки.Вставить("УчитыватьНДС",     УчитыватьНДС);
		СтруктураСтроки.Вставить("СуммаВключаетНДС", СуммаВключаетНДС);
		СтруктураСтроки.Вставить("КоличествоСлив",   0);
		СтруктураСтроки.Вставить("НомерТранзакции",  эл.transId);
		
		Если СтруктураСтроки.Количество > 0 Тогда
			мсвВыборкаЗаправки.Добавить(СтруктураСтроки);
		Иначе
			Если СоздаватьСливыДляОтрицательныхЗаправок Тогда
				СтруктураСтроки.Вставить("КоличествоСлив", СтруктураСтроки.Количество);
				мсвВыборкаСливы.Добавить(СтруктураСтроки);
			КонецЕсли;
		КонецЕсли;
		
	КонецЦикла;
	СписокПЛ = Новый СписокЗначений;
	
	ТекОтветственный = уатОбщегоНазначенияПовтИсп.ПолучитьЗначениеПоУмолчаниюПользователя(Пользователи.АвторизованныйПользователь(), "ОсновнойОтветственный");
	
	КолСтрок	 = мсвВыборкаЗаправки.Количество();
	Инд			 = 0;
	Дата1		 = '00010101';
	флЗаписать	 = Ложь;
	мОтказ		 = Ложь;
	ВидОперацииСливГСМ		 = ?(АЗС.ЭтоАЗССклад, Перечисления.уатВидыОперацийСливГСМ.НаСклад, Перечисления.уатВидыОперацийСливГСМ.НаАЗС);
	ВидОперацииЗаправкаГСМ	 = ?(АЗС.ЭтоАЗССклад, Перечисления.уатВидыДвиженияГСМ.ЗаправкаПластиковаяКартаСклад, Перечисления.уатВидыДвиженияГСМ.ЗаправкаПластиковаяКарта);
	флгЕстьПутевойЛист = Ложь;
	
	Для Каждого ВыборкаЗапроса Из мсвВыборкаЗаправки Цикл
		Инд = Инд + 1;
		
		Если уатОбщегоНазначения.уатЗначениеНеЗаполнено(ВыборкаЗапроса.ТС) Тогда
			Продолжить;
		КонецЕсли;	
		
		Если Дата1 <> ВыборкаЗапроса.Период Тогда
			
			Дата1 = ВыборкаЗапроса.Период;
			
			мДокументЗаправкаСлив = Документы.уатЗаправкаГСМ.СоздатьДокумент();
			мДокументЗаправкаСлив.УчитыватьНДС = ВыборкаЗапроса.УчитыватьНДС;
			мДокументЗаправкаСлив.СуммаВключаетНДС = ВыборкаЗапроса.СуммаВключаетНДС;
			
			мДокументЗаправкаСлив.ВидДвиженияГСМ = ВидОперацииЗаправкаГСМ;
			Если ТипЗнч(АЗС.Контрагент_Склад) = Тип("СправочникСсылка.Контрагенты") Тогда
				мДокументЗаправкаСлив.ДоговорКонтрагента = уатЗаполнениеДокументов.ПолучитьОсновнойДоговорКонтрагента(АЗС.Контрагент_Склад, "СПоставщиком");
			КонецЕсли;
			
			мДокументЗаправкаСлив.Дата			 = Дата1;
			мДокументЗаправкаСлив.АЗС			 = АЗС;
			мДокументЗаправкаСлив.Ответственный	 = ТекОтветственный;
			
			флЗаписать = Истина;
			
		КонецЕсли;
		
		НоваяСтрока = мДокументЗаправкаСлив.Заправки.Добавить();
		НоваяСтрока.Дата		 = Дата1;
		НоваяСтрока.ГСМ			 = ВыборкаЗапроса.ГСМ;
		НоваяСтрока.ТС			 = ВыборкаЗапроса.ТС;
		НоваяСтрока.Цена		 = ВыборкаЗапроса.Стоимость / ?(ВыборкаЗапроса.Количество = 0, 1, ВыборкаЗапроса.Количество);
		НоваяСтрока.Количество	 = ВыборкаЗапроса.Количество + ВыборкаЗапроса.КоличествоСлив;
		НоваяСтрока.Сумма		 = ?(ЗначениеЗаполнено(ВыборкаЗапроса.КоличествоСлив) , НоваяСтрока.Количество * НоваяСтрока.Цена, ВыборкаЗапроса.Стоимость);
		
		НоваяСтрока.СтавкаНДС = ВыборкаЗапроса.СтавкаНДС;
		НоваяСтрока.СуммаНДС  = ?(ЗначениеЗаполнено(ВыборкаЗапроса.КоличествоСлив), уатОбщегоНазначенияТиповые.уатРассчитатьСуммуНДС(НоваяСтрока.Сумма,
		мДокументЗаправкаСлив.УчитыватьНДС, мДокументЗаправкаСлив.СуммаВключаетНДС,
		уатОбщегоНазначенияТиповые.уатПолучитьСтавкуНДС(НоваяСтрока.СтавкаНДС)), ВыборкаЗапроса.СуммаНДС);
		
		
		Если ВыборкаЗапроса.УчитыватьНДС = Истина И ВыборкаЗапроса.СуммаВключаетНДС = Ложь Тогда
			НоваяСтрока.Сумма = НоваяСтрока.Сумма - ВыборкаЗапроса.СуммаНДС;
		Иначе
			НоваяСтрока.Сумма = НоваяСтрока.Сумма;
		КонецЕсли;
		
		НоваяСтрока.Валюта				 = ВыборкаЗапроса.Валюта;
		НоваяСтрока.ПластиковаяКарта	 = ВыборкаЗапроса.ПластиковаяКарта;
		
		//находим путевой лист, глубина поиск ПЛ в часах
		ВремяВыезд      = ГлубинаПоискаПЛДоВыезда;
		ВремяВозврат    = ГлубинаПоискаПЛПослеВозвращения;
		
		ТаблицаПЛ = уатОбщегоНазначения.уатПутевыеЛистыВыездВозврат(ВыборкаЗапроса.ТС,Дата1, ВремяВыезд, 
		ВремяВозврат, , ?(ОбрабатыватьРассчитанныеПутевыеЛисты, Неопределено, Ложь));
		
		Если ТаблицаПЛ.Количество() > 0 Тогда
			флгЕстьПутевойЛист = Истина;

			Если СоздаватьСливыДляОтрицательныхЗаправок И ВыборкаЗапроса.Количество < 0 Тогда
				мДокументЗаправкаСлив.ПутевойЛист = ТаблицаПЛ[0].Ссылка;
				Если СписокПЛ.НайтиПоЗначению(мДокументЗаправкаСлив.ПутевойЛист) = Неопределено Тогда
					СписокПЛ.Добавить(мДокументЗаправкаСлив.ПутевойЛист);
				КонецЕсли;
			Иначе
				НоваяСтрока.ПутевойЛист = ТаблицаПЛ[0].Ссылка;
				НоваяСтрока.Водитель = ТаблицаПЛ[0].Ссылка.Водитель1;
				Если СписокПЛ.НайтиПоЗначению(НоваяСтрока.ПутевойЛист) = Неопределено Тогда
					СписокПЛ.Добавить(НоваяСтрока.ПутевойЛист);
				КонецЕсли;
			КонецЕсли; 
		КонецЕсли;                              
				
		Если флЗаписать Тогда
			Попытка
				Если ПроводитьСозданныеЗаправкиГСМ Тогда
					Если флгЕстьПутевойЛист Тогда
						мДокументЗаправкаСлив.Записать(РежимЗаписиДокумента.Проведение);
					КонецЕсли;
				КонецЕсли;
			Исключение
			КонецПопытки;
		КонецЕсли;
		флгЕстьПутевойЛист = Ложь;
	КонецЦикла;
	
	флЗаписать = Ложь;
	
	// Слив ГСМ
	Если СоздаватьСливыДляОтрицательныхЗаправок Тогда
		
		КолСтрок	 = мсвВыборкаСливы.Количество();
		Инд			 = 0;
		Дата1		 = '00010101';
		флЗаписать	 = Ложь;
		мОтказ		 = Ложь;
		
		Для Каждого ВыборкаЗапроса Из мсвВыборкаСливы Цикл
			
			Если уатОбщегоНазначения.уатЗначениеНеЗаполнено(ВыборкаЗапроса.ТС) Тогда
				Продолжить;
			КонецЕсли;	
			
			Дата1 = ВыборкаЗапроса.Период;
			
			мДокументЗаправкаСлив = Документы.уатСливГСМ.СоздатьДокумент();
			мДокументЗаправкаСлив.ВидОперации = ВидОперацииСливГСМ;
			
			мДокументЗаправкаСлив.Дата			 = Дата1;
			мДокументЗаправкаСлив.АЗС			 = АЗС;
			мДокументЗаправкаСлив.Ответственный	 = ТекОтветственный;
			
			флЗаписать = Истина;
			
			мДокументЗаправкаСлив.ГСМ			 = ВыборкаЗапроса.ГСМ;
			мДокументЗаправкаСлив.ТС			 = ВыборкаЗапроса.ТС;
			мДокументЗаправкаСлив.Количество	 = -ВыборкаЗапроса.Количество;
			мДокументЗаправкаСлив.ГСМ			 = ВыборкаЗапроса.ГСМ;
			
			//находим путевой лист
			ВремяВыезд      = ГлубинаПоискаПЛДоВыезда;
			ВремяВозврат    = ГлубинаПоискаПЛПослеВозвращения;
			
			ТаблицаПЛ = уатОбщегоНазначения.уатПутевыеЛистыВыездВозврат(ВыборкаЗапроса.ТС,Дата1, ВремяВыезд, 
			ВремяВозврат, , ?(ОбрабатыватьРассчитанныеПутевыеЛисты, Неопределено, Ложь));
			
			Если ТаблицаПЛ.Количество() > 0 Тогда
				флгЕстьПутевойЛист = Истина;
				мДокументЗаправкаСлив.ПутевойЛист = ТаблицаПЛ[0].Ссылка;
				Если СписокПЛ.НайтиПоЗначению(мДокументЗаправкаСлив.ПутевойЛист) = Неопределено Тогда
					СписокПЛ.Добавить(мДокументЗаправкаСлив.ПутевойЛист);
				КонецЕсли;
			КонецЕсли;

			
			Если флЗаписать Тогда
				Попытка
					Если ПроводитьСозданныеЗаправкиГСМ Тогда
						Если флгЕстьПутевойЛист Тогда
							мДокументЗаправкаСлив.Записать(РежимЗаписиДокумента.Проведение);						
					    КонецЕсли;
					КонецЕсли;
				Исключение
				КонецПопытки;
			КонецЕсли;
			флгЕстьПутевойЛист = Ложь;
		КонецЦикла;
		
	КонецЕсли;
	
	//обновляем информацию по путевым листам
	КолСтрок	 = СписокПЛ.Количество();
	Инд			 = 0;
	
	Для Каждого ТекСтрока Из СписокПЛ Цикл			
		мПутевойЛист	= ТекСтрока.ПолучитьОбъект();
		мЗаголовок = НСтр("ru='Ошибки при расчете итогов работы по путевому листу №'") + мПутевойЛист.Номер + " :";
		Если ПересчитатьПутевыеЛисты Тогда
			мПутевойЛист.ПересчетВыданногоГСМ();
			мПутевойЛист.ПересчетСданногоГСМ();
			мПутевойЛист.РасчетРасходаГСМ(мЗаголовок, мОтказ);
		Иначе
			мПутевойЛист.Рассчитан	= Ложь;
		КонецЕсли;	
		Если мПутевойЛист.Проведен Тогда
			мРежимЗаписи = РежимЗаписиДокумента.Проведение;
		Иначе
			мРежимЗаписи = РежимЗаписиДокумента.Запись;
		КонецЕсли;
		
		Попытка
			мПутевойЛист.Записать(мРежимЗаписи);
		Исключение
		КонецПопытки;
	КонецЦикла;
	
КонецПроцедуры

Функция ПолучитьТопливныеКарты(стрТипСправочника = "уатТС") Экспорт
	Запрос = Новый Запрос;
	тзРезультат = Новый ТаблицаЗначений;
	Запрос.Текст = "ВЫБРАТЬ
	|	уатПластиковыеКарты.Код КАК Код,
	|	уатПластиковыеКарты.Ссылка КАК Ссылка
	|ИЗ
	|	Справочник.уатПластиковыеКарты КАК уатПластиковыеКарты
	|ГДЕ
	|	ТИПЗНАЧЕНИЯ(уатПластиковыеКарты.КомуВыдана) = ТИП(Справочник." + стрТипСправочника + ")
	|	И НЕ уатПластиковыеКарты.ПометкаУдаления";
	РезультатЗапроса = Запрос.Выполнить();
	Если НЕ РезультатЗапроса.Пустой() Тогда
		тзРезультат = РезультатЗапроса.Выгрузить();	
		тзРезультат.Колонки.Добавить("НовыйКод",, "НовыйКод");  
		Для каждого эл из тзРезультат Цикл
			эл.НовыйКод = СокрЛП(эл.Код);			
		КонецЦикла;
	КонецЕсли;
	
	Возврат тзРезультат;
КонецФункции

Процедура ПересопоставитьГСМ()
	
	ПересчитатьПутевыеЛисты = Объект.ПересчитатьПутевыеЛистыЛукойл;
	//
	ВремяВыезд = Объект.ГлубинаПоискаПЛДоВыездаЛукойл;
	ВремяВыезд = ?(ЗначениеЗаполнено(ВремяВыезд), ВремяВыезд, 0);
	//
	ВремяВозврат = Объект.ГлубинаПоискаПЛПослеВозвращенияЛукойл;
	ВремяВозврат = ?(ЗначениеЗаполнено(ВремяВозврат), ВремяВозврат, 0);
	//
	//
	СоздаватьСливыДляОтрицательныхЗаправок = Объект.СоздаватьСливыДляОтрицательныхЗаправокЛукойл;
	//
	
	ДатаНачала = Объект.НачалоПериода;
    ДатаКонец = Объект.КонецПериода;	
	
	Запрос = Новый Запрос;
	Запрос.Текст = 
	"ВЫБРАТЬ
	|	уатЗаправкаГСМЗаправки.Ссылка КАК Ссылка,
	|	уатЗаправкаГСМЗаправки.ТС КАК ТС,
	|	уатЗаправкаГСМЗаправки.Дата КАК Дата
	|ИЗ
	|	Документ.уатЗаправкаГСМ.Заправки КАК уатЗаправкаГСМЗаправки
	|ГДЕ
	|	уатЗаправкаГСМЗаправки.Ссылка.ПометкаУдаления = ЛОЖЬ
	|	И уатЗаправкаГСМЗаправки.ПутевойЛист.Ссылка ЕСТЬ NULL
	|	И уатЗаправкаГСМЗаправки.Дата МЕЖДУ &ДатаНачала И &ДатаКонец
	|
	|ОБЪЕДИНИТЬ
	|
	|ВЫБРАТЬ
	|	уатСливГСМ.Ссылка,
	|	уатСливГСМ.ТС,
	|	уатСливГСМ.Дата
	|ИЗ
	|	Документ.уатСливГСМ КАК уатСливГСМ
	|ГДЕ
	|	уатСливГСМ.ПутевойЛист.Ссылка ЕСТЬ NULL
	|	И уатСливГСМ.ПометкаУдаления = ЛОЖЬ
	|	И уатСливГСМ.Дата МЕЖДУ &ДатаНачала И &ДатаКонец";
	
	Запрос.УстановитьПараметр("ДатаНачала",ДатаНачала);
	Запрос.УстановитьПараметр("ДатаКонец",ДатаКонец);
	
	РезультатЗапроса = Запрос.Выполнить();
	
	Выборка = РезультатЗапроса.Выбрать();
	
	СписокПЛ = Новый Массив();
	
	Пока Выборка.Следующий() Цикл
		
		ТаблицаПЛ = уатОбщегоНазначения.уатПутевыеЛистыВыездВозврат(Выборка.ТС,Выборка.Дата, ВремяВыезд, 
		ВремяВозврат, ,?(ОбрабатыватьРассчитанныеПутевыеЛисты, Неопределено, Ложь));
		
		Если ТаблицаПЛ.Количество() > 0 Тогда
			флгЕстьПутевойЛист = Истина;
			Если ТаблицаПЛ[0].Ссылка.Организация <> Выборка.Ссылка.Организация Тогда
				Сообщить("Предупреждение", "Организации в " + Строка(Выборка.Ссылка) + " и документа " + Строка(ТаблицаПЛ[0].Ссылка) + " не совпадают.");										
			КонецЕсли;
			
			Если ТипЗнч(Выборка.Ссылка) = Тип("ДокументСсылка.уатЗаправкаГСМ") Тогда
				Заправка = Выборка.Ссылка.ПолучитьОбъект();
				НайтиСтроки = Заправка.Заправки.НайтиСтроки(Новый Структура("Дата,ТС",Выборка.Дата,Выборка.ТС)); 
				
				
				Для каждого стр из НайтиСтроки Цикл
					стр.ПутевойЛист = ТаблицаПЛ[0].Ссылка;
					стр.Водитель = ТаблицаПЛ[0].Ссылка.Водитель1;
				КонецЦикла;
				
				Попытка 
					Заправка.Записать(РежимЗаписиДокумента.Проведение);
				Исключение
					Заправка.Записать(РежимЗаписиДокумента.Запись);					
				КонецПопытки;
				
				
			Иначе
				Слив = Выборка.Ссылка.ПолучитьОбъект();
				Слив.ПутевойЛист = ТаблицаПЛ[0].Ссылка;	
				
				Попытка 
					Слив.Записать(РежимЗаписиДокумента.Проведение);
				Исключение
					Слив.Записать(РежимЗаписиДокумента.Запись);
				КонецПопытки;
				
			КонецЕсли;
			Если СписокПЛ.Найти(ТаблицаПЛ[0].Ссылка) = Неопределено Тогда
				СписокПЛ.Добавить(ТаблицаПЛ[0].Ссылка);
			КонецЕсли;
		Иначе
			Сообщить("Предупреждение", "Не найден Путевой лист для " + Строка(Выборка.Ссылка) + ". При сопоставлении");											
		КонецЕсли;	
	КонецЦикла;
	
	Для Каждого ТекСтрока Из СписокПЛ Цикл			
		мПутевойЛист	= ТекСтрока.ПолучитьОбъект();
		мЗаголовок = НСтр("en='Errors in calculation of balance of the work by waybill №';ru='Ошибки при расчете итогов работы по путевому листу №'") + мПутевойЛист.Номер + " :";
		Отказ = Ложь;
		Если ПересчитатьПутевыеЛисты Тогда
			мПутевойЛист.ПересчетВыданногоГСМ();
			мПутевойЛист.ПересчетСданногоГСМ();
			мПутевойЛист.РасчетРасходаГСМ(мЗаголовок,Отказ);
		КонецЕсли;
		
		Если мПутевойЛист.Проведен Тогда
			мРежимЗаписи = РежимЗаписиДокумента.Проведение;
		Иначе
			мРежимЗаписи = РежимЗаписиДокумента.Запись;
		КонецЕсли;
		
		Попытка
			мПутевойЛист.Записать(мРежимЗаписи);
		Исключение
			мПутевойЛист.Записать(РежимЗаписиДокумента.Запись);
		КонецПопытки;
	КонецЦикла;
	
	
	
	
КонецПроцедуры

Таким образом, реализуется самая простая форма синхронизации с топливными сервисами, которую дальше можно доводить до визуальной красоты.

В нашем случаем это простая обработка, где с заполненными параметрами на форме, по кнопке синхронизировать, в УАТ создаются документы заправок и сливок, согласно данным сервиса, и сопопставляются путевым листам.

Специальные предложения

Автор запретил комментарии

См. также

.Net в 1С. На примере использования HTTPClient, AngleSharp. Удобный парсинг сайтов с помощью библиотеки AngleSharp, в том числе с авторизацией аля JQuery с использованием CSS селекторов. Динамическая компиляция Промо

Практика программирования WEB v7.7 v8 Бесплатно (free)

Часто приходится парсить сайты, в том числе с авторизацией, перескакивая со страницы на страницу по ссылкам. Тот, кто занимался вэб программированием, знает, как удобно использовать JQuery и CSS селекторы. На .Net написана очень удобная библиотека AngleSharp. Я покажу, как с её помощью можно значительно облегчить себе труд.

10.03.2016    53626    0    Serginio    33    

История создания успешной системы чат-ботов на 1С

WEB v8 Бесплатно (free)

Использование чат-ботов в мессенджерах позволяет автоматизировать многие сложные бизнес-процессы путем диалога с системой через виртуального собеседника. О том, как создать универсальную систему ботов с бэкендом на 1С, работающую в Telegram, Viber и Facebook Messenger одновременно, на конференции Infostart Event 2019 Inception рассказал программист-фрилансер Константин Гейнрих.

21.05.2020    4110    0    CyberCerber    10    

Парсинг html страниц с выводом информации через JavaScript с использованием Selenium

WEB v8 1cv8.cf Бесплатно (free)

Есть девочки как девочки, есть мальчики как мальчики, есть сайтики как сайтики, но странички их обманщики. В целях сохранить информацию, от автоматизированного сбора, многие ресурсы пытаются защитить ее. Один из таких способов - вывод информации на странице через JavaScript. При получении такой страницы в 1С, JavaScript не успевает вывести необходимые данные, и в 1с получаем практически пустую страницу. В статье приведу пример разработки, для парсинга таких страниц, без регистрации и смс.

20.05.2020    1472    0    platonov.e    16    

Интеграция 1С и CMS WordPress посредством Rest API сайта. Шаг третий, WooCommerce, публикация категорий товаров

WEB v8 1cv8.cf Бесплатно (free)

Интеграция 1С и CMS WordPress посредством функционала Rest API. Используем только язык программирования 1С и штатный функционал Rest API предоставляемый CMS, без дополнительных библиотек и плагинов. Процедуры и функции публикации категорий товаров в магазин WooCommerce, с комментариями внутри.

13.05.2020    1262    0    osivv    3    

Online телефонный справочник из 1С: Зарплата и управление персоналом Промо

WEB Управление персоналом (HRM) Управление персоналом (HRM) v8 ЗУП3.x Россия Бесплатно (free)

В интернете представлено много реализаций online телефонных справочников организаций. Есть справочники, которые использует для хранения информации базу Active Directory (LDAP), есть справочники, которые реализованы с использованием СУБД (например, MySQL). Но я не нашел справочника, который использует информацию из базы 1С. Далее я рассмотрю данную разработку.

10.03.2017    24097    0    ruha    14    

Интеграция 1С и CMS WordPress посредством Rest API сайта. Шаг второй, публикация картинок

WEB v8 Бесплатно (free)

Интеграция 1С и CMS WordPress посредством функционала Rest API. Используем только язык программирования 1С и штатный функционал Rest API предоставляемый CMS, без дополнительных библиотек и плагинов. Процедуры и функции передачи фото из 1С, с комментариями внутри.

13.05.2020    942    0    osivv    0    

Интеграция Camunda BPM и 1С

WEB Интеграция v8 Бесплатно (free)

Быстрый старт. Только практические примеры. Установка, запуск и публикация бизнес-процесса на сервере Camunda BPM. Управление бизнес-процессами из 1С при помощи Camunda REST API.

12.05.2020    913    0    zhichkin    4    

Интеграция 1С и CMS WordPress посредством Rest API сайта. Первый шаг

WEB v8 Россия Бесплатно (free)

Интеграция 1С и CMS WordPress посредством функционала Rest API. Используем только язык программирования 1С и штатный функционал Rest API предоставляемый CMS, без дополнительных библиотек и плагинов. Процедуры и функции 1С с комментариями внутри.

28.04.2020    2446    0    osivv    23    

Кэширование COM-соединения. Три способа Промо

Практика программирования Перенос данных из 1С7.7 в 1C8.X Внешние источники данных WEB v8 Россия Бесплатно (free)

Статья о трех способах кэширования COM-соединения в 1С:Предприятии 8.x.

11.04.2013    39633    0    YPermitin    33    

Выразительный Web API

WEB v8 Бесплатно (free)

Теория разработки Web API с ожидаемым поведением, за который не будет стыдно за пределами мира 1С.

27.04.2020    3764    0    fr13    19    

Хранение статистики публикаций автора сообщества Инфостарт ® (мобильное приложение И ++)

Мобильная разработка WEB v8 1cv8.cf Бесплатно (free)

Инфостарт ® достаточно удобный в плане работы со своим личным кабинетом сайт. Но программисты тем и отличаются от большинства людей, что им хочется знать больше. Поэтому появилась конфигурация 1С (она же мобильное приложение 1С) для более подробного учета статистики публикаций: рейтинг, количество просмотров, количество комментариев в динамике и в разрезах.

24.04.2020    1237    0    capitan    13    

Интеграция 1С с веб-сервисами Лукойл ЛИКАРД

WEB v8 1cv8.cf Россия Бесплатно (free)

Описание интерфейса взаимодействия сервиса Лукойл- ЛИКАРД с информационной системой 1С.

20.04.2020    2611    0    RPGrigorev    0    

Помощник работы с VirtueMart Промо

WEB Розничная торговля Розничная торговля v8 УТ10 УПП1 Россия Бесплатно (free)

Обработка для обмена данными с интернет-магазином на базе VirtueMart. Позволяет выгружать товары с изображениями и загружать заказы покупателей. Управлять интернет-магазином теперь стало просто!

19.04.2012    23180    1    salexdv    13    

Ошибка инициализации модуля: HTTPСервис

WEB v8 1cv8.cf Узбекистан Бесплатно (free)

Решение проблемы "Ошибка при работе с HTTP сервисом 500. Ошибка инициализации модуля".

13.04.2020    1450    0    VipDim    10    

COVID-19. Динамика эпидемии

WEB v8 v8::СКД 1cv8.cf Бесплатно (free)

Весной 2020 практически все ждут, «когда же это закончится», когда эпидемия пойдет на спад. Специалисты призывают «сгладить кривую». Как понять, в какой точке мы сейчас? Данные университета Джонса Хопкинса в любой 1С.

01.04.2020    2466    0    Alejandro_V    6    

Как я собрал для себя высокопроизводительный и бесплатный облачный бекенд для 1С на PosgreSQL + PostgREST

Производительность и оптимизация (HighLoad) WEB Интеграция Мобильная разработка Администрирование веб-серверов v8 Бесплатно (free)

В этой статье я расскажу о проблемах бека для мобильных приложений или другого фронта, который требует производительности, быстрой реакции и отказоустойчивости, и как я решил это благодаря opensource проекту PostgREST и СУБД Postgre SQL 12. Проведу простой тест производительности для сравнения 1С с данным решением. Это может быть полезно всем, кто разрабатывает мобильные приложения либо фронтсайд-приложения для 1С на чем угодно - на мобильной платформе или на нативном языке или на Simple UI. И также обзор новых функций SimpleUI для связи с этим бекендом.

31.03.2020    9431    0    informa1555    21    

Заготовка для загрузки файлов по ftp Промо

WEB Перенос данных из 1C8 в 1C8 v8 1cv8.cf Бесплатно (free)

3 процедуры и 1 макет

03.06.2013    29205    0    anig99    6    

Коронавирус COVID-19. Статистика по странам

WEB v8 Бесплатно (free)

В связи с COVID-19 люди поделились на две категории: те, кто осознал, и те кто ЕЩЕ не осознал. Единственное наше преимущество перед Коронавирусом заключается в том, что информация распространяется быстрее, чем расползается "невидимка".

25.03.2020    4971    2    Evgen.Ponomarenko    60    

Получение html-кода страницы. JS из 1С

Практика программирования WEB v8 Бесплатно (free)

Получение исходника страницы, выполнение произвольного js-кода. Теперь с WebKit от 1С.

18.02.2020    4156    0    Yashazz    1    

Отладка конфигурации в режиме веб-клиента

WEB v8 Бесплатно (free)

После очередного обновления платформы при попытке запуска отладки в веб-клиенте стало появляться сообщение. Собственно, до этого момента никогда веб-клиентом особо не пользовался и необходимости в отладке как-то не возникало. Данное сообщение заставило задуматься, что не так с отладкой в веб-клиенте и как ее собственно включить? Тот самый неловкий момент, когда программа просит обратиться к администратору, а администратор - это вы.

12.02.2020    3319    0    gamletspb    2    

Анализ работы внешней обработки сервиса МодульКасса применительно к задаче фискализации чеков при доставке

Кассовые операции WEB v8 УТ11 Россия Бесплатно (free)

В статье разберу работу внешней обработки для работы с МодульКасса, опишу недочеты и применимость для организации доставки, предложу собственный вариант реализации.

11.02.2020    1909    0    malikov_pro    0    

Вариант реализации REST API для 1С-Битрикс Управление сайтом

WEB v8 Россия Бесплатно (free)

В статье опишу вариант обмена 1С УТ 11.4 и 1С-Битрикс УС 18.5 с иcпользованием компонентов Symfony, в качестве примера обмен данными по складам.

28.01.2020    3041    0    malikov_pro    2    

Вариант реализации работы с сервисом Dadata применительно к конфигурации УТ 11.4 и подобным

WEB v8 УТ11 Россия Бесплатно (free)

В статье описывается реализация получения данных с сервиса DaData при работе с формами справочников в конфигурации УТ 11 для дополнения информации по ФИО, ИНН, Адресу.

22.01.2020    2280    0    malikov_pro    5    

Двусторонний обмен с поставщиком через интернет-магазин для реализации товаров с ответственного хранения (с 01.02.2020 "Партии" не используются)

Файловые протоколы обмена, FTP WEB v8 УНФ Оптовая торговля, дистрибуция, логистика Россия УУ Бесплатно (free)

Рассмотрены реализация двустороннего обмена данными с использованием API-сервиса сайта поставщика при продаже товаров со склада ответственного хранения, алгоритм движения товаров и обмена документами на примере конфигурации 1С: УНФ у партнера, который взаимодействует с поставщиком "ООО Пауэр-Интернэшнл-шины" - одним из крупнейших в России поставщиков автомобильных шин и дисков.

16.01.2020    3420    0    chkurs    0    

Получение номера ВСД по идентификатору 1С: Меркурий

Производство готовой продукции (работ, услуг) WEB v8 УТ11 Пищевая промышленность Россия Бесплатно (free)

Код парсинга веб страницы для получения номера ВСД в системе Меркурий.

24.11.2019    3502    0    ohyen    0    

Немного о интеграции с CRM AMO

WEB v8 1cv8.cf Бесплатно (free)

Немного информации о том, как настроить интеграцию с CRM AMO. Пример функций для подключения к АМО и обновления заказа. Пример на основе API авторизации.

15.11.2019    3376    0    xxxAndricxxx    6    

Ещё немного о ИНН и сервисе DaData

WEB v8 1cv8.cf Бесплатно (free)

Об использовании сервиса dadata и немного информации о возможностях получать данные по ИНН. Возможно, кому-то будет полезным.

14.11.2019    6069    0    xxxAndricxxx    21    

Вариант реализации клиента SOAP на примере получения остатков из MERLION

WEB v8 1cv8.cf Россия Бесплатно (free)

В статье приведу пример клиента к сервису SOAP, функции которого принимают несколько значений типа строка или массив строк.

14.11.2019    2807    0    malikov_pro    0    

Разбор любого JSON-объекта в соответствующую структуру

Инструментарий разработчика WEB v8 1cv8.cf Бесплатно (free)

Данная публикация предназначена разработчикам 1С, которым приходиться разбирать данные формата JSON. Выложенный пример кода создает объект типа Структура, полностью повторяющий структуру данных формата JSON.

13.11.2019    6251    0    user665435_al.windstorm    14    

Проверка reCAPTCHA от Google на стороне HTTP-Сервиса

WEB v8 Россия Бесплатно (free)

Код проверяет переданный токен reCAPTCHA от Google при вызове HTTP-Сервиса. Таким образом проверяем, отправил ли данные на наш HTTP-Сервис робот или реальный пользователь.

06.11.2019    5163    0    AVR    0    

Простой способ опубликовать базу 1C из дома в интернет, когда Ваш провайдер этого не обеспечивает (3G, 4G модем и т.п.)

WEB Облачные сервисы, хостинг v8 1cv8.cf Бесплатно (free)

Если у Вас возникла потребность опубликовать из дома во всемирную паутину базу 1С (например, для тестирования), в т.ч. интерфейс OData, HTTP или Web-сервисы, а интернет-провайдер (например, 3G Мегафон) не предоставляет возможности инициировать соединения извне, то в конце статьи Вы найдете простой, быстрый и условно-бесплатный способ это сделать.

14.10.2019    9523    0    uno-c    25    

Самый примитивный HTTP-сервис в мире

WEB v8 Бесплатно (free)

Пошаговый пример создания простейшего HTTP-сервиса, который генерирует HTML-страницу для поиска товара, а также реализует асинхронное получение данных из базы.

12.09.2019    18090    0    YPermitin    26    

Свой веб интерфейс к 1С: побеждаем CORS на IIS, сохраняя авторизацию

WEB Администрирование данных 1С v8 Бесплатно (free)

Если "веб морда" расположена не по тому же адресу, что и публикация 1С (что часто бывает, например, при разработке, публикация 1С на http://localhost/1c, а разрабатываемое веб-приложение на http://localhost:8080) или, например, мы заходим на веб приложение то по ip адресу, то по имени сервера, или просто веб сервер и сервер, на котором опубликована 1С - это разные сервера, то для большинства запросов от браузера к 1С срабатывает политика CORS, которая заключается в том, что браузер сначала посылает запрос OPTIONS, на который сервер должен ответить определенным образом, заголовками, содержащими разрешения, а потом уже (если разрешение есть), браузер посылает основной запрос. В случае, когда в публикации 1С (default.vrd) жестко прописан логин и пароль, разрулить ситуацию можно средствами 1С. В случае же, когда нужно сохранить авторизацию (или используется стандартный интерфейс odata), начинаются проблемы.

20.08.2019    9437    0    Fragster    9    

Вывод отчетов из Штрих-М Торговое предприятие 5 на кассовое ПО Кассир 5 через веб-сервис

Розничная торговля WEB Розничная торговля v8 1cv8.cf Розничная и сетевая торговля (FMCG) Россия УУ Бесплатно (free)

Универсальный механизм вывода отчетов товароучетной системы Штрих-М Торговое предприятие в кассовое ПО Кассир 5 посредством веб-сервиса.

14.08.2019    5233    0    Van2507    1    

Совсем простой обмен HTTP, 2 функции

WEB v8 Бесплатно (free)

Функция для вызова рест-сервиса и функция для разбора результата. Быстро, просто, универсально.

12.08.2019    7676    0    Yashazz    15    

Использование HTTP-сервиса для создания "фронтенда" HTML/CSS/jQuery. Продолжение

WEB v8 1cv8.cf Бесплатно (free)

Получение изображений из информационной базы и отправка файлов через "фронт" на HTML/CSS/JS.

08.08.2019    7232    0    Sedaiko    1    

1Script.Web. Интернет-приложения на языке 1С

WEB OneScript Инструментарий разработчика v8 Бесплатно (free)

Запросы рынка таковы, что любое современное клиент-серверное приложение должно иметь веб-интерфейс. Почему бы не писать такие приложения на языке 1С? Андрей Овсянкин расскажет о возможностях разработки веб-приложений на базе 1Script, рассмотрит перспективы этого направления и в качестве демонстрации покажет «боевое» веб-приложение на новом движке – кроссплатформенную консоль администрирования парка кластеров 1С.

20.05.2019    18350    0    Evil Beaver    33    

Неверные остатки на сайте битрикс

WEB v8 УТ11 Бесплатно (free)

Исправление процедуры выгрузки остатков на сайт битрикс из УТ 11

25.04.2019    5158    0    distorshion    4    

Отправка файлов через SOAP. SOAP with attachments, MTOM

WEB v8 1cv8.cf Россия Бесплатно (free)

В продолжение «своеобразной» поддержки 1С протокола SOAP, описанной в https://infostart.ru/public/965259/, опишу еще одну особенность. 1С не поддерживает возможность отправки файлов-вложений. Для решения этой проблемы пришлось самостоятельно писать формирование пакетов SOAP и разбор ответов сервера.

18.04.2019    7312    0    mysm    2    

HTML-клиент у конфигурации 1С

WEB v8 Бесплатно (free)

Приветствую. В этой публикации опишу свой опыт создания html-клиента для конфигурации 1С с помощью http-сервисов. HTML-клиент в этом случае - это frontend (html + css+ js), который генерирует и выдает пользователю конфигурация + backend, который тоже реализован в этой же конфигурации.

17.04.2019    16064    0    Smaylukk    119    

Парсинг сайтов из 1С на примере ломбарды.рф с помощью XPATH для ДокументDOM

WEB v8 Бесплатно (free)

На всякую хитрую гайку всегда найдется болт с резьбой (с)

01.04.2019    13917    0    starik-2005    33    

Логируй больше! 1С + UPD + GELF + Graylog

Практика программирования Администрирование данных 1С WEB Разработка v8 Бесплатно (free)

Наличие производительной платформы управления логами - это жизненно важный элемент в ландшафте систем с высокой активностью. Рассмотрим один из подходов логирования активности систем на платформе 1С в Graylog.

26.02.2019    10476    0    Lars Ulrich    16    

Устранение некоторых ошибок, обнаруженных в модуле Обмена с ВЕТИС (ФГИС Меркурий)

WEB Адаптация типовых решений v8 БП3.0 Сельское хозяйство и рыболовство Оптовая торговля, дистрибуция, логистика Пищевая промышленность Россия Бесплатно (free)

Устранение ошибок, обнаруженных в модуле Обмена с ВЕТИС (ФГИС Меркурий) в конфигурации Бухгалтерия предприятия, редакция 3.0 (3.0.67.67).

08.02.2019    7355    0    aks    3    

Создание телеграм бота с гугл авторизацией, обратными вызовами и уведомлениями об обновлении через сервер-маршрутизатор

WEB v8 1cv8.cf Бесплатно (free)

Статья детально рассказывает обо всех аспектах настройки телеграм бота, работающего через сервер-маршрутизатор посредством обратных вызовов. Приведены примеры работы отправки/исправления сообщений, отправки файлов, работы с внутренними и встроенными запросами. Создание клавиатуры. Авторизация пользователей через gmail.

07.11.2018    26718    0    🅵🅾️🆇    57    

Мой опыт небольшого проекта с веб-сервисами (Часть 2)

WEB v8 Бесплатно (free)

Продолжение публикации по веб-сервису для реализации странички с выводом данных.

05.10.2018    6651    0    alex_bitti    0