Загрузка расходов СБИС Документация
Настройка
Алгоритмы распознания
Алгоритм для распознания строк
Подходит для случаев, где для заполнения строк расхода достаточно "Основного вложения". Основное вложение - это электронный документ подтверждения факта хозяйственной деятельности (Акт, УПД). Если из предоставляемой поставщиком услуги можно выделить услугу без мусора (меняющиеся части) и номер грузоперевозки, то этот тип алгоритма подойдёт для этого поставщика.
Выполняется в контексте:
УслугаПоставщика = СокрЛП(СтруктураСтроки.НаимТов);
Рез = Новый Структура("Контейнера,Услуга",Новый Массив,"");
Например, услуга в документе поставщика содержит услугу "XXXU1234567 Агентское вознаграждение ФИТ"
Как видим, услуга с номером контейнера и без "мусора". В этом случае, будет достаточно выделить из строки номера контейнеров, а остальное считать услугой:
СыраяСтрока = СтрЗаменить(УслугаПоставщика,","," ");
ЧастиСтроки = СтрРазделить(СыраяСтрока," ",Ложь);
Для каждого Часть ИЗ ЧастиСтроки Цикл
Контейнер = ВРег(СокрЛП(Часть));
Если СтрДлина(Контейнер) <> 11 ИЛИ Сред(Контейнер,4,1)<>"U" Тогда
Рез.Услуга = Рез.Услуга + ?(Рез.Услуга = "",""," ")+Часть;
Продолжить;
КонецЕсли;
Рез.Контейнера.Добавить(Контейнер);
КонецЦикла;
Рез.Услуга = СокрЛП(Рез.Услуга);
Услуга поставщика может быть похожа на следующую: "Перевозка контейнера XXXU1234567 Коносамент SKLM1111111 Маршрут: НАХОДКА ВОСТОЧНЫЙ - КЛЕЩИХА". В этом случае в услуге есть "мусор", это номер коносамента, маршрут. Если мы их не уберём, то сопоставление номенклатуры работать не будет. В этом случае, всё до номера контейнера можно считать услугой, всё после - мусором:
СыраяСтрока = СтрЗаменить(УслугаПоставщика,","," ");
ЧастиСтроки = СтрРазделить(СыраяСтрока," ",Ложь);
БылКонтейнер = Ложь;
Для каждого Часть ИЗ ЧастиСтроки Цикл
Контейнер = ВРег(СокрЛП(Часть));
Если СтрДлина(Контейнер) <> 11 ИЛИ Сред(Контейнер,4,1)<>"U" Тогда
Если БылКонтейнер = Ложь Тогда
Рез.Услуга = Рез.Услуга + ?(Рез.Услуга = "",""," ")+Часть;
КонецЕсли;
Продолжить;
КонецЕсли;
Рез.Контейнера.Добавить(Контейнер);
БылКонтейнер = Истина;
КонецЦикла;
Рез.Услуга = СокрЛП(Рез.Услуга);
Алгоритм распознания документов
Часть поставщиков не указывают в типовых электронных документов информацию, достаточную для формирования расхода, и дополняют электронный пакет файлом, в котором содержится нужная информация. Таким файлом может являться дополнительный xml файл (ВМТП/ФИТ), pdf файл,
В настройке поставщика "Поиск вложения к распознанию" можно указать условия подбора вложения к распознанию. Установка текстовых значений через запятую наложит фильтр по указанным значениям поля "Тип" при переборе вложений пакета. Можно так же указать условие в формате структуры, например: "Новый Структура("Тип","Расчет_Стоимости")":
Тут, в качестве контекста, вам достаются объекты ДД, РасходЗаготовка, ПП. ДД - двоичные данные вложения на распознание, РасходЗаготовка - это расход в виде структуры:
ПоляРасхода = "Услуги,Организация,Контрагент,Договор,Валюта,ПредъявленСчет,ПредъявленАкт,ПредъявленСФ,НомерСчета,ДатаСчета,НомерАкта,ДатаАкта,НомерСФ,ДатаСФ,ЭтоКорректировка,Продавец,Расход,РасходПроведен,ДокументБП,Счет";
ПоляУслуг = "НомерКонтейнера,Услуга,Грузоперевозка,Номенклатура,Представление,ПорядокОтражения,Покупатель,ДоговорПокупателя,СтавкаНДС,Цена,Количество,Сумма,НДС,Всего";
Поля расхода уже будут заполнены нужными значениями. При распознании, вам нужно заполнить массив РасходЗаготовка.Услуги элементами Новый Структура(ПоляУслуг), элементами с заполненными значениями полей НомерКонтейнера,Услуга,СтавкаНДС,Цена,Количество,Сумма,НДС,Всего. Так же, в этом алгоритме, вы можете изменить любые другие значения РасходЗаготовка.
Распознавание xml вложения Расчет_Стоимости (ВМТП / ФИТ) возможно следующим алгоритмом:
Документ = РаспознатьXML(ДД,Док.ОсновноеВложениеКНД,ФабрикиПоКНД);
Если Не ЗначениеЗаполнено(РасходЗаготовка.Договор) Тогда
//Документ.Header.Agr_number / Документ.Header.Agr_date ;
НомерДоговора = Документ.Header.Agr_number;
ДатаДоговора = ВычленитьДату(Документ.Header.Agr_date);//
Если ЗначениеЗаполнено(НомерДоговора) И ЗначениеЗаполнено(ДатаДоговора) Тогда
РасходЗаготовка.Договор = ITSP_ВернутьЭлементСправочника("CW_ДоговорыПоГрузоперевозкам",
Новый Структура("НомерДоговора,ДатаДоговора,Наименование,Владелец,Организация,ВалютаДоговора,ВидДоговора",
НомерДоговора,
ДатаДоговора,
НомерДоговора+" "+Формат(ДатаДоговора,"ДФ=dd.MM.yy"),
РасходЗаготовка.Контрагент,
РасходЗаготовка.Организация,
РасходЗаготовка.Валюта,
Перечисления.ВидыДоговоровКонтрагентов.СПоставщиком),
СтроковыеФункцииКлиентСервер.РазложитьСтрокуВМассивПодстрок("НомерДоговора,Владелец,Организация,ВалютаДоговора,ВидДоговора"),Истина); // Поиск по всему, кроме наименования и даты. Мало ли может ошиблись. Это не критично
КонецЕсли;
КонецЕсли;
РасходЗаготовка.Услуги = Новый Массив;
Если ПП.ИскатьНомерСчета Тогда
Попытка
РасходЗаготовка.НомерСчета = Документ.Header.Inv_Number;
РасходЗаготовка.ДатаСчета = ITSP_XMLДата(Документ.Header.Inv_Date);
Исключение
КонецПопытки;
КонецЕсли;
СтрокиАкта = Новый ТаблицаЗначений;
СтрокиАкта.Колонки.Добавить("Идентификатор");
СтрокиАкта.Колонки.Добавить("Наименование");
СтрокиАкта.Колонки.Добавить("СтавкаНДС");
СтрокиАкта.Колонки.Добавить("Цена");
СтрокиАкта.Колонки.Добавить("Всего");
СтрокиАкта.Колонки.Добавить("НДС");
Если ТипЗнч(Документ.Act_Row) = Тип("ОбъектXDTO") Тогда
ITSP_ДобавитьСтрокуАкта(Документ.Act_Row,СтрокиАкта);
Иначе
Для каждого ЭлементТаблицы ИЗ Документ.Act_Row Цикл
ITSP_ДобавитьСтрокуАкта(ЭлементТаблицы,СтрокиАкта);
КонецЦикла;
КонецЕсли;
УслугиПоОбъектам = Новый ТаблицаЗначений();
УслугиПоОбъектам.Колонки.Добавить("ИдентификаторСтрокиАкта");
УслугиПоОбъектам.Колонки.Добавить("ИдентификаторПеревозки");
УслугиПоОбъектам.Колонки.Добавить("ЕдиницаИзмерения");
УслугиПоОбъектам.Колонки.Добавить("Количество");
УслугиПоОбъектам.Колонки.Добавить("Всего");
УслугиПоОбъектам.Колонки.Добавить("НДС");
Если ТипЗнч(Документ.Object_Service) = Тип("ОбъектXDTO") Тогда
ITSP_ДобавитьУслугуПоОбъектам(Документ.Object_Service,УслугиПоОбъектам);
Иначе
Для каждого ЭлементТаблицы ИЗ Документ.Object_Service Цикл
ITSP_ДобавитьУслугуПоОбъектам(ЭлементТаблицы,УслугиПоОбъектам);
КонецЦикла;
КонецЕсли;
ОбъектыПеревозки = Новый ТаблицаЗначений();
ОбъектыПеревозки.Колонки.Добавить("Идентификатор");
ОбъектыПеревозки.Колонки.Добавить("НомерКонтейнера");
Если ТипЗнч(Документ.Transfer_Object) = Тип("ОбъектXDTO") Тогда
ITSP_ДобавитьОбъектПеревозки(Документ.Transfer_Object,ОбъектыПеревозки);
Иначе
Для каждого ЭлементТаблицы ИЗ Документ.Transfer_Object Цикл
ITSP_ДобавитьОбъектПеревозки(ЭлементТаблицы,ОбъектыПеревозки);
КонецЦикла;
КонецЕсли;
Для каждого УслугаПоОбъектам ИЗ УслугиПоОбъектам Цикл
НС = Новый Структура(ПоляУслуг);
СтрокаАкта = СтрокиАкта.Найти(УслугаПоОбъектам.ИдентификаторСтрокиАкта,"Идентификатор");
ОбъектПеревозки = ОбъектыПеревозки.Найти(УслугаПоОбъектам.ИдентификаторПеревозки,"Идентификатор");
Если СтрокаАкта = Неопределено ИЛИ ОбъектПеревозки = Неопределено Тогда
//МассивСообщений.Добавить("Ошибка формата. "+ПредставлениеДокумента);
//Возврат Неопределено;
КонецЕсли;
ЗаполнитьЗначенияСвойств(НС,УслугаПоОбъектам,"Количество,Всего,НДС");
ЗаполнитьЗначенияСвойств(НС,СтрокаАкта,"Цена,СтавкаНДС");
ЗаполнитьЗначенияСвойств(НС,ОбъектПеревозки,"НомерКонтейнера");
//------------------------------------------- были замечены ситуации, когда в услугахПоОбъекту нет информации о НДС, но есть в строке акта. Однако информацию из строки акта можно брать только в том случае, когда услугПоОбъектам, касающихся этой строки акта одын штука
Если УслугиПоОбъектам.НайтиСтроки(Новый Структура("ИдентификаторСтрокиАкта",СтрокаАкта.Идентификатор)).Количество() = 1 Тогда
Если СтрокаАкта.Всего <> неопределено И СтрокаАкта.НДС <> неопределено Тогда
ЗаполнитьЗначенияСвойств(НС,СтрокаАкта,"Всего,НДС");
КонецЕсли;
КонецЕсли;
//-------------------------------------------
НС.Сумма = НС.Всего - НС.НДС;
НС.Услуга = ОчиститьУслугуФИТ(СтрокаАкта.Наименование);
НС.ПорядокОтражения = ПП.ПорядокОтражения;
РасходЗаготовка.Услуги.Добавить(НС);
КонецЦикла;