🚀欢迎来到本文🚀
🍉个人简介: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.
``
怎么样,在了解此篇文章有何感想?
如果本文对大家有所帮助的话,还望各位能给我点赞、收藏并评论一下,感谢各位💕!!! 另如果大家有什么疑问或者建议的话,欢迎评论区留言。更多精彩内容->在这里