Здесь я хотел написать много букв про креативные ИТ подходы во многих компаниях мира, где на каждый бизнес-чих бегут покупать новую ИТ систему вместо того, чтобы доработать существующую ERP, и создать интегрированную платформу вместо свалки из систем, интеграционных потоков и так далее. Но не буду. Буду позже, когда совсем накипит. Сегодня мы делаем мини-контактный центр для HR. У SAP есть стандартное решение SAP Employee Iteraction Center и SAP Shared Service Framework. Второе лучше первого. Но оба стоят денег.
В стандарте SAP нет такой простой штуки, как принять входящее электронное сообщение и отправить его в поток операций, где консультант сможет проанализировать сообщение и выстроить правильную маршрутизацию. Есть кусочные решения для отдельных блоков ALM, SRM, EIC, SOLMAN, еще чего-то.
Попробуем сделать свое решение за пять минут, чтобы мы могли получить электронное письмо, и запустить поток операций на выполнение, приложив к нему это самое письмо. Своего рода входящая почта в SAP HR для HR. Дальше коллеги из HR включат свою фантазию и придумают ей применение.
Настройка приема почты в самой системе осуществляется элементарно за 5 минут. Для этого читаем ноту 455140 . Там пара параметров в профиле, перезагрузка системы, настройка в SCOT и все. После этого вы сможете получать почту снаружи для ваших логинов. То есть, можно отправить почту с vasya@pupkin.com на *@potceluev.com.
Да, не забываем, что для этого ваш САП сервер должен быть прописан в DNS корпоративной сети. Это уже вне САП.
Существует три способа реализовать нашу задачу.
- Создать расширение для обработки писем для транзакции SO50 через наследование интерфейса IF_INBOUND_EXIT_BCS BCS: Exit for Inbound Processing
- Создать BOR объект (SWO1) через наследование интерфейса IFRECEIVE Receive Office objects. Указать его получателем в транзакции SO28
- Создать программку, которая в фоне будет опрашивать почтовый ящик и обрабатывать письма
Давайте начнем с первого способа. В se24 создаем класс с реализацией интерфейса IF_INBOUND_EXIT_BCS и интерфейса IF_WORKFLOW. Второй нужен для того, чтобы мы могли инициировать с его помощью запуск потока операций с нужным нам событием. Также создаем событие с параметрами SENDER_ADDRESS и BODY_TEXT. Мы будем брать эти два параметра из входящего письма и передавать их в поток операций.
Исходник класса внизу. Там всего ничего, поэтому быстро разберетесь.
Создаем простой поток операций в транзакции SWDD.
В транзакции SWETYPV прописывам связку события с классом:
Теперь осталось прописать наш класс в SO50, чтобы он вызывался, когда приходит входящая почта.
Проверяем:
А в транзакции SWIA смотрим вызов потока:
15.09.2017 Display Class 1 -------------------------------------------------------------------------------- class-pool . INCLUDE <cntn02>. class ZCL_SMTP_WORKFLOW definition public final create public . public section. type-pools SX . interfaces IF_INBOUND_EXIT_BCS . interfaces BI_OBJECT . interfaces BI_PERSISTENT . interfaces IF_WORKFLOW . events MAIL_RECEIVED exporting value(SENDER_ADDRESS) type STRING value(BODY_TEXT) type STRING . protected section. private section. endclass. "ZCL_SMTP_WORKFLOW definition class ZCL_SMTP_WORKFLOW implementation. method IF_INBOUND_EXIT_BCS~CREATE_INSTANCE. DATA: lcl_OBJECT type ref to ZCL_SMTP_WORKFLOW. CREATE OBJECT lcl_OBJECT. RO_REF = lcl_OBJECT. endmethod. method IF_INBOUND_EXIT_BCS~PROCESS_INBOUND. DATA: l_sender_addr TYPE string, l_body_text TYPE string, lo_sender TYPE REF TO IF_SENDER_BCS, l_uuid TYPE SYSUUID_C32, lv_objtype TYPE sibftypeid, lv_event TYPE sibfevent, lv_objkey TYPE sibfinstid, lr_event_parameters TYPE REF TO if_swf_ifs_parameter_container. lo_sender = io_sreq->get_sender( ). l_sender_addr = lo_sender->address_string( ). TRY. CALL METHOD CL_SYSTEM_UUID=>IF_SYSTEM_UUID_STATIC~CREATE_UUID_C32 RECEIVING UUID = l_uuid. CATCH CX_UUID_ERROR . ENDTRY. lv_objtype = 'ZCL_SMTP_WORKFLOW'. lv_event = 'MAIL_RECEIVED'. MOVE l_uuid TO lv_objkey. CALL METHOD cl_swf_evt_event=>get_event_container EXPORTING im_objcateg = cl_swf_evt_event=>mc_objcateg_cl im_objtype = lv_objtype im_event = lv_event RECEIVING re_reference = lr_event_parameters. TRY. CALL METHOD lr_event_parameters->set EXPORTING name = 'SENDER_ADDRESS' value = l_sender_addr. CALL METHOD lr_event_parameters->set EXPORTING name = 'BODY_TEXT' value = l_body_text. CATCH cx_swf_cnt_cont_access_denied. CATCH cx_swf_cnt_elem_access_denied . CATCH cx_swf_cnt_elem_not_found . CATCH cx_swf_cnt_elem_type_conflict . CATCH cx_swf_cnt_unit_type_conflict . CATCH cx_swf_cnt_elem_def_invalid . CATCH cx_swf_cnt_container . ENDTRY. TRY. CALL METHOD cl_swf_evt_event=>raise EXPORTING im_objcateg = cl_swf_evt_event=>mc_objcateg_cl im_objtype = lv_objtype im_event = lv_event im_objkey = lv_objkey im_event_container = lr_event_parameters. CATCH cx_swf_evt_invalid_objtype . CATCH cx_swf_evt_invalid_event . ENDTRY. COMMIT WORK. e_retcode = if_inbound_exit_bcs=>gc_terminate. endmethod. method BI_PERSISTENT~FIND_BY_LPOR. create object result TYPE ZCL_SMTP_WORKFLOW. endmethod. method BI_PERSISTENT~LPOR. DATA: lpor TYPE sibflpor. lpor-catid = 'CL'. lpor-typeid = 'ZCL_SMTP_WORKFLOW'. lpor-instid = '1'. result = lpor. endmethod. method BI_PERSISTENT~REFRESH. endmethod. method BI_OBJECT~DEFAULT_ATTRIBUTE_VALUE. endmethod. method BI_OBJECT~EXECUTE_DEFAULT_METHOD. endmethod. method BI_OBJECT~RELEASE. endmethod. endclass. "ZCL_SMTP_WORKFLOW implementation
2 комментария
Calm
Круто! 🙂
VirVit
А то 🙂