matinal:SAP ABAP 关于SAP系统中如何集成HTTPS的若干功能总结篇【第三篇】

🚀欢迎来到本文🚀
🍉个人简介:matinal,目前职业是IT行业,一个正在慢慢前行的普通人。
🏀系列专栏:涵盖SAP各模块,Python,Excel,人工智能等
💡 其他专栏:一些平时学习的技术,感兴趣的小伙伴可以看看。

🍔公众号:matinal
🎁希望各位→点赞👍 + 收藏⭐️ + 留言📝 ​
⛱️万物从心起,心动则万物动🏄‍♂️


前言:SAP ABAP 关于SAP系统中如何集成HTTPS的若干功能总结篇,这是第三篇。本篇主要介绍SAP中集成http服务,所以,如果你了解并熟知,请略过本篇。

🦙(工作遇到傻逼,千万要远离。道路千万条,远离傻逼第一条)


1990年互联网诞生之初,就已经开始用超文本传输协议 HTTP 传输数据,这也是为什么现在网页地址都是以 http 开头的原因。但是HTTP协议传输数据是明文传输,任意的人抓包就能看到传输的数据,这显然不安全。1994年,Netscape 公司用加密协议增加了 HTTP,开始在 HTTP 的基础上加入 SSL 即安全套接层(Secure Socket Layer)。称为 "HTTP over SSL" 或者 "HTTP Secure",也就是我们现在熟知的 HTTPS。

HTTPS 其实是一个“非常简单”的协议,RFC 文档很小,只有短短的 7 页,里面规定了新的协议名“https”,默认端口号 443,至于其他的什么请求 - 应答模式、报文结构、请求方法、URI、头字段、连接管理等等都完全沿用 HTTP,没有任何新的东西。

也就是说,除了协议名“http”和端口号 80 这两点不同,HTTPS 协议在语法、语义上和 HTTP 完全一样,优缺点也“照单全收”(当然要除去“明文”和“不安全”)。 

HTTP 协议一般指 HTTP(超文本传输协议)。

超文本传输协议(英语:HyperText Transfer Protocol,缩写:HTTP)是一种用于分布式、协作式和超媒体信息系统的应用层协议,是因特网上应用最为广泛的一种网络传输协议,所有的 WWW 文件都必须遵守这个标准。

HTTP 是为 Web 浏览器与 Web 服务器之间的通信而设计的,但也可以用于其他目的。

HTTP 是一个基于 TCP/IP 通信协议来传递数据的(HTML 文件、图片文件、查询结果等)。

下面进入正文


前言

1、 钉钉API文档说明: https://dingdoc.dingtalk.com/doc#/serverapi2/ul33mm.

2、请求地址: https://oapi.dingtalk.com/attendance/listRecordaccess_token=ACCESS_TOKEN.


一、准备工作

1.获取AppKey&AppSecret(每家供应商可能不一样)
2.获取token(拼接成url)
3.根据URL生成HTTP代理
4.设置 HTTP 版本
5.将HTTP代理设置GET方法
6.发送HTTP请求
7.获取返回的数据
8.关闭HTTP链接
9.将字符串转为abap结构类型变量中


二、检查安全证书

在调用钉钉API前 有次SSL检查,若SAP没有证书则会报错

检查客户GUI,发现

这个没有创建,图中是我创建的

然后重启ICM

三、获取安全证书

在重启ICM之前,需要获取钉钉的证书,导入到sap.
证书获取:
到钉钉的网站按F12
F12打开Chrome开发者工具,Security标签页,View certificate,点击view detais,选择Copy to file.

*&---------------------------------------------------------------------*
*& Report ZMATINAL
*&---------------------------------------------------------------------*
*&
*&---------------------------------------------------------------------*
REPORT zmatinal.

TABLES: pernr.",zthrpt006_log,zthrpt006_2_log.  mark @20201013
INFOTYPES: 0000,0001,0105,0007.

PARAMETERS: p_job TYPE char1 DEFAULT 'X' NO-DISPLAY.

TYPES: BEGIN OF ty_department,"部门列表
         id   TYPE string,
         name TYPE string,
       END OF ty_department.
DATA: gt_department TYPE TABLE OF ty_department,
      gs_department TYPE ty_department.

TYPES: BEGIN OF ty_userlist, "部门成员详细信息
         userid TYPE string,
         name   TYPE string,
         email  TYPE string,
       END OF ty_userlist.
DATA: gt_userlist TYPE TABLE OF ty_userlist,
      gs_userlist TYPE ty_userlist.

*DATA:gt_zdepfromding_log TYPE TABLE OF zdepfromding_log,     mark @20201013
*     gs_zdepfromding_log TYPE zdepfromding_log.

TYPES: BEGIN OF ty_ptresult, "员工考勤数据
         index          TYPE i,
         pernr          TYPE pernr_d, "员工号
         ename          TYPE p0001-ename,  "姓名
         userid         TYPE string, "钉钉用户ID
         email          TYPE p0105-usrid, "邮箱

         plantime       TYPE uzeit,
         createtime     TYPE uzeit,
         modifytime     TYPE uzeit,

         islegal        TYPE char1, "是否合法
         locationresult TYPE string, "位置结果

         begda          TYPE begda,
         endda          TYPE endda,
         workdatum      TYPE datum,         "工作日
         zdklx          TYPE retyp,     "打卡类型
         zbase          TYPE uzeit,   "基准时间
         zdktime        TYPE uzeit, "实际打卡时间
         zresult(40)    TYPE c, "时间结果
         zmins(40)      TYPE c,   "迟到分钟数

************************钉钉原始数据*****************************
         id             TYPE string, "钉钉考勤结果唯一标识ID
         workdate       TYPE string, "工作日
         checktype      TYPE string, "考勤类型(OnDuty:上班,OffDuty:下班)
         timeresult     TYPE string, "时间结果(Normal:正常;Early:早退; Late:迟到;SeriousLate:严重迟到;NotSigned:未打卡)
         basechecktime  TYPE string, "计算迟到和早退,基准时间
         planchecktime  TYPE string, "排班打卡时间
         userchecktime  TYPE string, "实际打卡时间
         gmtcreate      TYPE string, "创建时间
         gmtmodified    TYPE string, "修改时间
       END OF ty_ptresult.
DATA: gt_ptresult TYPE TABLE OF ty_ptresult,
      gs_ptresult TYPE ty_ptresult.

DATA: gt_ptresult1 TYPE TABLE OF ty_ptresult,
      gs_ptresult1 TYPE ty_ptresult.
DATA: gt_ptresult2 TYPE TABLE OF ty_ptresult,
      gs_ptresult2 TYPE ty_ptresult.

TYPES: BEGIN OF ty_person, "员工基础公共信息
         index  TYPE i,
         pernr  TYPE pernr_d,
         ename  TYPE p0001-ename,
         userid TYPE string,    "钉钉用户ID
         email  TYPE p0105-usrid, "邮箱
       END OF ty_person.
DATA: gt_person TYPE TABLE OF ty_person,
      gs_person TYPE ty_person.

TYPES: BEGIN OF ty_post, "post结构体信息
         post TYPE string,
       END OF ty_post.
DATA: gt_post TYPE TABLE OF ty_post,
      gs_post TYPE ty_post.

DATA: gv_begda TYPE sy-datum,
      gv_endda TYPE sy-datum.
DATA: gv_post TYPE string.
DATA: gv_index TYPE i.
*DATA: gt_log TYPE TABLE OF zthrpt006_log,      "MARK 20201013
*      gs_log TYPE zthrpt006_log.
DATA: gv_token TYPE string.

CONSTANTS:
  cns_corpid     TYPE string VALUE 'dingXXXXXXXXXXXXXXXXX',    "corpid
  cns_corpsecret TYPE string VALUE 'bKXXXXXXXXXXXXXXXXX'.  

INITIALIZATION.
  pnpbegda = sy-datum - 1.
  pnpendda = pnpbegda.


START-OF-SELECTION.
  PERFORM f_init.

GET pernr.
  PERFORM f_get_data.

END-OF-SELECTION.
  PERFORM f_pro_data.
  PERFORM f_ptrecord_from_ding TABLES gt_ptresult
                                   USING gv_token.
  PERFORM f_pro_detail_data.
  IF p_job = 'X'.
*    PERFORM f_ins_9401.    mark 20201013
  ENDIF.
*&---------------------------------------------------------------------*
*& Form F_INIT
*&---------------------------------------------------------------------*
*& text
*&---------------------------------------------------------------------*
*& -->  p1        text
*& <--  p2        text
*&---------------------------------------------------------------------*
FORM f_init .
  DATA: lt_department TYPE TABLE OF ty_department,
        ls_department TYPE ty_department,
        lt_userlist   TYPE TABLE OF ty_userlist,
        ls_userlist   TYPE ty_userlist.

  gv_begda = pn-begda.
  gv_endda = pn-endda.

  DATA ddate TYPE datum.

  ddate = pn-begda - 10.


  "获取CIFI-token
  CLEAR gv_token.
  PERFORM f_token_from_ding USING cns_corpid cns_corpsecret
                                          CHANGING gv_token.
  IF gv_token IS INITIAL.
    MESSAGE '获取token失败' TYPE 'E'.
  ENDIF.

  "获取部门列表
  REFRESH lt_department[].
  PERFORM f_department_from_ding TABLES gt_department
                                     USING gv_token.
  IF gt_department IS NOT INITIAL.
    SORT gt_department ASCENDING BY id name.
  ELSE.
    MESSAGE '获取部门列表失败' TYPE 'E'.
  ENDIF.

  "获取部门成员详情
  REFRESH lt_userlist[].
  PERFORM f_userlist_from_ding TABLES gt_userlist
                                   USING gv_token.

  CLEAR gs_userlist.

  IF gt_userlist IS NOT INITIAL.
    DELETE gt_userlist WHERE email IS INITIAL.
    DELETE ADJACENT DUPLICATES FROM gt_userlist COMPARING userid name email. "删除相同人员
    SORT gt_userlist ASCENDING BY userid name.
  ELSE.
    MESSAGE '获取部门成员详情失败' TYPE 'E'.
  ENDIF.
ENDFORM.
*&---------------------------------------------------------------------*
*& Form F_GET_DATA_FROM_DING
*&---------------------------------------------------------------------*
*& text
*&---------------------------------------------------------------------*
*      -->P_GT_DEPARTMENT  text
*&---------------------------------------------------------------------*
FORM f_department_from_ding TABLES t_department STRUCTURE gs_department
                                USING i_token TYPE string.
  DATA: lr_http_client_01 TYPE REF TO if_http_client, "获取部门列表
        lr_initial_01     TYPE REF TO cx_sy_ref_is_initial,
        lr_format_error   TYPE REF TO cx_xslt_format_error.

  DATA: lv_message TYPE bapireturn1-message,
        lv_return  TYPE i.

  DATA: lv_url_01    TYPE string, "获取部门列表url
        lv_result_01 TYPE string. "获取部门列表


  CONCATENATE 'https://oapi.dingtalk.com/department/list?access_token='
              i_token
              INTO lv_url_01.

  "根据URL生成HTTP代理
  CALL METHOD cl_http_client=>create_by_url(
    EXPORTING
      url                = lv_url_01
    IMPORTING
      client             = lr_http_client_01
    EXCEPTIONS
      argument_not_found = 1
      plugin_not_active  = 2
      internal_error     = 3
      OTHERS             = 4 ).

*设置 HTTP 版本
  lr_http_client_01->request->set_version( if_http_request=>co_protocol_version_1_0 ).

  CHECK lr_http_client_01 IS NOT INITIAL.
*将HTTP代理设置GET方法
  lr_http_client_01->request->set_method( if_http_request=>co_request_method_get ).

  TRY.
      "发送HTTP请求
      CALL METHOD lr_http_client_01->send
        EXCEPTIONS
          http_communication_failure = 1
          http_invalid_state         = 2.

      CALL METHOD lr_http_client_01->receive
        EXCEPTIONS
          http_communication_failure = 1
          http_invalid_state         = 2
          http_processing_failed     = 3.

    CATCH cx_sy_ref_is_initial INTO lr_initial_01.
      lv_message = lr_initial_01->if_message~get_text( ).
      MESSAGE lv_message TYPE 'E'.
  ENDTRY.

* 获取返回的数据
  CLEAR lv_result_01.
  lv_result_01 = lr_http_client_01->response->get_cdata( ).

*关闭HTTP链接
  lr_http_client_01->close( ).

  REPLACE ALL OCCURRENCES OF '"ID"'     IN lv_result_01
                        WITH  '"ID"'     IGNORING CASE.
  REPLACE ALL OCCURRENCES OF '"NAME"'     IN lv_result_01
                        WITH  '"NAME"'     IGNORING CASE.
  REPLACE ALL OCCURRENCES OF '"errmsg"'     IN lv_result_01
                        WITH  '"ERRMSG"'     IGNORING CASE.
  REPLACE ALL OCCURRENCES OF '"department"'     IN lv_result_01
                        WITH  '"DEPARTMENT"'     IGNORING CASE.
  REPLACE ALL OCCURRENCES OF '"errcode"'     IN lv_result_01
                        WITH  '"ERRCODE"'     IGNORING CASE.

*将字符串转为abap结构类型变量中
  TRY .
      REFRESH gt_department[].
      CALL TRANSFORMATION id SOURCE XML lv_result_01
          RESULT department = t_department[].
    CATCH cx_xslt_format_error INTO lr_format_error .
      lv_message = lr_format_error->get_text( ).
  ENDTRY.

ENDFORM.
*&---------------------------------------------------------------------*
*& Form F_USERLIST_FROM_DING
*&---------------------------------------------------------------------*
*& text
*&---------------------------------------------------------------------*
*      -->P_LT_USERLIST  text
*      -->P_LV_OFFSET  text
*      -->P_LV_SIZE  text
*&---------------------------------------------------------------------*
FORM f_userlist_from_ding TABLES t_userlist STRUCTURE gs_userlist
                               USING i_token TYPE string.
  DATA: lt_userlist TYPE TABLE OF ty_userlist.
  DATA: lr_http_client_02 TYPE REF TO if_http_client, "获取部门列表
        lr_initial_02     TYPE REF TO cx_sy_ref_is_initial,
        lr_format_error   TYPE REF TO cx_xslt_format_error.

  DATA: lv_message TYPE bapireturn1-message,
        lv_return  TYPE i.

  DATA: lv_url_02    TYPE string, "获取部门成员详情
        lv_result_02 TYPE string. "获取部门成员详情
  DATA: l_lines   TYPE i,
        lv_offset TYPE p,
        l_offset  TYPE string.

  LOOP AT gt_department INTO gs_department .
    lv_offset = 0.
    DO .
      l_offset = lv_offset.
      CONCATENATE 'https://oapi.dingtalk.com/user/list?access_token='
                  i_token
                  '&department_id='
                  gs_department-id
                  '&offset='
                  l_offset
                  '&size=100'
                  INTO lv_url_02.
      CONDENSE lv_url_02 NO-GAPS.
      "根据URL生成HTTP代理
      CALL METHOD cl_http_client=>create_by_url(
        EXPORTING
          url                = lv_url_02
        IMPORTING
          client             = lr_http_client_02
        EXCEPTIONS
          argument_not_found = 1
          plugin_not_active  = 2
          internal_error     = 3
          OTHERS             = 4 ).

*设置 HTTP 版本
      lr_http_client_02->request->set_version( if_http_request=>co_protocol_version_1_0 ).

      CHECK lr_http_client_02 IS NOT INITIAL.
*将HTTP代理设置GET方法
      lr_http_client_02->request->set_method( if_http_request=>co_request_method_get ).

      TRY.
          "发送HTTP请求
          CALL METHOD lr_http_client_02->send
            EXCEPTIONS
              http_communication_failure = 1
              http_invalid_state         = 2.

          CALL METHOD lr_http_client_02->receive
            EXCEPTIONS
              http_communication_failure = 1
              http_invalid_state         = 2
              http_processing_failed     = 3.

        CATCH cx_sy_ref_is_initial INTO lr_initial_02.
          lv_message = lr_initial_02->if_message~get_text( ).
          MESSAGE lv_message TYPE 'E'.
      ENDTRY.

* 获取返回的数据
      CLEAR lv_result_02.
      lv_result_02 = lr_http_client_02->response->get_cdata( ).

*关闭HTTP链接
      lr_http_client_02->close( ).

      REPLACE ALL OCCURRENCES OF '"USERID"'      IN lv_result_02
                            WITH  '"USERID"'     IGNORING CASE.
      REPLACE ALL OCCURRENCES OF '"NAME"'        IN lv_result_02
                            WITH  '"NAME"'       IGNORING CASE.
      REPLACE ALL OCCURRENCES OF '"EMAIL"'       IN lv_result_02
                            WITH  '"EMAIL"'      IGNORING CASE.
      REPLACE ALL OCCURRENCES OF '"errmsg"'      IN lv_result_02
                            WITH  '"ERRMSG"'     IGNORING CASE.
      REPLACE ALL OCCURRENCES OF '"userlist"'    IN lv_result_02
                            WITH  '"USERLIST"'   IGNORING CASE.
      REPLACE ALL OCCURRENCES OF '"errcode"'     IN lv_result_02
                            WITH  '"ERRCODE"'    IGNORING CASE.
      REPLACE ALL OCCURRENCES OF '"hasMore"'     IN lv_result_02
                            WITH  '"HASMORE"'    IGNORING CASE.

*将字符串转为abap结构类型变量中
      TRY .
          REFRESH: lt_userlist[].
          CALL TRANSFORMATION id SOURCE XML lv_result_02
              RESULT userlist = lt_userlist[].
        CATCH cx_xslt_format_error INTO lr_format_error .
          lv_message = lr_format_error->get_text( ).
      ENDTRY.

      CLEAR l_lines.
      l_lines = lines( lt_userlist ).

      DELETE lt_userlist WHERE email IS INITIAL.
      APPEND LINES OF lt_userlist TO t_userlist.

      IF l_lines GT 0 AND l_lines MOD '100' EQ 0 .
        lv_offset = lv_offset + 100.
      ELSE.
        EXIT..
      ENDIF.
    ENDDO.
    CLEAR gs_department.
  ENDLOOP.

ENDFORM.
*&---------------------------------------------------------------------*
*& Form F_GET_DATA
*&---------------------------------------------------------------------*
*& text
*&---------------------------------------------------------------------*
*& -->  p1        text
*& <--  p2        text
*&---------------------------------------------------------------------*
FORM f_get_data .
  rp_provide_from_last p0001 space pn-begda pn-endda.
  rp_provide_from_last p0105 '01' pn-begda pn-endda.
  IF p0105-usrid IS NOT INITIAL.

    gs_person-pernr = p0001-pernr.
    gs_person-ename = p0001-ename.
    gs_person-email = p0105-usrid.
    TRANSLATE gs_person-email TO LOWER CASE.
    CLEAR gs_userlist.
    READ TABLE gt_userlist INTO gs_userlist WITH KEY email = gs_person-email.
    IF gs_userlist-userid IS NOT INITIAL .
      gs_person-userid = gs_userlist-userid.
      gv_index = gv_index + 1.
      gs_person-index = gv_index.

      APPEND gs_person TO gt_person.
    ENDIF.
    CLEAR gs_person.
  ENDIF.
ENDFORM.
*&---------------------------------------------------------------------*
*& Form F_PTRECORD_FROM_DING
*&---------------------------------------------------------------------*
*& text
*&---------------------------------------------------------------------*
*      -->P_GT_PTRESULT  text
*&---------------------------------------------------------------------*
FORM f_ptrecord_from_ding TABLES t_ptresult STRUCTURE gs_ptresult
                              USING  i_token TYPE string.

  DATA: lr_http_client_03 TYPE REF TO if_http_client, "获取部门列表
        lr_initial_03     TYPE REF TO cx_sy_ref_is_initial,
        lr_format_error   TYPE REF TO cx_xslt_format_error.

  DATA: lv_message TYPE bapireturn1-message,
        lv_return  TYPE i.
  DATA: lt_ptresult TYPE TABLE OF ty_ptresult,
        ls_ptresult TYPE ty_ptresult.

  DATA: lv_url_03    TYPE string, "获取员工考勤数据
        lv_result_03 TYPE string. "获取员工考勤数据
  DATA: lv_offset TYPE p,
        l_offset  TYPE string.
  DATA: lv_post   TYPE string,
        lv_len    TYPE i,
        lv_gather TYPE string. "50个userid 为一组
  DATA: lv_head_name  TYPE string,
        lv_head_value TYPE string.

  LOOP AT gt_post INTO gs_post.
    "    CLEAR gs_zdkfromding_log.      mark 20201013

    lv_head_name = 'Content-Type'.
    lv_head_value = 'application/json; charset=utf-8'.

    CONCATENATE 'https://oapi.dingtalk.com/attendance/listRecord?access_token='
                i_token
                INTO lv_url_03.

*    gs_zdkfromding_log-begda = gv_begda.     mark 20201013
*    gs_zdkfromding_log-endda = gv_begda.
*    gs_zdkfromding_log-url = lv_url_03.

    "根据URL生成HTTP代理
    CALL METHOD cl_http_client=>create_by_url(
      EXPORTING
        url                = lv_url_03
      IMPORTING
        client             = lr_http_client_03
      EXCEPTIONS
        argument_not_found = 1
        plugin_not_active  = 2
        internal_error     = 3
        OTHERS             = 4 ).

*设置 HTTP 版本
    lr_http_client_03->request->set_version( if_http_request=>co_protocol_version_1_0 ).

    lr_http_client_03->propertytype_logon_popup = lr_http_client_03->co_enabled .

    "设置请求方法
    lr_http_client_03->request->set_method( if_http_entity=>co_request_method_post ).
*lr_http_client_03->request->set_method( 'POST' ).

    "设置头部
    CALL METHOD lr_http_client_03->request->set_header_field
      EXPORTING
        name  = lv_head_name
        value = lv_head_value.

    DATA: lv_date_end  TYPE sy-datum,
          lv_date_from TYPE string,
          lv_date_to   TYPE string.
    CONCATENATE gv_begda+0(4) '-' gv_begda+4(2) '-' gv_begda+6(2) INTO lv_date_from.

    CLEAR lv_date_end.
    lv_date_end = gv_endda + 1 ."加班到凌晨下班
    CONCATENATE lv_date_end+0(4) '-' lv_date_end+4(2) '-' lv_date_end+6(2) INTO lv_date_to.

    lv_gather = gs_post-post.
    CONCATENATE '{"userIds": '
              lv_gather
              ','
              '"checkDateFrom":'
              '"'
              lv_date_from
              ' 00:00:00",'
              '"checkDateTo":'
              '"'
              lv_date_to
              ' 05:00:00"}'
         INTO lv_post.

    lv_len = strlen( lv_post ).

    "    gs_zdkfromding_log-request = lv_post.    mark 20201013

    CALL METHOD lr_http_client_03->request->set_cdata
      EXPORTING
        data   = lv_post
        offset = 0
        length = lv_len.

    TRY.
        "发送HTTP请求
        CALL METHOD lr_http_client_03->send
          EXCEPTIONS
            http_communication_failure = 1
            http_invalid_state         = 2.

        CALL METHOD lr_http_client_03->receive
          EXCEPTIONS
            http_communication_failure = 1
            http_invalid_state         = 2
            http_processing_failed     = 3.

      CATCH cx_sy_ref_is_initial INTO lr_initial_03.
        lv_message = lr_initial_03->if_message~get_text( ).
        MESSAGE lv_message TYPE 'E'.
    ENDTRY.

* 获取返回的数据
    CLEAR lv_result_03.
    lv_result_03 = lr_http_client_03->response->get_cdata( ).

*关闭HTTP链接
    lr_http_client_03->close( ).

    "    gs_zdkfromding_log-response = lv_result_03.    mark 20201013
    "    APPEND gs_zdkfromding_log TO gt_zdkfromding_log.

    REPLACE ALL OCCURRENCES OF '"RECORDRESULT"'      IN lv_result_03
                          WITH  '"RECORDRESULT"'     IGNORING CASE.
    REPLACE ALL OCCURRENCES OF '"USERID"'      IN lv_result_03
                          WITH  '"USERID"'     IGNORING CASE.
    REPLACE ALL OCCURRENCES OF '"ID"'      IN lv_result_03
                          WITH  '"ID"'     IGNORING CASE.
    REPLACE ALL OCCURRENCES OF '"WORKDATE"'        IN lv_result_03
                          WITH  '"WORKDATE"'       IGNORING CASE.
    REPLACE ALL OCCURRENCES OF '"CHECKTYPE"'       IN lv_result_03
                          WITH  '"CHECKTYPE"'      IGNORING CASE.
    REPLACE ALL OCCURRENCES OF '"TIMERESULT"'      IN lv_result_03
                          WITH  '"TIMERESULT"'     IGNORING CASE.
    REPLACE ALL OCCURRENCES OF '"BASECHECKTIME"'    IN lv_result_03
                          WITH  '"BASECHECKTIME"'   IGNORING CASE.
    REPLACE ALL OCCURRENCES OF '"PLANCHECKTIME"'     IN lv_result_03
                          WITH  '"PLANCHECKTIME"'    IGNORING CASE.
    REPLACE ALL OCCURRENCES OF '"USERCHECKTIME"'     IN lv_result_03
                          WITH  '"USERCHECKTIME"'    IGNORING CASE.
    REPLACE ALL OCCURRENCES OF '"GMTCREATE"'     IN lv_result_03
                          WITH  '"GMTCREATE"'    IGNORING CASE.
    REPLACE ALL OCCURRENCES OF '"GMTMODIFIED"'     IN lv_result_03
                          WITH  '"GMTMODIFIED"'    IGNORING CASE.
    REPLACE ALL OCCURRENCES OF '"ISLEGAL"'     IN lv_result_03
                          WITH  '"ISLEGAL"'    IGNORING CASE.
    REPLACE ALL OCCURRENCES OF '"LOCATIONRESULT"'     IN lv_result_03
                          WITH  '"LOCATIONRESULT"'    IGNORING CASE.

*将字符串转为abap结构类型变量中
    TRY .
        REFRESH: lt_ptresult[].
        CALL TRANSFORMATION id SOURCE XML lv_result_03
            RESULT recordresult = lt_ptresult[].
      CATCH cx_xslt_format_error INTO lr_format_error .
        lv_message = lr_format_error->get_text( ).
    ENDTRY.


*    DELETE lt_ptresult WHERE islegal = 'N'.
    IF lt_ptresult IS NOT INITIAL.
      APPEND LINES OF lt_ptresult TO gt_ptresult.
    ENDIF.
    CLEAR gs_post.
  ENDLOOP.
*  DELETE gt_ptresult WHERE islegal = 'N'.
*  IF gt_zdkfromding_log IS NOT INITIAL.    mark 20201013
*    MODIFY zdkfromding_log FROM TABLE gt_zdkfromding_log.
*  ENDIF.
ENDFORM.
*&---------------------------------------------------------------------*
*& Form F_PRO_DATA
*&---------------------------------------------------------------------*
*& text
*&---------------------------------------------------------------------*
*& -->  p1        text
*& <--  p2        text
*&---------------------------------------------------------------------*
FORM f_pro_data .
  DATA: lv_beg TYPE i,
        lv_end TYPE i.

  lv_beg = 1 .
  lv_end = 50 .
  DO .
    CLEAR: gv_post.
    LOOP AT gt_person INTO gs_person FROM lv_beg TO lv_end.
      IF sy-tabix = 1."第一条数据
        CONCATENATE  '"'
                     gs_person-userid
                     '"'
                     INTO gv_post.
      ELSE.
        CONCATENATE  gv_post
                     ',"'
                     gs_person-userid
                     '"'
                     INTO gv_post.
      ENDIF.
      CLEAR gs_person.
    ENDLOOP.
    IF sy-subrc = 0.
      CONCATENATE '[' gv_post ']' INTO gs_post-post.
      APPEND gs_post TO gt_post.
      CLEAR: gs_post.
      lv_beg = lv_beg + 50 .
      lv_end = lv_end + 50 .
    ELSE.
      EXIT.
    ENDIF.
  ENDDO.
ENDFORM.
*&---------------------------------------------------------------------*
*& Form F_PRO_DETAIL_DATA
*&---------------------------------------------------------------------*
*& text
*&---------------------------------------------------------------------*
*& -->  p1        text
*& <--  p2        text
*&---------------------------------------------------------------------*
FORM f_pro_detail_data .
  DATA: lv_datum TYPE sy-datum,
        lv_uzeit TYPE sy-uzeit.
  DATA: lv_zmins TYPE i.

  CLEAR: gv_index.
  LOOP AT gt_ptresult INTO gs_ptresult.
******日期转换
    "实际打卡时间
    CLEAR: lv_datum,lv_uzeit.
    PERFORM f_convert_unixtime_to_datum USING gs_ptresult-userchecktime
                                        CHANGING lv_datum
                                                 lv_uzeit.
    gs_ptresult-zdktime = lv_uzeit.

    "打卡日期
    CLEAR: lv_datum,lv_uzeit.
    PERFORM f_convert_unixtime_to_datum USING gs_ptresult-workdate
                                        CHANGING lv_datum
                                                 lv_uzeit.
    gs_ptresult-workdatum = lv_datum .
    gs_ptresult-begda = lv_datum.
    gs_ptresult-endda = lv_datum.

    "基准时间
    CLEAR: lv_datum,lv_uzeit.
    PERFORM f_convert_unixtime_to_datum USING gs_ptresult-basechecktime
                                        CHANGING lv_datum
                                                 lv_uzeit.
    gs_ptresult-zbase = lv_uzeit.

    "排班打卡时间
    CLEAR: lv_datum,lv_uzeit.
    PERFORM f_convert_unixtime_to_datum USING gs_ptresult-planchecktime
                                        CHANGING lv_datum
                                                 lv_uzeit.
    gs_ptresult-plantime = lv_uzeit.

    "创建时间
    CLEAR: lv_datum,lv_uzeit.
    PERFORM f_convert_unixtime_to_datum USING gs_ptresult-gmtcreate
                                        CHANGING lv_datum
                                                 lv_uzeit.
    gs_ptresult-createtime = lv_uzeit.
    "修改时间
    CLEAR: lv_datum,lv_uzeit.
    PERFORM f_convert_unixtime_to_datum USING gs_ptresult-gmtmodified
                                        CHANGING lv_datum
                                                 lv_uzeit.
    gs_ptresult-modifytime = lv_uzeit.

    IF gs_ptresult-checktype = 'OnDuty'.
      gs_ptresult-zdklx = '01'.
    ELSEIF gs_ptresult-checktype = 'OffDuty'.
      gs_ptresult-zdklx = '02'.
    ENDIF.

    IF gs_ptresult-timeresult = 'Normal'.
      gs_ptresult-zresult = '10'.
    ELSEIF gs_ptresult-timeresult = 'Early'.
      gs_ptresult-zresult = '20'.
    ELSEIF gs_ptresult-timeresult = 'Late'.
      gs_ptresult-zresult = '30'.
    ELSEIF gs_ptresult-timeresult = 'SeriousLate'.
      gs_ptresult-zresult = '40'.
    ELSEIF gs_ptresult-timeresult = 'NotSigned'.
      gs_ptresult-zresult = '50'.
    ENDIF.

*    IF gs_ptresult-islegal = 'N' OR gs_ptresult-locationresult NE 'Normal'.
    IF gs_ptresult-locationresult NE 'Normal'.
      gs_ptresult-zresult = '60'.
    ENDIF.

    IF gs_ptresult-zresult = '30' OR gs_ptresult-zresult = '40'.
      IF gs_ptresult-zdktime <= gs_ptresult-zbase.
        gs_ptresult-zresult = '10'.
      ELSE.
        CLEAR lv_zmins.
        lv_zmins = gs_ptresult-zdktime - gs_ptresult-zbase.
        gs_ptresult-zmins = lv_zmins / 60.
      ENDIF.
*      gs_ptresult-zmins = gs_ptresult-zdktime - gs_ptresult-zbase.
    ELSEIF gs_ptresult-zresult = '20'.
      IF gs_ptresult-zbase <= gs_ptresult-zdktime.
        gs_ptresult-zresult = '10'.
      ELSE.
        CLEAR lv_zmins.
        lv_zmins = gs_ptresult-zbase - gs_ptresult-zdktime.
        gs_ptresult-zmins = lv_zmins / 60.
      ENDIF.
*      gs_ptresult-zmins = gs_ptresult-zbase - gs_ptresult-zdktime.
    ENDIF.

    CLEAR gs_person.
    READ TABLE gt_person INTO gs_person WITH KEY userid = gs_ptresult-userid.
    gs_ptresult-pernr = gs_person-pernr.
    gs_ptresult-ename = gs_person-ename.
    gs_ptresult-email = gs_person-email.

    gv_index = gv_index + 1.
    gs_ptresult-index = gv_index.

    MODIFY gt_ptresult FROM gs_ptresult.
  ENDLOOP.
ENDFORM.
*&---------------------------------------------------------------------*
*& Form F_CONVERT_UNIXTIME_TO_DATUM
*&---------------------------------------------------------------------*
*& text
*&---------------------------------------------------------------------*
*      -->P_GS_PTRESULT_USERCHECKTIME  text
*      <--P_LV_DATUM  text
*&---------------------------------------------------------------------*
FORM f_convert_unixtime_to_datum USING iv_unixtime
                                  CHANGING ev_datum
                                           ev_uzeit.

  DATA: lv_seconds_per_day(8) TYPE p VALUE 86400,
        lv_init_date          LIKE sy-datum VALUE '19700101'.

  DATA: lv_datum          TYPE datum,
        lv_uzeit          TYPE uzeit,
        lv_timestmp(8)    TYPE p,
        lv_tzone          TYPE sy-tzone,
        lv_timestmp_c     TYPE numc15,
        lv_tzone_c        TYPE numc10,
        lv_time_and_tzone TYPE text50,
        lv_perfix         TYPE text50,
        lv_suffix         TYPE text50.

  CHECK iv_unixtime IS NOT INITIAL.

  lv_timestmp = iv_unixtime DIV 1000 .

  lv_uzeit = lv_timestmp + 3600 * 8.

  lv_datum = ( lv_timestmp + 3600 * 8 ) DIV lv_seconds_per_day + lv_init_date.

  ev_datum = lv_datum.
  ev_uzeit = lv_uzeit.
ENDFORM. " F_CONVERT_UNIXTIME_TO_DATUM
*&---------------------------------------------------------------------*
*&      Form  F_P9401_OPERATION     全部注释-20201013
*&---------------------------------------------------------------------*
*       text
*----------------------------------------------------------------------*
*      -->P_LS_P9401  text
*      -->P_LV_OPERATION  text
*      -->P_LV_TCLAS  text
*      -->P_LV_NOCOMMIT  text
*      <--P_LS_RETURN  text
*      <--P_LV_TYPE  text
*      <--P_LV_MESSAGE  text
*----------------------------------------------------------------------*
*FORM f_p9401_operation USING s_p9401 STRUCTURE p9401
*                                 i_operation TYPE pspar-actio
*                                 i_tclas TYPE pspar-tclas
*                                 i_nocommit TYPE bapi_stand-no_commit
*                                 i_dialog_mode TYPE char1
*                        CHANGING s_return TYPE bapireturn1
*                                 e_type TYPE bapireturn1-type
*                                 e_message TYPE bapireturn1-message.
*  IF s_p9401 IS INITIAL OR
*     i_operation IS INITIAL OR
*     i_tclas IS INITIAL OR
*     i_nocommit IS INITIAL.
*    e_type = 'E'.
*    e_message = '输入参数不合法'.
*    RETURN.
*  ENDIF.
*
** Enqueue this person.
*  CALL FUNCTION 'BAPI_EMPLOYEE_ENQUEUE'
*    EXPORTING
*      number = s_p9401-pernr
*    IMPORTING
*      return = s_return.
*
*  IF s_return-type = 'E' OR s_return-type = 'A'.
*    e_type = 'E'.
*    e_message = s_return-message.
*  ELSE.
**信息类型操作
*    CLEAR s_return.
*    CALL FUNCTION 'HR_INFOTYPE_OPERATION'
*      EXPORTING
*        infty         = s_p9401-infty
*        subtype       = s_p9401-subty
*        number        = s_p9401-pernr
*        validityend   = s_p9401-endda
*        validitybegin = s_p9401-begda
*        record        = s_p9401
*        operation     = i_operation
*        tclas         = i_tclas
*        nocommit      = i_nocommit
*        dialog_mode   = i_dialog_mode
*      IMPORTING
*        return        = s_return.
*    IF s_return-type EQ 'E' OR s_return-type EQ 'A'.
*      e_type = 'E'.
*      e_message = s_return-message.
*      ROLLBACK WORK.
*
*      CALL FUNCTION 'HR_INITIALIZE_BUFFER'
*        EXPORTING
*          tclas = 'A'
*          pernr = s_p9401-pernr.
*      CALL FUNCTION 'HR_PSBUFFER_INITIALIZE'.
*    ELSE.
*      e_type = 'S'.
*      COMMIT WORK.
*    ENDIF.
*  ENDIF.
*
*  CALL FUNCTION 'BAPI_EMPLOYEE_DEQUEUE'
*    EXPORTING
*      number = s_p9401-pernr
*    IMPORTING
*      return = s_return.
*
*ENDFORM.
*&---------------------------------------------------------------------*
*& Form F_INS_9401      全部注释20201013
*&---------------------------------------------------------------------*
*& text
*&---------------------------------------------------------------------*
*& -->  p1        text
*& <--  p2        text
*&---------------------------------------------------------------------*
*FORM f_ins_9401 .
*  DATA: lt_log   TYPE TABLE OF zthrpt006_log,
*        lt_log2  TYPE TABLE OF zthrpt006_2_log,
*        ls_log   TYPE zthrpt006_log,
*        lt_p9401 TYPE TABLE OF p9401,
*        ls_p9401 TYPE p9401.
*  DATA: ls_return  TYPE bapireturn1,
*        lv_type    TYPE bapireturn1-type,
*        lv_message TYPE bapireturn1-message.
*  DATA: lv_operation   LIKE pspar-actio VALUE 'INS',
*        lv_tclas       LIKE pspar-tclas VALUE 'A',
*        lv_nocommit    LIKE bapi_stand-no_commit VALUE 'X',
*        lv_dialog_mode TYPE char1 VALUE '0'.
*
*  ""先导入遗留&之前失败的
*  IF gt_log IS NOT INITIAL.
*    LOOP AT gt_log INTO gs_log.
*      MOVE-CORRESPONDING gs_log TO ls_p9401.
*      ls_p9401-infty = '9401'.
*      ls_p9401-subty = ls_p9401-zdklx.
*      CLEAR: ls_return,lv_type,lv_message.
*      PERFORM f_p9401_operation  USING    ls_p9401
*                                          lv_operation
*                                          lv_tclas
*                                          lv_nocommit
*                                          lv_dialog_mode
*                        CHANGING    ls_return
*                                    lv_type
*                                    lv_message .
*      IF lv_type = 'S'.
*        gs_log-flag = 'X'.
*        MODIFY zthrpt006_log FROM gs_log.
*      ENDIF.
*      CLEAR: gs_log,ls_p9401.
*    ENDLOOP.
*  ENDIF.
*
*  ""导入今天的打卡记录
*  DELETE gt_ptresult WHERE zdklx IS INITIAL.
*  DELETE gt_ptresult WHERE workdatum NE pn-begda.
***上班取最早的一条数据,下班取最晚的一条数据 beg  byhandfyf 20191109
*  SORT gt_ptresult BY pernr zdklx.
*  REFRESH:gt_ptresult1,gt_ptresult2.
*  LOOP AT gt_ptresult INTO gs_ptresult.
*    CLEAR:gs_ptresult-index.
*    IF gs_ptresult-zdklx = '01'.
*      APPEND gs_ptresult TO gt_ptresult1.
*    ELSEIF gs_ptresult-zdklx = '02'.
*      APPEND gs_ptresult TO gt_ptresult2.
*    ENDIF.
*    CLEAR:gs_ptresult.
*  ENDLOOP.
*  SORT gt_ptresult1 BY pernr zdktime.
*  DELETE ADJACENT DUPLICATES FROM gt_ptresult1 COMPARING pernr.
*  SORT gt_ptresult2 DESCENDING BY pernr  zdktime.
*  DELETE ADJACENT DUPLICATES FROM gt_ptresult2 COMPARING pernr.
*  REFRESH:gt_ptresult.
*  LOOP AT gt_ptresult1 INTO gs_ptresult1.
*    APPEND gs_ptresult1 TO gt_ptresult.
*    CLEAR:gs_ptresult1.
*  ENDLOOP.
*  LOOP AT gt_ptresult2 INTO gs_ptresult2.
*    APPEND gs_ptresult2 TO gt_ptresult.
*    CLEAR:gs_ptresult2.
*  ENDLOOP.
*  SORT gt_ptresult BY pernr zdklx.
***上班取最早的一条数据,下班取最晚的一条数据 end  byhandfyf 20191109
*
*
*  LOOP AT gt_ptresult INTO gs_ptresult.
*    MOVE-CORRESPONDING gs_ptresult TO ls_log.
*    APPEND ls_log TO lt_log2.
*    CLEAR:ls_log,gs_ptresult.
*  ENDLOOP.
*
*  IF lt_log2 IS NOT INITIAL.
*    MODIFY zthrpt006_2_log FROM TABLE lt_log2.
*  ENDIF.
*
*  LOOP AT gt_ptresult INTO gs_ptresult.
*    MOVE-CORRESPONDING gs_ptresult TO ls_p9401.
*    MOVE-CORRESPONDING gs_ptresult TO ls_log.
*    ls_p9401-infty = '9401'.
*    ls_p9401-subty = ls_p9401-zdklx.
*    CLEAR: ls_return,lv_type,lv_message.
*    PERFORM f_p9401_operation  USING    ls_p9401
*                                        lv_operation
*                                        lv_tclas
*                                        lv_nocommit
*                                        lv_dialog_mode
*                      CHANGING    ls_return
*                                  lv_type
*                                  lv_message .
*
*    IF lv_type = 'E'.
*      ls_log-message = lv_message.
*      APPEND ls_log TO lt_log.
*    ELSE.
*      ls_log-flag = 'X'.
*    ENDIF.
*    MODIFY zthrpt006_2_log FROM ls_log.
*
*    CLEAR ls_log.
*    CLEAR ls_p9401.
*  ENDLOOP.
*
*
*
*  IF sy-subrc = 0.
*    MESSAGE '打卡数据写入成功' TYPE 'S'.
*  ENDIF.
*
*  IF lt_log IS NOT INITIAL.
*    MODIFY zthrpt006_log FROM TABLE lt_log.
*  ENDIF.
*ENDFORM.
*&---------------------------------------------------------------------*
*&      Form  F_TOKEN_FROM_DING
*&---------------------------------------------------------------------*
*       text
*----------------------------------------------------------------------*
*      <--P_GV_TOKEN  text
*----------------------------------------------------------------------*
FORM f_token_from_ding USING i_corpid TYPE string
                              i_corpsecret TYPE string
                                  CHANGING i_token.
  DATA: lr_http_client  TYPE REF TO if_http_client, "获取token
        lr_initial      TYPE REF TO cx_sy_ref_is_initial,
        lr_format_error TYPE REF TO cx_xslt_format_error.

  DATA: lv_message TYPE bapireturn1-message,
        lv_return  TYPE i.

  DATA: lv_url    TYPE string, "获取部门列表url
        lv_result TYPE string. "获取部门列表

  CONCATENATE 'https://oapi.dingtalk.com/gettoken?corpid='
              i_corpid
              '&corpsecret='
              i_corpsecret
              INTO lv_url.

  "根据URL生成HTTP代理
  CALL METHOD cl_http_client=>create_by_url(
    EXPORTING
      url                = lv_url
    IMPORTING
      client             = lr_http_client
    EXCEPTIONS
      argument_not_found = 1
      plugin_not_active  = 2
      internal_error     = 3
      OTHERS             = 4 ).

*设置 HTTP 版本
  lr_http_client->request->set_version( if_http_request=>co_protocol_version_1_0 ).

  CHECK lr_http_client IS NOT INITIAL.
*将HTTP代理设置GET方法
  lr_http_client->request->set_method( if_http_request=>co_request_method_get ).

  TRY.
      "发送HTTP请求
      CALL METHOD lr_http_client->send
        EXCEPTIONS
          http_communication_failure = 1
          http_invalid_state         = 2.

      CALL METHOD lr_http_client->receive
        EXCEPTIONS
          http_communication_failure = 1
          http_invalid_state         = 2
          http_processing_failed     = 3.

    CATCH cx_sy_ref_is_initial INTO lr_initial.
      lv_message = lr_initial->if_message~get_text( ).
      MESSAGE lv_message TYPE 'E'.
  ENDTRY.

* 获取返回的数据
  CLEAR lv_result.
  lv_result = lr_http_client->response->get_cdata( ).

*关闭HTTP链接
  lr_http_client->close( ).

  REPLACE ALL OCCURRENCES OF '"errcode"'     IN lv_result
                        WITH  '"ERRCODE"'     IGNORING CASE.
  REPLACE ALL OCCURRENCES OF '"access_token"'     IN lv_result
                        WITH  '"ACCESS_TOKEN"'     IGNORING CASE.
  REPLACE ALL OCCURRENCES OF '"errmsg"'     IN lv_result
                        WITH  '"ERRMSG"'     IGNORING CASE.

*将字符串转为abap结构类型变量中
  TRY .
      REFRESH gt_department[].
      CALL TRANSFORMATION id SOURCE XML lv_result
          RESULT access_token = i_token.
    CATCH cx_xslt_format_error INTO lr_format_error .
      lv_message = lr_format_error->get_text( ).
  ENDTRY.

ENDFORM.

``


 怎么样,在了解此篇文章有何感想?


如果本文对大家有所帮助的话,还望各位能给我点赞、收藏并评论一下,感谢各位💕!!! 另如果大家有什么疑问或者建议的话,欢迎评论区留言。更多精彩内容->在这里

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值