1. 简介

与企企系统对接过程中,,从第三方系统传输数据到企企,或者从企企获取数据,实现两个系统之间的数据对接。本教程将介绍如果通过开放平台openApi实现两个系统之间的数据对接。

1.1. 操作流程

数据传输方向如下所示:

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

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

2. 企企系统数据传至第三方系统

2.1. 实时同步部门档案

2.1.1. 步骤一: 新建部门

在企企系统中新建部门,基础数据-> 部门-> 新建

2.1.2. 步骤二: 监听消息队列

企企系统中创建部门信息后,第三方系统要监听消息队列,达到实时获取部门档案最近变化数据的目的。监听消息后,Entity 的CUD时间发生后,企企将消息发送到SQS队列,开发者获取到消息后,可根据消息返回到信息,查询部门信息。

java sdk使用示例

package com.q7link.openapi.example;

import com.amazonaws.auth.AWSStaticCredentialsProvider;
import com.amazonaws.auth.BasicAWSCredentials;
import com.amazonaws.opensdk.BaseRequest;
import com.amazonaws.opensdk.SdkRequestConfig;
import com.amazonaws.regions.Regions;
import com.amazonaws.services.sqs.AmazonSQS;
import com.amazonaws.services.sqs.AmazonSQSClientBuilder;
import com.amazonaws.services.sqs.model.Message;
import com.amazonaws.services.sqs.model.ReceiveMessageRequest;
import com.q7link.openapi.Openapi;
import com.q7link.openapi.model.GetQueueRequest;
import com.q7link.openapi.model.Queue;
import java.util.List;

/**
 * sqs request example
 */
public class AmazonSqsReceiveMessage {
  private static Regions regions = Regions.CN_NORTH_1;
  private static AmazonSQS amazonSQS;
  private static Openapi openapi;
  private static final String ACCESS_KEY_ID = "";
  private static final String SECRET_KEY = "";
  private static final String OPEN_ID = "";

  public static void main(String[] args) {
    // 通过openapi queue接口获取queueUrl
    Queue queue = getQueue();
    String queueUrl = queue.getQueueUrl();
    while (true) {
      // 接收消息
      List<Message> messages = receiveMessages(queueUrl);
      for (Message message : messages) {
        // 消息体
        String body = message.getBody();

        // do something (构建查询参数,调用查询接口)
        System.out.println(body);

        // 删除消息
        amazonSQS().deleteMessage(queueUrl, message.getReceiptHandle());
      }
    }
  }

  /**
   * 接收消息,推荐使用长轮询
   * <pre>
   *   1.最大等待时间:20秒 值范围:1-20秒
   *   2.最大接收消息数:10 值范围:1-10
   *   3.默认可见性超时:60秒 值范围:0-12天
   *      根据业务需求适当调整可见性超时时间
   * </pre>
   *
   * @param queueUrl 队列url
   * @return 消息列表
   */
  private static List<Message> receiveMessages(String queueUrl) {
    ReceiveMessageRequest request = new ReceiveMessageRequest()
            // 队列url
            .withQueueUrl(queueUrl)
            // 可见性超时:默认60秒,收到消息在可见性超时时间内不会再次收到该消息。注意:可见性超时无法保证不会接收消息两次
            .withVisibilityTimeout(10)
            // 最大等待时间:20秒 值范围:1-20秒
            .withWaitTimeSeconds(5)
            // 最大接收消息数:10 值范围:1-10
            .withMaxNumberOfMessages(10);
    return amazonSQS().receiveMessage(request).getMessages();
  }

  /**
   * 获取队列信息
   *
   * @return 队列对象
   */
  private static Queue getQueue() {
    GetQueueRequest request = new GetQueueRequest();
    request.sdkRequestConfig(getSdkRequestConfig(request));
    return openapi().getQueue(request).getQueue();
  }

  private static SdkRequestConfig getSdkRequestConfig(BaseRequest request) {
    return request.sdkRequestConfig().copyBuilder()
            .customHeader("Content-Type", "application/json")
            .customHeader("Access-Key-Id", ACCESS_KEY_ID)
            .customHeader("Open-Id", OPEN_ID)
            .build();
  }

  public static Openapi openapi() {
    if (openapi == null) {
      String accessKey = ACCESS_KEY_ID;
      String accessSecret = SECRET_KEY;
      BasicAWSCredentials awsCredentials = new BasicAWSCredentials(accessKey, accessSecret);
      openapi = Openapi.builder()
              .iamCredentials(new AWSStaticCredentialsProvider(awsCredentials))
              .build();
    }
    return openapi;
  }

  public static AmazonSQS amazonSQS() {
    if (amazonSQS == null) {
      String accessKey = ACCESS_KEY_ID;
      String accessSecret = SECRET_KEY;
      BasicAWSCredentials awsCredentials = new BasicAWSCredentials(accessKey, accessSecret);
      amazonSQS = AmazonSQSClientBuilder.standard()
              .withRegion(regions)
              .withCredentials(new AWSStaticCredentialsProvider(awsCredentials))
              .build();
    }
    return amazonSQS;
  }
}
  • 监听到的消息体为:
  {
        "tenantId":"XXXX",     // 租户id
        "objectName":"Department",  // 对象类型
        "objectId":"KBJG]03V",      // 对象id
        "operation":"create",  // 操作为新增
        "billTypeId":"EV2VP160CXE000B", // 单据ID
        "billTypeCode":"EX052"          // 单据编码
  }
  • 使用官方提供的php获取消息队列,如果出现以下错误信息,请修改key 为region 的参数,改为: cn-northwest-1 报错信息:
Error executing "ReceiveMessage" on "https://sqs.cn-northwest-1.amazonaws.com.cn/6208XXXXXX99/KBXWXXXXXX6000W-RRBQXXXXXTB0029"; AWS HTTP error: Client error: `POST https://sqs.cn-northwest-1.amazonaws.com.cn/6208XXXXXX99/KBXWXXXXXX6000W-RRBQXXXXXTB0029` resulted in a `403 Forbidden` response: SenderS (truncated...) SignatureDoesNotMatch (client): Credential should be scoped to a valid region. - SenderSignatureDoesNotMatchCredential should be scoped to a valid region. 6a14219a-dad2-5ce0-9b60-7cd80014beef

2.1.3. 步骤三: 同步部门信息

根据以上消息中返回的的objectName,objectId 查询部门信息,调用查询接口,查询到部门数据后,可将改数据传入第三方系统

使用接口

a. POST https://api2.77hub.com/v1/list 查询接口

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

{"json":"{\"objectType\":\"Department\",\"criteriaStr\":\"id ='\''KBJG]03V'\''\",\"fields\":[\"id\",\"name\",\"code\",{\"fieldName\":\"parent\",\"fields\":[\"id\",\"name\",\"code\"]},{\"fieldName\":\"manager\",\"fields\":[\"id\",\"name\",\"code\"]},\"executiveId\",\"characterId\",\"annualNumber\"]}"}

body的json 值:

{
    "objectType":"Department",  // 查询的对象名称,从数据字典中查看对象名称
    "criteriaStr":"id ='KBJG]03V'",    // 查询条件
    "fields":[                        //该对象下要查询的字段
        "id",
        "name",
        "code",
        {
            "fieldName":"parent",
            "fields":[
                "id",
                "name",
                "code"
            ]
        },
        {
            "fieldName":"manager",
            "fields":[
                "id",
                "name",
                "code"
            ]
        },
        "executiveId",
        "characterId",
        "annualNumber"
    ]
}

参数说明:

  • objectType: 查询对象名称
  • criteriaStr :查询条件
  • fields:该对象下要查询的字段

c.使用 curl 命令行工具调用查询接口,获取相关对象信息:

-- 发送请求的参数应包含参与签名的所有参数,并且保持结构一致
curl -X POST 'https://api2.77hub.com/v1/list' \
-H 'Authorization: AWS4-HMAC-SHA256 Credential=AKIAZBC3TYIX7E3BRKX4/20220727/cn-northwest-1/execute-api/aws4_request,SignedHeaders=access-key-id;content-type;host;open-id;x-amz-date,Signature=a1028e7f986fa0403dac021edd278eaa89f71a9ebb0dd0806903c27893361e8a' \
-H 'Access-Key-Id: AKIAZBTYIX7E3BRKX4' \
-H 'Open-Id: 7cfbacd2e2d63b1021bae0277a9e5' \
-H 'X-Amz-Date: 20220727T091444Z' \
-H 'Content-Type: application/json' \
-d'{"json":"{\"objectType\":\"Department\",\"criteriaStr\":\"id ='\''KBJG]03V'\''\",\"fields\":[\"id\",\"name\",\"code\",{\"fieldName\":\"parent\",\"fields\":[\"id\",\"name\",\"code\"]},{\"fieldName\":\"manager\",\"fields\":[\"id\",\"name\",\"code\"]},\"executiveId\",\"characterId\",\"annualNumber\"]}"}'

d. java sdk查询接口示例

publicj void testList() {
  PostListRequest request = new PostListRequest();
  ApiParams apiParams = new ApiParams();
  apiParams.setJson("{\"objectType\":\"Department\",\"criteriaStr\":\"id ='KBJG]03V'\",\"fields\":[\"id\",\"name\",\"code\",{\"fieldName\":\"parent\",\"fields\":[\"id\",\"name\",\"code\"]},{\"fieldName\":\"manager\",\"fields\":[\"id\",\"name\",\"code\"]},\"executiveId\",\"characterId\",\"annualNumber\"]}");
  System.out.println(apiParams.getJson());
  request.sdkRequestConfig(getSdkRequestConfig(request));
  request.setApiParams(apiParams);
  PostListResult postListResult = openapi().postList(request);
  ApiResponse apiResponse = postListResult.getApiResponse();
}

e. 调用结果

  • 成功调用后的返回信息如下图所示:
{"json":"{\"data\":{\"list\":[{\"parent\":{\"code\":\"zongbu001\",\"name\":\"总部\",\"id\":\"1EAV3K501JR0001\"},\"annualNumber\":0,\"code\":\"0001\",\"manager\":{\"code\":\"000000003\",\"name\":\"人员C\",\"id\":\"G7TCQX50CPA002J\"},\"executiveId\":\"HVR2NT50E4W002Q\",\"name\":\"建设管理部\",\"id\":\"RLSLT462XPV0081\"}]},\"errors\":[]}"}
  • 如果返回以下报错信息,请检查相关查询参数是否符合数据字典数据结构
[{"description":"Sub selection required for type null of field children","locations":[{"line":4,"column":27}],"message":"Validation error of type SubSelectionRequired: Sub selection required for type null of field children","validationErrorType":"SubSelectionRequired"}]]

2.1.4. 步骤四: 修改部门档案同步

  • 在企企系统中修改部门,基础数据-> 部门-> 修改

  • 部门修改,按照 步骤二 监听消息队列,获取到消息体为:
{
        "tenantId":"XXXX",     // 租户ID
        "objectName":"Department", // 对象名称,与数据字典中的对象名称符合
        "objectId":"KBJG]03V",    // 对象id
        "operation":"update",  // 操作为更新
        "billTypeId":"EV2VP160CXE000B",   
        "billTypeCode":"EX052"
}
  • 根据消息中返回的的objectName,objectId 按照步骤三查询部门信息,即可获取最近的部门档案数据

2.1.5. 步骤五: 删除部门档案同步

  • 在企企系统中修改部门,基础数据-> 部门-> 删除
  • 部门删除,按照 步骤二 监听消息队列,获取到消息体为:
{
        "tenantId":"XXXX",  // 租户ID
        "objectName":"Department",  // 对象名称,与数据字典中的对象名称符合
        "objectId":"KBJG]03V",      // 对象id
        "operation":"delete",  // 操作为更新
        "billTypeId":"EV2VP160CXE000B",
        "billTypeCode":"EX052"
}
  • 根据消息中返回的的objectName,objectId 删除第三方系统中的部门数据。

2.1.6. 定时同步人员档案,项目分类,项目

步骤一:企企中新建人员,项目分类,项目

1.企企中新建人员

images

2.企企中新建项目分类:

3.企企中新建项目:

项目提交:

步骤二:定时查询数据列表

人员档案,项目分类,项目同步到第三方,第一次同步,如果数据量超过100条数据,建议采用分页拉取数据,第一次拉取之后如果数据有更新,可根据最后修改时间作为查询条件进行查询,拉取数据,拉取数据如下:

a. POST https://api2.77hub.com/v1/list 查询接口

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

{"json":"{\"objectType\":\"User\",\"criteriaStr\":\"id is not null limit 3 offset 0\",\"fields\":[\"id\",\"name\",\"code\",{\"fieldName\":\"jobRelationships\",\"fields\":[\"id\",\"name\",\"code\",\"startTime\",\"disabledTime\",\"departmentId\",\"supervisorId\",\"isMain\",\"rankId\"]},\"genderId\",\"englishName\"]}"}

body的 json 值如下:

{
  "objectType":"User",    //查询对象名称
  "criteriaStr":"id is not null limit 100 offset 0", 查询条件,分页查询
  // "criteriaStr":lastModifiedTime  >= to_timestamp(1653408000)", 根据最后修改时间查询
  "fields":[   // 要查询到字段
     "id",     
     "name",
     "code",
     {
         "fieldName":"jobRelationships",  // 任职记录
         "fields":[
             "id",
             "name",
             "code",
             "startTime",
             "disabledTime",
             "departmentId",
             "supervisorId",
             "isMain",
             "rankId"
         ]
     },
     "genderId",
     "englishName"
   ]
}

c.使用 curl 命令行工具调用查询接口,获取相关对象信息:

-- 发送请求的参数应包含参与签名的所有参数,并且保持结构一致
curl -X POST 'https://api2.77hub.com/v1/list' \
-H 'Authorization: AWS4-HMAC-SHA256 Credential=AKIAZBC3TYIX7E3BRKX4/20220727/cn-northwest-1/execute-api/aws4_request,SignedHeaders=access-key-id;content-type;host;open-id;x-amz-date,Signature=a1028e7f986fa0403dac021edd278eaa89f71a9ebb0dd0806903c27893361e8a' \
-H 'Access-Key-Id: AKIAZBTYIX7E3BRKX4' \
-H 'Open-Id: 7cfbacd2e2d63b1021bae0277a9e5' \
-H 'X-Amz-Date: 20220727T091444Z' \
-H 'Content-Type: application/json' \
-d'{"json":"{\"objectType\":\"User\",\"criteriaStr\":\"id is not null limit 3\",\"fields\":[\"id\",\"name\",\"code\",{\"fieldName\":\"jobRelationships\",\"fields\":[\"id\",\"name\",\"code\",\"startTime\",\"disabledTime\",\"departmentId\",\"supervisorId\",\"isMain\",\"rankId\"]},\"genderId\",\"englishName\"]}"}'

d. java sdk查询接口示例

publicj void testList() {
  PostListRequest request = new PostListRequest();
  ApiParams apiParams = new ApiParams();
  apiParams.setJson(" {"objectType":"User","criteriaStr":"","fields":["id","name","code",{"fieldName":"jobRelationships","fields":["id","name","code","startTime","disabledTime","departmentId","supervisorId","isMain","rankId"]},"genderId","englishName"]}");
  request.sdkRequestConfig(getSdkRequestConfig(request));
  request.setApiParams(apiParams);
  PostListResult postListResult = openapi().postList(request);
  ApiResponse apiResponse = postListResult.getApiResponse();
}

e. 调用结果

  • 成功调用后的回显信息如下图所示:
    {"Json":"{\"objectType\":\"Payment\",\"data\":{\"billType.name\":\"付款单\",\"webEditTemplate.name\":\"付款单\",\"businessType.name\":\"其他付款\",\"code\":\"PA0120230700001\",\"businessDate\":\"2023-07-04\",\"settleObjectType\":\"User\",\"transObject.code\":\"0001100001\",\"transObject.name\":\"王小二\",\"settlementMethod.code\":\"02\",\"settlementMethod.name\":\"现金\",\"bankAccount.code\":\"00062\",\"bankAccount.name\":\"中国建设银行1111\",\"partyBankAccount.accountCode\":\"334455667777\",\"department.code\":\"0001\",\"department.name\":\"建设管理部\",\"currency.name\":\"人民币\",\"exchangeRate\":1,\"description\":\"新增付款单\",\"project.code\":\"JC20210094\",\"project.name\":\"大厦修复\",\"paymentItems\":[{\"settleObjectType\":\"User\",\"transObject.code\":\"0001100001\",\"transObject.name\":\"王小二\",\"fundPurpose.name\":\"其他应付\",\"apFundArapTypeId\":\"ApFundArapType.beforeAp\",\"project.code\":\"004000000005\",\"project.name\":\"大厦修复\",\"originApAmount\":3987,\"department.code\":\"0001\",\"department.name\":\"建设管理部\",\"description\":\"付款行明细\"}],\"externalObjectId\":\"2100000028\",\"externalObjectType\":\"Payment\",\"externalSystemCode\":\"210028\"}}"}
    

2.2. 第三方系统数据传到企企

2.2.1. 同步付款单

新增付款单

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

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

{"json":"{\"objectType\":\"Payment\",\"data\":{\"billType.name\":\"付款单\",\"webEditTemplate.name\":\"付款单\",\"businessType.name\":\"其他付款\",\"code\":\"PA0120230700001\",\"businessDate\":\"2023-07-04\",\"settleObjectType\":\"User\",\"transObject.code\":\"0001100001\",\"transObject.name\":\"王小二\",\"settlementMethod.code\":\"02\",\"settlementMethod.name\":\"现金\",\"bankAccount.code\":\"00062\",\"bankAccount.name\":\"中国建设银行1111\",\"partyBankAccount.accountCode\":\"334455667777\",\"department.code\":\"0001\",\"department.name\":\"建设管理部\",\"currency.name\":\"人民币\",\"exchangeRate\":1,\"description\":\"新增付款单\",\"project.code\":\"JC20210094\",\"project.name\":\"大厦修复\",\"paymentItems\":[{\"settleObjectType\":\"User\",\"transObject.code\":\"0001100001\",\"transObject.name\":\"王小二\",\"fundPurpose.name\":\"其他应付\",\"apFundArapTypeId\":\"ApFundArapType.beforeAp\",\"project.code\":\"004000000005\",\"project.name\":\"大厦修复\",\"originApAmount\":3987,\"department.code\":\"0001\",\"department.name\":\"建设管理部\",\"description\":\"付款行明细\"}],\"externalObjectId\":\"2100000028\",\"externalObjectType\":\"Payment\",\"externalSystemCode\":\"210028\"}}"}

body参数,json 的value 值如下:

{
   "objectType":"Payment",   // 新增的对象名称,从数据字典中查看对象名称
   "data":{
      "billType.name":"付款单",   // 单据类型,必填,对应系统中的付款单的单据类型,可子啊系统中查询,也可通过gql 查询
      "webEditTemplate.name":"付款单", // 单据模版,对应系统中的单据模版
      "businessType.name":"其他付款",  // 业务类型,必填,对应系统中的业务类型
      "code":"PA0120230700001",
      "businessDate":"2023-07-04",   // 业务日期,必填
      "settleObjectType":"User",     // 往来单位类型,必填
      "transObject.code":"0001100001",
      "transObject.name":"王小二",
      "settlementMethod.code":"02",  // 结算方式,必填
      "settlementMethod.name":"现金",
      "bankAccount.code":"00062",    // 账户,必填
      "bankAccount.name":"中国建设银行1111",
      "partyBankAccount.accountCode":"334455667777",
      "department.code":"0001",
      "department.name":"建设管理部",
      "currency.name":"人民币",
      "exchangeRate":1,
      "description":"新增付款单",
      "project.code":"JC20210094",
      "project.name":"大厦修复",
      "paymentItems":[
       {
          "settleObjectType":"User",       // 往来单位类型
          "transObject.code":"0001100001", // 往来单位
          "transObject.name":"王小二", 
          "fundPurpose.name":"其他应付", // 款项类型
          "apFundArapTypeId":"ApFundArapType.beforeAp", // 款项性质
          "project.code":"004000000005",
          "project.name":"大厦修复",
          "originApAmount":3987,   // 原币付款金额
          "department.code":"0001",
          "department.name":"建设管理部",
          "description":"付款行明细"
        }
      ],
      "externalObjectId":"2100000028", 
      "externalObjectType":"Payment",  
      "externalSystemCode":"210028" 
   }
}
  • 新增参数说明:

    • externalObjectId,externalObjectType,externalSystemCode 三个字段必填,最长128,是外部系统的标识,必填,externalObjectType+externalObjectId不能重复,建议不要是中文 外键字段:
  • 如何区分是否是外键字段

    • 字段有参照对象,字段类型是String,而且没有列表对象
  • 新建对象时,如果不知道外键字段的id,可以用以下方式
    • 如果外键字段以id 结尾, 该字段可替换为 fileName去掉Id +"."+ 参照对象的字段 ;
    • 如果外键字段字段名不是以id结尾,该字段可替换为 fileName +Object + "."+ 参照对象的字段
    • 参照对象的的字段范围:
字段名 字段说明
code 编码
name 名称
title 标题
accountCode 银行账号
bankName 开户银行
rowNo 行号
objectType 对象类型
aliasName 别名
stage.name 阶段名称
stage.code 阶段编码
year 会计期间年
party.code 组织编码
party.name 组织名称
  • 例如以上的单据模版id,字段名为billTypeId,其参照对象为BillType,BillType中可使用的字段为code,name ,所以 billTypeId可被替换为billType.name 或billType.code,
    • 可用以下三种形式录入:
      • 知道id: "billTypeId" : "ERVCSV50H0001"
      • 知道编码:"billType.code:"009933"
      • 知道名称: "billType.name":"付款单1"
      • 既知道名称,又知道编码,录入两个:"billType.code:"009933" , "billType.name":"付款单" ,会优先还有code 查找, 企企后台会根据传入的code或者name 去查询相关对象的id

c. 使用sdk,新增时自动提交付款单示例如下

public static void main(String[] args)  {
  PostAddRequest request = new PostAddRequest();
  ApiParams apiParams = new ApiParams();
  String now = String.valueOf(System.currentTimeMillis());
  apiParams.setJson("{\"objectType\":\"Payment\",\"data\":{\"billType.name\":\"付款单\",\"webEditTemplate.name\":\"付款单\",\"businessType.name\":\"采购付款\",\"code\":\"122kPA0120220700012\",\"businessDate\":\"2022-08-16\",\"settleObjectType\":\"Vendor\",\"transObject.code\":\"0000100001\",\"transObject.name\":\"材料供应商\",\"settleObject.code\":\"0000100001\",\"settleObject.name\":\"材料供应商\",\"settlementMethod.code\":\"02\",\"settlementMethod.name\":\"银行转账\",\"bankAccount.code\":\"00062\",\"bankAccount.name\":\"中国建设银行7890\",\"partyBankAccount.accountCode\":\"334455667777\",\"department.code\":\"dd10035\",\"department.name\":\"测试添加部门\",\"ownerUser.code\":\"genera0001\",\"ownerUser.name\":\"李多\",\"currency.name\":\"人民币\",\"exchangeRate\":1,\"description\":\"新增付款单\",\"purchaseInvoice.code\":\"122kIV8020220800008\",\"contract.code\":\"122kCM022022000007\",\"contract.name\":\"应付单合同\",\"projectOrg.name\":\"科技集团公司-多组织\",\"paymentItems\":[{\"fundPurpose.code\":\"901_SYS\",\"fundPurpose.name\":\"采购及服务\",\"apFundArapTypeId\":\"ApFundArapType.shouldAp\",\"project.code\":\"004000000005\",\"project.name\":\"测试开发项目\",\"projectOrg.code\":\"1122k\",\"projectOrg.name\":\"科技集团公司-多组织\",\"originApAmount\":7232,\"department.code\":\"dd10035\",\"department.name\":\"测试添加部门\",\"ownerUser.code\":\"genera0001\",\"ownerUser.name\":\"李多\",\"cost.code\":\"0001\",\"cost.name\":\"test%s\",\"description\":\"付款行明细\",\"contractSettlementItem.rowNo\":\"10\",\"contract.code\":\"122kCM022022000007\",\"contract.name\":\"应负单合同\"}],\"externalObjectId\":\"2100000028\",\"externalObjectType\":\"Payment\",\"externalSystemCode\":\"210028\"}}");   
  // getSdkRequestConfig(BaseRequest request, boolean ignoreWarn, boolean saveAsDraft)
  // saveAsDraft 为true,自动提交
  request.sdkRequestConfig(getSdkRequestConfig(request,falsetrue,));
  request.setApiParams(apiParams);
  PostAddResult postAddResult = openapi().postAdd(request);
  ApiResponse apiResponse = postAddResult.getApiResponse();
}

d. 调用结果

{"json":"{\"id\":\"RMUEH160PG9000M\"}"}

e. 如返回一下错误信息,说明TS02在企企中不存在,请修改相关参数

{"json":"{\"error\":{\"单据类型\":\"[参照的对象没有找到:[TS02]]\"}}"}

效果实现

同步到企企中的单据示范效果:

审批后单据上生效:

2.2.2. 修改付款单

数据同步后,在企企中不同的单据状态修改的方式不同,修改方式可分为一下3种。

  1. 单据状态为已生效
  2. 单据状态为已提交
  3. 单据状态为未提交,已撤回,已退回

单据状态为已生效时修改单据

在企企企单据已经生效,业务上需要修改数据,但企企已生效态的单据不允许修改,所以需要先将企企中的收款单弃审,调用更新接口修改单据后,再将单据重新提交。步骤如下所示

  • 弃审付款单
  • 修改付款单
  • 重新提交付款单 (重新提交后,如果有审批流程,需要重新审批)

步骤一:弃审付款单

单据生效后,单据弃审,将单据状态由已生效改为已退回。

a. 使用接口POST https://api2.77hub.com/v1/batchDo 弃审。

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

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

c. 使用sdk,弃审付款单示例如下

public static void main(String[] args)  {
  PostBatchDoRequest request = new PostBatchDoRequest();
  // 忽略警告
  boolean ignoreWarn = true;
  request.sdkRequestConfig(getSdkRequestConfig(request, ignoreWarn));
  AsyncBatchDoParams params = new AsyncBatchDoParams();
  params.objectId("RMUEH160PG9000M");
  params.setObjectType("Payment");
  // 单据弃审
  params.setAction("manualWithdraw");
  request.setAsyncBatchDoParams(params);
  PostBatchDoResult result = openapi().postBatchDo(request);
  ApiResponse apiResponse = result.getApiResponse();
}

d. 接口返回正确结果如下:

 {
  "Json":"{\"successIds\":[\"RMUEH160PG9000M\"],\"failIds\":{},\"warningIds\":null,\"isComplete\":true}"
}

参数说明:

  • successIds:["RMUEH160PG9000M" ]: 为操作成功的id
  • isComplete:true 为操作完成的标志 f.返回以下报错信息,请检查单据的状态是否为已生效状态:
{"Json":" {\"runningIds\":[],\"successIds\":[],\"failIds\":{\"RMUEH160PG9000M\":{\"type\":\"error\",\"code\":\"0000\",\"message\":\"状态为[已退回]的单据不允许执行该操作\"}},\"warningIds\":{},\"userTaskActionValue\":\"manualWithdraw\",\"objectType\":\"Reimburse\",\"failedCount\":1,\"runningCount\":0,\"successCount\":0,\"warningCount\":0,\"totalCount\":1,\"taskId\":\"0G9VU462XRS00DP\",\"isCompleted\":true,\"requestId\":\"time-4b83e81b-12bb-4336-ab79-b8773911e1a8\"}"}

参数说明:

  • failIds:{} 操作失败的信息
  • isCompleted:true 为操作完成的标志

e. 实现效果:

单据由已生效改为已经退回

步骤二:修改付款单

修改付款单的结算方式,修改后,保存

a. 使用接口,POST https://api2.77hub.com/v1/update 修改。

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

{
  "json":"{    \"objectType\":\"Vendor\",    \"data\":{        \"id\":\"RMUEH160PG9000M\",        \"settlementMethod.name\":\"银行转账\"   }}"
}

接口参数,json 的value 值如下:

{
    "objectType":"Vendor",
    "data":{
        "id":"RMUEH160PG9000M",   //需要修改的单据id,必填
        "settlementMethod.name":"银行转账"
    }
}

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

public static void main(String[] args)  {
  PutUpdateRequest request = new PutUpdateRequest();
  ApiParams apiParams = new ApiParams();
  apiParams.setJson("{\n" +
          "    \"objectType\":\"Vendor\",\n" +
          "    \"data\":{\n" +
          "        \"id\":\"RMUEH160PG9000M\",\n" +
          "        \"settlementMethod.name\":\"银行转账\"\n" +
          "    }\n" +
          "}");

  request.sdkRequestConfig(getSdkRequestConfig(request));
  request.setApiParams(apiParams);
  PutUpdateResult result = openapi().putUpdate(request);
  ApiResponse apiResponse = result.getApiResponse();
}

d.返回结果如下:

{"json":"{\"success\":true}"}

e.实现效果:

步骤三:付款单单据提交

单据状态是未提交,已撤回,已退回是,可以重新提交单据,使用同步接口进行单据提交,将单据状态由未提交变为已提交。

a. 使用接口,POST https://api2.77hub.com/v1/batchDo 提交。

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

 {
    "objectType":"Payment",   // 对象名称,从数据字典中查看对象名称,必填
    "objectId":"RMUEH160PG9000M", // 对象Id,必填
    "action":"manualSubmit",   // 执行动作,提交,必填
    "reason":"原因"          // 执行原因
  }

c. 使用sdk,提交付款单示例如下

public static void main(String[] args)  {
  PostBatchDoRequest request = new PostBatchDoRequest();
  // 忽略警告
  boolean ignoreWarn = true;
  request.sdkRequestConfig(getSdkRequestConfig(request, ignoreWarn));
  AsyncBatchDoParams params = new AsyncBatchDoParams();
  params.objectId("F63Q3261UAT009S");
  params.setObjectType("Payment");
  // 单据提交
  params.setAction("manualSubmit");
  request.setAsyncBatchDoParams(params);
  PostBatchDoResult result = openapi().postBatchDo(request);
  ApiResponse apiResponse = result.getApiResponse();
}

d.返回结果如下:

{
  "Json":"{\"successIds\":[\"RMUEH160PG9000M\"],\"failIds\":{},\"warningIds\":null,\"isComplete\":true}"
}

e.返回以下结果,请检查单据状态是否为未提交,已撤回,已退回状态

{"Json":"{\"successIds\":[],\"failIds\":{\"5CGU2X50ETN0031\":{\"type\":\"error\",\"code\":\"0000\",\"message\":\"只有待提交,已退回的单据可以提交\"}},\"warningIds\":{}}"}

f. 实现效果:

审批流为自动审批,提交后自动生效:

单据状态为未提交,已撤回,已退回时修改单据

单据状态为未提交,已撤回,已退回时,可直接参考 单据转状态为已生效时修改单据的步骤二 修改付款单

单据状态为已提交时修改单据

单据状态为已提交时,可直接参考 单据转状态为已生效时修改单据的步骤修改付款单,只需要在步骤一时,将执行动作改为撤回,manualRestart,修改单据后,重新提交后单据也需要重新审批。

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

 {
    "objectType":"Payment",    // 对象名称,从数据字典中查看对象名称,必填
    "objectId":"RMUEH160PG9000M", // 对象id,必填
    "action":"manualRestart",   // 执行动作,撤回,manualWithdra修改为manualRestart,必填
    "reason":"原因"// 执行原因
  }

results matching ""

    No results matching ""