跳到主要内容

asyncBatchDo

简介

在与企企系统对接中,企企提供异步接口。草稿态新增时,可使用异步接口进行单据提交。异步接口支持单据的提交,撤回,弃审,同意。本教程将介绍如果通过开放平台openApi实现企企异步接口的调用。

操作流程

本教程通过 API 实现企企与第三方系统的对接,操作时序图如下所示:

使用到的 OpenAPI

本教程将调用以下 OpenApi 接口

方法(API)操作访问凭证
POST /v1/list 标准接口 (所有开放对象的查询都可使用此接口)查询对象列表openid(v1 版本)
PUT /v1/update 标准接口 (所有开放对象的查询都可使用此接口)更新对象(单据状态为:草稿、已退回、已撤回 时支持更新)openid(v1 版本)
POST /v1/delete 标准接口 (所有开放对象的查询都可使用此接口)删除对象openid(v1 版本)
POST /v1/batchDo 仅支持单据,不支持档案同步任务接口,用于单据状态变更(支持状态:提交,撤回,弃审,同意状态)openid(v1 版本)
GET /v1/code 仅支持单据,不支持档案根据code获取openid无需openid

案例实现

新增报销单

草稿态新增报销单:

a. 使用接口**,**POST https://api2.77hub.com/v1/add 新增接口。

b. 使用sdk,新增时自动提交付款单示例如下, Save-As-Draft 设置为 true

public void testAdd() {
PostAddRequest request = new PostAddRequest();
ApiParams apiParams = new ApiParams();
apiParams.setJson("{\"objectType\":\"Reimburse\",\"data\":{\"billType.name\":\"差旅报销单\",\"webEditTemplate.name\":\"差旅报销单\",\"businessType.name\":\"日常报销\",\"businessDate\":\"2023-08-02\",\"code\":\"122kEX0120220800001\",\"applyDepartment.name\":\"总部\",\"applyUser.name\":\"qianqian-1127\",\"department.name\":\"总部\",\"isEntrust\":false,\"description\":\"出差报销\",\"project.name\":\"预算项目\",\"originActualAmount\":6000,\"reimburseTaxis\":[{\"cost.name\":\"广告费\",\"activityDate\":\"1659283200000\",\"originAmount\":500,\"originDeductedAmount\":500,\"description\":\"出差打车\",\"fromPlace\":\"北京\",\"toPlace\":\"大兴机场\",\"reimburseVoucher.name\":\"增值税普通发票\",\"isDeduction\":false,\"project.name\":\"预算项目\",\"originActualAmount\":500,\"budgetAccount.name\":\"费用预算001\"}],\"reimburseTransports\":[{\"cost.name\":\"营业外支出\",\"activityDate\":\"1659283200000\",\"originAmount\":1000,\"originDeductedAmount\":921.56,\"description\":\"长途\",\"fromDistrict.code\":\"01\",\"fromDistrict.name\":\"北京\",\"toDistrict.code\":\"09\",\"toDistrict.name\":\"上海市\",\"transport.name\":\"飞机\",\"transportClass.name\":\"经济舱\",\"discount\":0,\"reimburseVoucher.name\":\"行程单\",\"isDeduction\":true,\"originDeductibleTaxAmount\":78.44,\"deductionTaxRate\":0.09,\"originActualAmount\":1000,\"project.name\":\"预算项目\",\"budgetAccount.name\":\"费用预算001\"}],\"reimburseAllowances\":[{\"cost.name\":\"财务费\",\"startDate\":\"1659283200000\",\"endDate\":\"1661875200000\",\"originAmount\":3000,\"originDeductedAmount\":3000,\"days\":30,\"originActualAmount\":3000,\"city.name\":\"上海市\",\"project.name\":\"预算项目\",\"budgetAccount.name\":\"费用预算001\"}],\"reimburseHotels\":[{\"cost.name\":\"财务费\",\"startDate\":\"2022-08-01\",\"endDate\":\"2022-08-31\",\"days\":30,\"originAmount\":3000,\"city.code\":\"09\",\"city.name\":\"上海市\",\"description\":\"住宿\",\"isDeduction\":true,\"originDeductibleTaxAmount\":66,\"deductionTaxRate\":0,\"project.name\":\"预算项目\",\"originActualAmount\":3000}],\"externalObjectId\":\"2100000028\",\"externalObjectType\":\"Reimburse\",\"externalSystemCode\":\"210028\"}}";
request.sdkRequestConfig(getSdkRequestConfig(request, true, true));
request.setApiParams(apiParams);
PostAddResult postAddResult = openapi().postAdd(request);
ApiResponse apiResponse = postAddResult.getApiResponse();
System.out.println(apiResponse);
}

c. 返回结果:

{"json":"{\"id\":\"RMUEHSDv87000S\"}"}

提交报销单

提交新增的报销单,提交后,如果有审批流程,会直接进入单据的审批流程

a. 使用接口**,**POST https://api2.77hub.com/v1/asyncBatchDo 提交报销单。

b. 在请求体(Body)中,以 JSON 格式填写请求参数。

  {
"objectType":"Reimburse", // 对象名称,从数据字典中查看对象名称,必填
"objectId":"RMUEHSDv87000S", // 对象id ,必填
"action":"manualSubmit", // 执行动作,必填
"reason":"原因" // 执行原因
}

c. 提交报销单返回:

{
"json": "{\"runningIds\":[\"RMUEHSDv87000S\"],\"successIds\":[],\"failIds\":{},\"warningIds\":{},\"userTaskActionValue\":\"manualSubmit\",\"objectType\":\"Reimburse\",\"failedCount\":0,\"runningCount\":1,\"successCount\":0,\"warningCount\":0,\"totalCount\":1,\"taskId\":\"L3QAT462XQU009G\",\"isCompleted\":false,\"requestId\":\"time-65a78588-dbe7-4b02-aabc-f789d5cb8494\"}"
}

参数说明:

  • runningIds: 执行的单据id
  • requestId: 查询一步任务执行结果的id

查询提交的结果

根据提交返回的requestId查询提交的结果

a. 使用接口**,**POST https://api2.77hub.com/v1/asyncTask 提交报销单。

b. 在请求体(Body)中,以 JSON 格式填写请求参数。

{
"requestId":"time-65a78588-dbe7-4b02-aabc-f789d5cb8494" // 提交返回的requestId
}

c. 使用sdk,修改付款单示例如下

public void testAsyncTask() {
PostAsynctaskRequest request = new PostAsynctaskRequest();
request.sdkRequestConfig(getSdkRequestConfig(request));
AsyncTaskParams params = new AsyncTaskParams();
params.setRequestId("time-d5b4e7a2-d593-4b5e-afd4-c42f2418aee1");
request.setAsyncTaskParams(params);
PostAsynctaskResult result = openapi().postAsynctask(request);
System.out.println(result.getAsyncTask());
}

d. 返回结果:

  • 提交成功返回结果
{AsyncTaskItems: [{AsyncTaskItemStatusObject: {Id: AsyncTaskItemStatus.succeeded,Title: 成功},BillStatusObject: {Id: BillStatus.restarted,Title: 已退回},LastErrorMsg: ,ObjectId: L3QAT462XQU0009,ObjectType: Reimburse}],IsCompleted: true}
  • AsyncTaskItemStatusObject; 异步任务状态
    • id: AsyncTaskItemStatus.succeeded 异步任务成功
  • IsCompleted:true 是否完成
  • 提交报错返回结果
{AsyncTaskItems: [{AsyncTaskItemStatusObject: {Id: AsyncTaskItemStatus.failed,Title: 失败},BillStatusObject: {Id: BillStatus.draft,Title: 未提交},LastErrorMsg: {"type":"error","code":"0010","message":"提交的数据存在问题","description":"Object validation failed","args":{"problems":{"default":{"ERROR":[{"fieldPath":"reimburseTaxis[0].budgetAccount","type":"error","code":"0011","message":"字段必填","args":{"objectType":"ReimburseTaxi"}},{"fieldPath":"reimburseAllowances[0].budgetAccount","type":"error","code":"0011","message":"字段必填","args":{"objectType":"ReimburseAllowance"}},{"fieldPath":"reimburseTransports[0].budgetAccount","type":"error","code":"0011","message":"字段必填","args":{"objectType":"ReimburseTransport"}}]}}}},ObjectId: L3QAT462XQU0009,ObjectType: Reimburse}],IsCompleted: true}
  • AsyncTaskItemStatusObject; 异步任务状态
    • id: AsyncTaskItemStatus.failed 异步任务失败
  • LastErrorMsg: 错误信息
  • IsCompleted:true 是否完成

e. 如果返回错误信息,需要先处理错误信息,针对错误信息更新数据:

{
"json": "{\"objectType\":\"Reimburse\",\"data\":{\"id\":\"L3QAT462XQU0009\",\"reimburseTaxis\":[{\"id\":\"L3QAT462XQU0008\",\"budgetAccount\":\"4000\",\"budgetAccount.name\":\"费用预算001\",\"editFlag\":\"update\"}],\"reimburseAllowances\":[{\"id\":\"L3QAT462XQU0005\",\"budgetAccount\":\"11\",\"budgetAccount.name\":\"费用预算001\",\"editFlag\":\"update\"}],\"reimburseTransports\":[{\"id\":\"L3QAT462XQU0006\",\"budgetAccount\":\"22\",\"budgetAccount.name\":\"费用预算001\",\"editFlag\":\"update\"}]}}"
}

json 的value 值如下:

{
"objectType":"Reimburse",
"data":{
"id":"L3QAT462XQU0009", // 报销单单据id
"reimburseTaxis":[
{
"id":"L3QAT462XQU0008", //出差打车明细id,更新明细,需要加上明细ID
"budgetAccount":"4000",
"budgetAccount.name":"费用预算001",
"editFlag":"update"
}
],
"reimburseAllowances":[
{
"id":"L3QAT462XQU0005", //出差打车明细id
"budgetAccount":"11",
"budgetAccount.name":"费用预算001",
"editFlag":"update"
}
],
"reimburseTransports":[
{
"id":"L3QAT462XQU0006", //出差打车明细id
"budgetAccount":"22",
"budgetAccount.name":"费用预算001",
"editFlag":"update"
}
]
}
}
  • 使用sdk,新增时自动提交付款单示例如下
public void testUpdate() {
PutUpdateRequest request = new PutUpdateRequest();
ApiParams apiParams = new ApiParams();
apiParams.setJson("{\"objectType\":\"Reimburse\",\"data\":{\"id\":\"L3QAT462XQU0009\",\"reimburseTaxis\":[{\"id\":\"L3QAT462XQU0008\",\"budgetAccount\":\"4000\",\"budgetAccount.name\":\"费用预算001\",\"editFlag\":\"update\"}],\"reimburseAllowances\":[{\"id\":\"L3QAT462XQU0005\",\"budgetAccount\":\"11\",\"budgetAccount.name\":\"费用预算001\",\"editFlag\":\"update\"}],\"reimburseTransports\":[{\"id\":\"L3QAT462XQU0006\",\"budgetAccount\":\"22\",\"budgetAccount.name\":\"费用预算001\",\"editFlag\":\"update\"}]}}");
request.sdkRequestConfig(getSdkRequestConfig(request));
request.setApiParams(apiParams);
PutUpdateResult result = openapi().putUpdate(request);
ApiResponse apiResponse = result.getApiResponse();
System.out.println(apiResponse);
}
  • 更新返回结果
 {"json":"{\"success\":true}"}
  • 数据更新后异步提交:
{
"json": "{\"runningIds\":[\"L3QAT462XQU0009\"],\"successIds\":[],\"failIds\":{},\"warningIds\":{},\"userTaskActionValue\":\"manualSubmit\",\"objectType\":\"Reimburse\",\"failedCount\":0,\"runningCount\":1,\"successCount\":0,\"warningCount\":0,\"totalCount\":1,\"taskId\":\"L3QAT462XQU00D9\",\"isCompleted\":false,\"requestId\":\"time-3720ce9e-178a-46f9-9025-e4810516ef1a\"}"
}
  • 异步提交口查询提交结果:
{AsyncTaskItems: [{AsyncTaskItemStatusObject: {Id: AsyncTaskItemStatus.succeeded,Title: 成功},BillStatusObject: {Id: BillStatus.restarted,Title: 已退回},LastErrorMsg: ,ObjectId: L3QAT462XQU0009,ObjectType: Reimburse}],IsCompleted: true}