Имя: Пароль:
1C
1С v8
Смс шлюз, помогите разобраться!
,
0 prilforreal
 
15.11.17
11:45
Доброго всем дня! 1с8.3 конфигурация самописная, есть обработка смс шлюз, с ее помощью из сообщений эл.почты (пересланных смс-уведомлений от банка) создается документ оплата с данными из сообщения. Обработка настроена на смс от сбербанка, другие сообщения идут лесом, Теперь добавились оплаты на карту тинькофф, нужно эти сообщения также автоматически заносить в док.Оплата,обработка работает через разбор текста сообщения и еще через неведомые мне алгоритмы(точнее ведоммые но понять я их к сожалению за недостатком опыта не могу) Помогите пожалуйста разобраться, как настроить обработку, вот листинг кода:


Процедура Сформировать()  
    Перем ТЗотправители,Запрос,ТекстЗапроса;

    ТЗотправители=Новый ТаблицаЗначений;
    ТЗотправители.Колонки.Добавить("Сумма");
    ТЗотправители.Колонки.Добавить("Текст");
    Запрос=Новый Запрос;
    
    СтрТема=""; СтрАтт=""; Тело="";
    ТЗ.Очистить();//.УдалитьСтроки();

    Пар=Новый ТаблицаЗначений;
    Пар.Колонки.Добавить("Наименование");
    Пар.Колонки.Добавить("Значение");
    
    Профиль=Новый ИнтернетПочтовыйПрофиль;
    Профиль.АдресСервераPOP3=СерверПриема;
    Профиль.ПортPOP3=ПортПриема;
    Профиль.Пользователь=Логин;
    Профиль.Пароль=Пароль;
    Попытка
        Почта.Подключиться(Профиль);
    Исключение
        Сообщить(ОписаниеОшибки());
        Возврат;
    КонецПопытки;
    Письма=Почта.Выбрать(Ложь);
    СР=Справочники.СтатьиРасхода.НайтиПоКоду(132);
    ТЗПисьма=Новый ТаблицаЗначений;
    ТЗПисьма.Колонки.Добавить("Наименование");
    СтрТЗ=ТЗ.Добавить();
    ВКкс=Письма.Количество();
    Для Индекс=0 По ВКкс Цикл
        Итог="";
        флаг=0;
        
        если ВКкс<>Индекс тогда
            ВК=Письма.Получить(Индекс);
            если НРЕГ(сокрлп(ВК.Кодировка))<>"utf-8" тогда
            стр="";
            Для каждого ТекстПисьма из ВК.Тексты цикл
                Стр=Стр+" "+ТекстПисьма.Текст;
            КонецЦикла;    
                
                Длина=СтрДлина(Стр);
        
                Для Н=1 По Длина Цикл
                    Знак=Сред(Стр,Н,1);
                    Код=КодСимвола(Знак,1);
                    Если Код<128 Тогда
                        Итог=Итог+Знак;
                    ИначеЕсли (Код>=128)И(Код<192) Тогда
                        
                    Иначе
                        Н=Н+1;
                        Знак2=Сред(Стр,Н,1);
                        Код2=КодСимвола(Знак2,1);
                        Если Код=208 Тогда
                            Если Код2=129 Тогда
                                Итог=Итог+"Ё";
                            Иначе
                                Итог=Итог+Символ(КодСимвола("А",1)+Код2-144);
                            КонецЕсли;                                                      
                        ИначеЕсли Код=209 Тогда
                            Если Код2=145 Тогда
                                Итог=Итог+"ё";
                            Иначе
                                Итог=Итог+Символ(КодСимвола("р",1)+Код2-128);
                            КонецЕсли;
                        КонецЕсли;
                    КонецЕсли;
                КонецЦикла;
                ном=Найти(Итог,"This message was delivered by MDaemon - http");
                если Ном<>0 тогда
                    Итог=Лев(Итог,ном-1);
                конецесли;
                Итог=СокрЛП(Итог);
            иначе
                стр="";
                Для каждого ТекстПисьма из ВК.Тексты цикл
                    Стр=Стр+""+ТекстПисьма.Текст;
                КонецЦикла;    
                Итог=СокрЛП(стр);
            конецесли;
            
            спрП=Справочники.Письма.НайтиПоНаименованию("<"+СокрЛП(ВК.ИдентификаторСообщения)+">");

            Если НЕ ЗначениеЗаполнено(спрП) тогда
                флаг=1;
            конецесли;
        конецесли;    
//        
//        
        если (флаг=1) или (ВКкс=Индекс) тогда
            Если (СтрНайти(Итог,"перевел(а)")<>0) Тогда

                СтрТЗотпр=ТЗотправители.Добавить();
                от=СтрНайти(Итог,"перевел(а) Вам ")+15;
                сколько=СтрНайти(Итог," RUB.");
                Если сколько=0 тогда
                    сколько=СтрНайти(Итог," RUB")-от;
                Иначе
                    сколько=сколько-от;
                КонецЕсли;    

                СтрТЗотпр.Сумма=Число(Сред(Итог,от,сколько));

                СтрТЗотпр.Текст=Символы.ПС+"Возможно "+Сред(Итог,18);
                
                Запрос.Текст="ВЫБРАТЬ
                             |    КартыОплаты.Дилер КАК Дилер,
                             |    КартыОплаты.Фамилия,
                             |    КартыОплаты.ИмяИ,
                             |    КартыОплаты.Отчество,
                             |    КартыОплаты.Собственник,
                             |    КартыОплаты.Собственник КАК СтрСобственник,
                             |    КартыОплаты.ФИО КАК ФИО
                             |ИЗ
                             |    (ВЫБРАТЬ
                             |        КартыОплаты.Владелец КАК Дилер,
                             |        КартыОплаты.Владелец.Фамилия КАК Фамилия,
                             |        КартыОплаты.Владелец.Имя КАК ИмяИ,
                             |        КартыОплаты.Владелец.Отчество КАК Отчество,
                             |        КартыОплаты.Собственник КАК Собственник,
                             |        ВЫРАЗИТЬ(""%"" + КартыОплаты.Собственник + ""%"" КАК СТРОКА) КАК СтрСобственник,
                             |        ВЫРАЗИТЬ(""%"" + КартыОплаты.Владелец.Имя + "" "" + КартыОплаты.Владелец.Отчество + "" "" + КартыОплаты.Владелец.Фамилия + "".%"" КАК СТРОКА) КАК ФИО
                             |    ИЗ
                             |        Справочник.КартыОплаты КАК КартыОплаты) КАК КартыОплаты
                             |ГДЕ
                             |    ((КартыОплаты.ИмяИ <> """"
                             |                И КартыОплаты.Отчество <> """"
                             |                И КартыОплаты.Фамилия <> """")
                             |                И &Итог ПОДОБНО КартыОплаты.ФИО)
                             |            ИЛИ (КартыОплаты.Собственник <> """"
                             |                И &Итог ПОДОБНО КартыОплаты.СтрСобственник)";
                Запрос.УстановитьПараметр("Итог",Итог);
                Рез=Запрос.Выполнить().Выбрать();

                Пока Рез.Следующий() Цикл

                    СтрТЗотпр.Текст=СтрТЗотпр.Текст+Символы.ПС+Рез.Дилер;
                КонецЦикла;

            ИначеЕсли (((Лев(Итог,4)="VISA")или(Лев(Итог,4)="ECMC")или(Врег(Лев(СокрЛП(СтрТЗ.Тело),7))="БАЛАНС "))и(СтрНайти(СокрЛП(Итог),"ОТКАЗ")=0))или(ВКкс=Индекс) ТОГДА
                поз=СтрНайти(СтрТЗ.Тело,"операция зачисления на сумму");
                поз1=СтрНайти(СтрТЗ.Тело,"зачисление");
                поз2=СтрНайти(СтрТЗ.Тело,"оплата услуг");
                поз3=СтрНайти(СтрТЗ.Тело,"Баланс:");
                Если (поз>0)или((поз1>0)и(сред(СтрТЗ.Тело,9,1)<>":")) тогда
                    дО=Документы.Оплата.СоздатьДокумент();
                    дО.УстановитьНовыйНомер();
                    дО.Дата=ТекущаяДата();
                    дО.Записать();
                    если поз>0 тогда
                        дО.Дата=Дата(Число("20"+Сред(СтрТЗ.Тело,17,2)),Число(Сред(СтрТЗ.Тело,14,2)),Число(Сред(СтрТЗ.Тело,11,2)),Число(Сред(СтрТЗ.Тело,20,2)),Число(Сред(СтрТЗ.Тело,23,2)),00);

                    иначеесли поз1>0 тогда
                        дО.Дата=Дата(Число("20"+Сред(СтрТЗ.Тело,16,2)),Число(Сред(СтрТЗ.Тело,13,2)),Число(Сред(СтрТЗ.Тело,10,2)),Число(Сред(СтрТЗ.Тело,19,2)),Число(Сред(СтрТЗ.Тело,22,2)),00);
                    конецесли;
                    
                    дО.Автор=ТекПользователь;

                    Сумма=0;
                    если поз>0 тогда                    
                            
                        Сумма=Сред(СтрТЗ.Тело,поз+29);
                        поз=СтрНайти(Сумма,"р");
                        если поз>0 тогда    
                            Сумма=Лев(Сумма,поз-1);                
                        конецесли;
//                        
                    иначеесли поз1>0 тогда
                        Сумма=Сред(СтрТЗ.Тело,поз1+11);
                        поз1=СтрНайти(Сумма,"р");
                        если поз1>0 тогда    
                            Сумма=Лев(Сумма,поз1-1);                
                        конецесли;
                    конецесли;
                    
                    дО.Сумма=Число(Сумма);
//                    
//                    
//                    
//                    
                    дО.Направление=Перечисления.Направление.Опт;
//                    

//                    
                    дО.Касса=Справочники.Кассы.НайтиПоРеквизиту("Карта",сред(СтрТЗ.Тело,5,4));
                    Карта="";
//                    
                    поз=СтрНайти(СтрТЗ.Тело,"****");
                    если поз>0 тогда
                        Карта=Сред(СтрТЗ.Тело,поз-4,12);
                    конецесли;
//                    
                    Карта=СокрЛП(СтрЗаменить(Карта,"****","-"));

                    поз=СтрНайти(СтрТЗ.Тело,"Баланс");
                    если поз>0 тогда
                        СтрТЗ.Тело=Лев(СтрТЗ.Тело,поз-1);
                    конецесли;
                    
                    строк=0;
                    СтрТЗотпр=ТЗотправители.Найти((Число(Сумма)),"Сумма");
                    

                    Если СтрТЗотпр<>Неопределено тогда
                        дО.Описание=СтрТЗ.Тело+СтрТЗотпр.Текст;
                        ТЗотправители.Удалить(СтрТЗотпр);
                    иначе
                        дО.Описание=СтрТЗ.Тело;
                    КонецЕсли;
//                    
//                    
//                    
                    дО.Сбер=1;
                    дО.Карта=Карта;  
                    отправить=0;
                    Спр=Справочники.КартыОплаты.НайтиПоНаименованию(Карта);
                    Сообщить(Карта+"|"+Спр);
                    Если ЗначениеЗаполнено(Карта) и ЗначениеЗаполнено(Спр) тогда
                        дО.Контрагент=Спр.Владелец;
                        Если ЗначениеЗаполнено(Спр.Владелец.ЭлПочта) тогда
                            отправить=1;
                        КонецЕсли;    
                    
                    иначе
                        дО.Контрагент=Константы.НеизвестныйКонтрагент.Получить();
                    конецесли;  
//                              
//                        
                    дО.Записать(РежимЗаписиДокумента.Проведение,РежимПроведенияДокумента.Неоперативный);
                    Сообщить(СокрЛП(дО)+"|"+дО.Контрагент);
                    если отправить=1 тогда
                        Долг=РегистрыНакопления.Расчеты.Остатки(,Новый Структура("Контрагент",дО.Контрагент)).Итог("Баланс");
                        Сообщить(""+дО.Контрагент+" Сумма: "+дО.Сумма+ "  руб. Баланс: "+Долг+" руб.");
                        глОтправитьОтчетПоПочте("",дО.Контрагент,"Поступление средств от "+дО.Контрагент+". ПМК Уют и Комфорт.",0,"Здравствуйте."+Символы.ПС+Символы.ПС+"На Ваш баланс поступила сумма в размере "+
                        дО.Сумма+" руб. с карты "+Карта+"."+Символы.ПС+Символы.ПС+"Ваш текущий баланс: "+Формат(Долг,"Ч12.2.,")+" руб."+Символы.ПС+Символы.ПС+"С уважением, ПМК ""Уют и Комфорт"".",0);
                    конецесли;
                    
                иначеесли (поз2<>0)и(поз3<>0) тогда
//                    

                    дРС=Документы.РасходСредств.СоздатьДокумент();
                    дРС.УстановитьНовыйНомер();
                    дРС.Дата=ТекущаяДата();
                    дРС.Записать(РежимЗаписиДокумента.Запись);
                    если поз>0 тогда
                        дРС.Дата=Дата(Число("20"+Сред(ТЗ.Тело,17,2)),Число(Сред(ТЗ.Тело,14,2)),Число(Сред(ТЗ.Тело,11,2)),Число(Сред(ТЗ.Тело,20,2)),Число(Сред(ТЗ.Тело,23,2)),00);

                    иначеесли поз1>0 тогда
                        дРС.Дата=Дата(Число("20"+Сред(ТЗ.Тело,16,2)),Число(Сред(ТЗ.Тело,13,2)),Число(Сред(ТЗ.Тело,10,2)),Число(Сред(ТЗ.Тело,19,2)),Число(Сред(ТЗ.Тело,22,2)),00);

                    конецесли;

//                    
                    дРС.Автор=ТекПользователь;

                    СтрдРС=дРС.ТабличнаяЧасть1.Добавить();

                    Сумма=0;
                    Сумма=Сред(СтрТЗ.Тело,поз2+13);
                    поз1=СтрНайти(Сумма,"р ");
                    если поз1>0 тогда    
                        Сумма=Лев(Сумма,поз1-1);                
                    конецесли;
//                    
//                    
                    СтрдРС.Сумма=Число(Сумма);
                    дРС.ИСумма=Число(Сумма);
//                    
                    СтрдРС.СтатьяРасхода=СР.Ссылка;
                    
                    дРС.Направление=Перечисления.Направление.Списание;
//                    

//                    
                    Касса=Справочники.Кассы.НайтиПоРеквизиту("Карта",сред(СтрТЗ.Тело,5,4));
                    Если ЗначениеЗаполнено(Касса) тогда

                        дРС.Касса=Касса;
                    конецесли;
                    СтрТЗ.Тело=Лев(СтрТЗ.Тело,поз3-1);
                    СтрТЗ.Тело=Сред(СтрТЗ.Тело,поз2+13);
                    СтрТЗ.Тело=Сред(СтрТЗ.Тело,поз1+2);
                    СтрдРС.Комментарий=СтрТЗ.Тело;
                    
                    дРС.Записать(РежимЗаписиДокумента.Проведение,РежимПроведенияДокумента.Неоперативный);

                    Сообщить(дРС);
                иначе
                    
                    Если Врег(Лев(СокрЛП(СтрТЗ.Тело),7))="БАЛАНС " тогда    //Отправляем баланс дилера, отправившего запрос
                        Тел=Справочники.Телефоны.НайтиПоНаименованию(Сред(ТЗ.Тема,6,12),Истина);

                        Если ЗначениеЗаполнено(Тел) тогда

                            Пар.Очистить();
                            км=Число(СокрЛП(Сред(СокрЛП(СтрТЗ.Тело),8)));

                            Если НЕ ЗначениеЗаполнено(км) тогда
                                км=1;
                            конецесли;

                            СтрПар=Пар.Добавить();
                            СтрПар.Наименование="ДатаНач";
                            СтрПар.Значение=ТекущаяДата()-км*30;
                            СтрПар=Пар.Добавить();
                            СтрПар.Наименование="ДатаКон";
                            СтрПар.Значение=ТекущаяДата();
                            СтрПар=Пар.Добавить();
                            СтрПар.Наименование="Контрагент";
                            СтрПар.Значение=Тел.Владелец;
                            СтрПар=Пар.Добавить();
                            СтрПар.Наименование="Отправить";
    
                        конецесли;
                    конецесли;                                          
                конецесли;
                Для каждого СтрТЗПисьма из ТЗПисьма Цикл

                    ЭлСпрП=Справочники.Письма.СоздатьЭлемент();

                    ЭлСпрП.УстановитьНовыйКод();

                    ЭлСпрП.Наименование=СтрТЗПисьма.Наименование;

                    ЭлСпрП.Записать();
                конеццикла;
                ТЗПисьма.Очистить();
                если ВКкс<>Индекс тогда

                    СтрТЗ=ТЗ.Добавить();
                    СтрТЗ.Пометка=1;
                    СтрТЗ.От=ВК.ИмяОтправителя+"<"+ВК.Отправитель.Адрес+">";
                    СтрТЗ.Тема=ВК.Тема;
                    СтрТЗ.Кому=ВК.Получатели[0].Адрес;
                    СтрТЗ.MessageID="<"+СокрЛП(ВК.ИдентификаторСообщения)+">";
                    Если ВК.CC.Количество()>0 тогда
                        СтрТЗ.Копия=ВК.CC[0].Адрес;
                    КонецЕсли;    
                    СтрТЗ.Аттачмент=ВК.Вложения;
                    СтрТЗ.ТипПисьма="";
                    СтрТЗ.Кодировка=ВК.Кодировка;
                    СтрТЗ.Тело=СокрЛП(Итог);
                    СтрТЗ.ИДПисьмаНаСервере=ВК.Идентификатор[0];
                    СтрТЗ.Тело=СокрЛП(Итог);
                конецесли;
            иначеесли  ((Лев(СтрТЗ.Тело,4)="VISA")или (Лев(СтрТЗ.Тело,4)="ECMC"))и(Найти(СокрЛП(Итог),"ОТКАЗ")=0) тогда
                СтрТЗ.Тело=СтрТЗ.Тело+СокрЛП(Итог);
            Конецесли;
            СтрТЗПисьма=ТЗПисьма.Добавить();
            СтрТЗПисьма.Наименование="<"+СокрЛП(ВК.ИдентификаторСообщения)+">";
        конецесли;        
    КонецЦикла;
    ТЗ.Удалить(0);
    Почта.Отключиться();
КонецПроцедуры


А это тексты сообщений:
Сбербанк- Сбербанк Онлайн. Иван Иванович И. перевел(а) Вам 5555.00 RUB. Сообщение: "********"

--
Received: Wed Nov 15 11:09:12 GMT+03:00 2017



Тинькоф- Vhodyaschiy platezh. Summa 6,666.00 RUB. Otpravitel Individualnyi predprinimatel Sereev Sergey Sergeevitch. 15.11.2017. Tinkoff.ru

--
Received: Wed Nov 15 10:18:51 GMT+03:00 2017
1 prilforreal
 
15.11.17
11:49
(0) Сберовские сообщения сшиваются из 2х, с тиньковым такого не нужно

2е сообщение:
VISA**** 15.11.17 11:07 зачисление 5555р Баланс: ****.38р

--
Received: Wed Nov 15 11:08:44 GMT+03:00 2017
2 SeregaMW
 
15.11.17
11:57
Все элементарно, включай отладчик и разбирай свое сообщение на данные по аналогии с твоим листингом.
Вдумчиво смотри и разбирайся в логике функции, тут за тебя ни кто писать не будет.

Если какие то куски кода не понятны спрашивай!
3 prilforreal
 
15.11.17
12:04
(2) Спасибо!)
Не ясен вот этот кусок:

ВКкс=Письма.Количество();
    Для Индекс=0 По ВКкс Цикл
        Итог="";
        флаг=0;
        
        если ВКкс<>Индекс тогда
            ВК=Письма.Получить(Индекс);
            если НРЕГ(сокрлп(ВК.Кодировка))<>"utf-8" тогда
            стр="";
            Для каждого ТекстПисьма из ВК.Тексты цикл
                Стр=Стр+" "+ТекстПисьма.Текст;
            КонецЦикла;    
                
                Длина=СтрДлина(Стр);
        
                Для Н=1 По Длина Цикл
                    Знак=Сред(Стр,Н,1);
                    Код=КодСимвола(Знак,1);
                    Если Код<128 Тогда
                        Итог=Итог+Знак;
                    ИначеЕсли (Код>=128)И(Код<192) Тогда
                        
                    Иначе
                        Н=Н+1;
                        Знак2=Сред(Стр,Н,1);
                        Код2=КодСимвола(Знак2,1);
                        Если Код=208 Тогда
                            Если Код2=129 Тогда
                                Итог=Итог+"Ё";
                            Иначе
                                Итог=Итог+Символ(КодСимвола("А",1)+Код2-144);
                            КонецЕсли;                                                      
                        ИначеЕсли Код=209 Тогда
                            Если Код2=145 Тогда
                                Итог=Итог+"ё";
                            Иначе
                                Итог=Итог+Символ(КодСимвола("р",1)+Код2-128);
                            КонецЕсли;
                        КонецЕсли;
                    КонецЕсли;
                КонецЦикла;

Перед ним все ясно, подключение к почте, проверка кодировки на utf-8, создание таблицы значений, колонок в ней. После этого куска также понятно что происходит разбор текста сообщения, но этот кусок хоть убейте понять не могу(
4 prilforreal
 
15.11.17
12:06
(2) Также обработка обращается к справочнику письма, элементы которого имеют вид :*код*-*наименование* (Пример:*38204*-*<1108544032.35.1492057594165@localhost>*)
5 volfy
 
15.11.17
12:07
на выходе то что?
6 volfy
 
15.11.17
12:07
в переменной стр и Итог
7 Йохохо
 
15.11.17
12:11
(3) переколировка аски вин1251
http://book.itep.ru/10/ascii.htm
8 volfy
 
15.11.17
12:15
(7) верно говорит
если НРЕГ(сокрлп(ВК.Кодировка))<>"utf-8" тогда
Если кодировка не та, то меняет символы.
9 prilforreal
 
15.11.17
12:15
(5) Говорю же с итогом не могу понять, а в строке тз заполненные колонки отправитель, тело сообщения, кодировка итд..
10 prilforreal
 
15.11.17
12:19
(7) Спасибо!
(8) Это мне ясно, но вот этот кусочек:
Для Н=1 По Длина Цикл
                    Знак=Сред(Стр,Н,1);
                    Код=КодСимвола(Знак,1);
                    Если Код<128 Тогда
                        Итог=Итог+Знак;
                    ИначеЕсли (Код>=128)И(Код<192) Тогда
                        
                    Иначе
                        Н=Н+1;
                        Знак2=Сред(Стр,Н,1);
                        Код2=КодСимвола(Знак2,1);
                        Если Код=208 Тогда
                            Если Код2=129 Тогда
                                Итог=Итог+"Ё";
                            Иначе
                                Итог=Итог+Символ(КодСимвола("А",1)+Код2-144);
                            КонецЕсли;                                                      
                        ИначеЕсли Код=209 Тогда
                            Если Код2=145 Тогда
                                Итог=Итог+"ё";
                            Иначе
                                Итог=Итог+Символ(КодСимвола("р",1)+Код2-128);

Вводит в недоумение
11 SeregaMW
 
15.11.17
12:33
(10) Да особо не парься это перекодировка текста в utf. Разбирайся дальше.
12 Йохохо
 
15.11.17
12:44
(10) похоже это разбор после url-encoded толькол не очень корректный, % пролезает
13 Йохохо
 
15.11.17
12:49
U+0401    Ё    %d0%81    
Если Код=208 Тогда //d0
                            Если Код2=129 Тогда //81
                                Итог=Итог+"Ё";
14 prilforreal
 
15.11.17
15:32
Кажется подразобрался, написал условия подхлдящие под нужные смс. Подскжите будьте добры, как Сред(,,) с конца текста делать?) И как убрать из суммы лишние символы 10,200.50 RUB?
15 SeregaMW
 
15.11.17
16:25
(14)
Можно обратным циклом собирать строку или определить конкретный промежуток символов с помощью поиска
Сред(Стр, Найти(Стр,".") Найти(Стр,","))
Убрать лишние символы СтрЗаменить()
16 prilforreal
 
15.11.17
16:30
(15) Спасибо!