1.1. 简介

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

1.1.1. 操作流程

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

1.1.2. 使用到的 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

1.2. 案例实现

1.2.1. 新增报销单

草稿态新增报销单:

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\"}"}

1.2.2. 提交报销单

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

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

1.2.3. 查询提交的结果

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

a. 使用接口POST https://api2.77hub.com/v1/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. 如果返回错误信息,需要先处理错误信息,针对错误信息更新数据:

  • 使用接口POST https://api2.77hub.com/v1/update 更新报销单。
  • 在请求体(Body)中,以 JSON 格式填写请求参数。

    {
    "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}
    

results matching ""

    No results matching ""