Загрузка расходов СБИС
Модуль загрузки расходов из ЭД (СБИС)
Загрузка расходов СБИС Документация
Настройка
Алгоритмы распознания
Алгоритм для распознания строк
Подходит для случаев, где для заполнения строк расхода достаточно "Основного вложения". Основное вложение - это электронный документ подтверждения факта хозяйственной деятельности (Акт, УПД). Если из предоставляемой поставщиком услуги можно выделить услугу без мусора (меняющиеся части) и номер грузоперевозки, то этот тип алгоритма подойдёт для этого поставщика.
Выполняется в контексте:
УслугаПоставщика = СокрЛП(СтруктураСтроки.НаимТов);
Рез = Новый Структура("Контейнера,Услуга",Новый Массив,"");
Например, услуга в документе поставщика содержит услугу "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 Тогда
Если СтрокаАкта.Всего <> неопределено И СтрокаАкта.НДС <> неопределено Тогда
ЗаполнитьЗначенияСвойств(НС,СтрокаАкта,"Всего,НДС");
КонецЕсли;
КонецЕсли;
//-------------------------------------------
НС.Сумма = НС.Всего - НС.НДС;
НС.Услуга = ОчиститьУслугуФИТ(СтрокаАкта.Наименование);
НС.ПорядокОтражения = ПП.ПорядокОтражения;
РасходЗаготовка.Услуги.Добавить(НС);
КонецЦикла;
История изменений Загрузка расходов СБИС
26.04.24
Все изменения сведены в один модуль.