1

本主题将演示如何通过基于 REST 合同的 API 从 Acumatica ERP 导出记录。与 Acumatica ERP 的 Screen-Based API 相比,Contract-Based API 同时提供 SOAP 和 REST 接口。有关基于合同的 API 的更多信息,请参阅Acumatica ERP 文档

4

1 回答 1

3

在单个 REST 调用中导出数据

在此示例中,您将探索如何通过基于 REST 合同的 API 在一次调用中从 Acumatica ERP 导出以下数据:

  • 应用程序中存在的所有库存项目
  • IN 类型的所有销售订单

如果您需要从 Acumatica ERP 导出记录,请使用以下 URL: http://<Acumatica ERP instance URL>/entity/<Endpoint name>/<Endpoint version>/<Top-level entity>

<Top-level entity>是您要导出的实体的名称

要在单个 REST 调用中导出所有库存项目:

要使用版本6.00.001的默认端点从本地AcumaticaERP实例导出库存项目记录,您应该使用以下 URL:http://localhost/AcumaticaERP/entity/Default/6.00.001/StockItem

下面是用 C# 编写的示例代码,通过向版本6.00.001的默认端点发送单个 REST 调用来导出所有库存项目:

using (RestService rs = new RestService(
    @"http://localhost/AcumaticaERP/", "Default/6.00.001",
    username, password, company, branch))
{
    string stockItems = rs.GetList("StockItem");
}

在单个 REST 调用中导出所有 IN 类型的销售订单:

要使用版本6.00.001的默认端点从本地实例导出IN类型的销售订单,您应该使用以下 URL:AcumaticaERPhttp://localhost/AcumaticaERP/entity/Default/6.00.001/SalesOrder?$filter=OrderType eq 'IN'

下面是用 C# 编写的示例代码,通过向版本6.00.001的默认端点发送单个 REST 调用来导出所有IN类型的销售订单:

using (RestService rs = new RestService(
    @"http://localhost/StackOverflow/", "Default/6.00.001",
    username, password, company, branch))
{
    var parameters = "$filter=OrderType eq 'IN'";
    string inSalesOrders = rs.GetList("SalesOrder", parameters);
}

多个 REST 请求的分页

在本例中,您将探索如何通过 REST Contract-Based API 从 Acumatica ERP 批量导出以下数据:

  • 以 10 条记录为单位存储应用程序中存在的项目
  • 100 条记录的所有销售订单

使用多个 REST 调用分批导出 10 条记录的库存项目:

要使用版本6.00.001的默认端点从本地AcumaticaERP实例导出前 10 个库存项目,您应该使用以下 URL:http://localhost/AcumaticaERP/entity/Default/6.00.001/StockItem?$top=10

因此,要请求从 10 到 20 的库存商品,您只需使用filter参数扩展上面的 URL:http://localhost/AcumaticaERP/entity/Default/6.00.001/StockItem?$top=10&$filter=InventoryID gt '<InventoryID>'

<InventoryID>是使用先前 REST 调用导出的最后一个库存项目的 ID

下面是用 C# 编写的示例代码,通过向版本6.00.001的默认端点发送多个 REST 调用,以 10 条记录为一组导出所有库存项目:

using (RestService rs = new RestService(
    @"http://localhost/StackOverflow/", "Default/6.00.001",
    username, password, company, branch))
{
    var json = new JavaScriptSerializer();
    string parameters = "$top=10";
    string items = rs.GetList("StockItem", parameters);
    var records = json.Deserialize<List<Dictionary<string, object>>>(items);

    while (records.Count == 10)
    {
        var inventoryID = records[records.Count - 1]["InventoryID"] as Dictionary<string, object>;
        var inventoryIDValue = inventoryID.Values.First();
        string nextParameters = parameters + "&" + 
            "$filter=" + string.Format("InventoryID gt '{0}'", inventoryIDValue);
        items = rs.GetList("StockItem", nextParameters);
        records = json.Deserialize<List<Dictionary<string, object>>>(items);
    }
}

使用多个 REST 调用以 100 条记录批量导出所有销售订单:##

要使用版本6.00.001的默认端点从本地AcumaticaERP实例导出前 100 个销售订单,您应该使用以下 URL:http://localhost/AcumaticaERP/entity/Default/6.00.001/SalesOrder?$top=100

由于Sales Order实体的主键由Order TypeOrder Number组成,因此在此示例中,您将使用Order TypeOrder Number字段的过滤参数组合:

  • 要请求SO类型从 100 到 200 的销售订单,您应该使用以下 URL:http://localhost/AcumaticaERP/entity/Default/6.00.001/SalesOrder?$top=100&$filter=OrderType eq 'SO' and OrderNbr gt '<OrderNbr>'

<OrderNbr>是使用先前 REST 调用导出的最后一个销售订单的编号

  • 因此,要请求下一个SO类型的前 100 个销售订单,您应该使用以下 URL:http://localhost/AcumaticaERP/entity/Default/6.00.001/SalesOrder?$top=100&$filter=OrderType gt 'SO' and OrderNbr gt ''

下面是用 C# 编写的示例代码,用于通过多次 REST 调用将所有销售订单批量导出 100 条记录到版本6.00.001的默认端点:

using (RestService rs = new RestService(
    @"http://localhost/StackOverflow/", "Default/6.00.001",
    username, password, company, branch))
{
    var json = new JavaScriptSerializer();
    string parameters = "$top=100";
    string items = rs.GetList("SalesOrder", parameters);
    var records = json.Deserialize<List<Dictionary<string, object>>>(items);

    bool sameOrderType = true;
    while (records.Count > 0 && (records.Count == 100 || !sameOrderType))
    {
        var orderType = records[records.Count - 1]["OrderType"] as Dictionary<string, object>;
        var orderTypeValue = orderType.Values.First();
        var orderNbr = records[records.Count - 1]["OrderNbr"] as Dictionary<string, object>;
        var orderNbrValue = orderNbr.Values.First();

        string nextParameters = parameters + "&" + "$filter=" +
            string.Format("OrderType {0} '{1}'", sameOrderType ? "eq" : "gt", orderTypeValue) + " and " +
            string.Format("OrderNbr gt '{0}'", sameOrderType ? orderNbrValue : "''" );
        items = rs.GetList("SalesOrder", nextParameters);
        records = json.Deserialize<List<Dictionary<string, object>>>(items);
        sameOrderType = records.Count == 100;
    }
}

要与 Acumatica ERP 的 REST 基于合同的 API 进行通信,您的客户端应用程序必须始终执行以下 3 个步骤:

  1. 登录 Acumatica ERP 实例并获取包含用户会话信息的 cookie
  2. 与 Acumatica ERP 实例上可用的基于合同的 API 端点之一交互
  3. 从 Acumatica ERP 注销以关闭用户会话

本主题中提供的所有示例均使用默认端点构建,始终作为标准 Acumatica ERP 安装过程的一部分进行部署。在Web 服务端点屏幕 (SM.20.70.60) 上,您可以查看现有端点的详细信息或配置 Acumatica ERP 基于合同的 Web 服务的自定义端点: 在此处输入图像描述

供您参考,下面是上述所有示例中使用的RestService类的实现,用于与 Acumatica ERP 的基于合同的 Web 服务进行交互:

public class RestService : IDisposable
{
    private readonly HttpClient _httpClient;
    private readonly string _acumaticaBaseUrl;
    private readonly string _acumaticaEndpointUrl;

    public RestService(string acumaticaBaseUrl, string endpoint,
        string userName, string password,
        string company, string branch)
    {
        _acumaticaBaseUrl = acumaticaBaseUrl;
        _acumaticaEndpointUrl = _acumaticaBaseUrl + "/entity/" + endpoint + "/";
        _httpClient = new HttpClient(
            new HttpClientHandler
            {
                UseCookies = true,
                CookieContainer = new CookieContainer()
            })
        {
            BaseAddress = new Uri(_acumaticaEndpointUrl),
            DefaultRequestHeaders =
            {
                Accept = {MediaTypeWithQualityHeaderValue.Parse("text/json")}
            }
        };

        var str = new StringContent(
            new JavaScriptSerializer()
                .Serialize(
                    new
                    {
                        name = userName,
                        password = password,
                        company = company,
                        branch = branch
                    }),
                    Encoding.UTF8, "application/json");

        _httpClient.PostAsync(acumaticaBaseUrl + "/entity/auth/login", str)
            .Result.EnsureSuccessStatusCode();
    }

    void IDisposable.Dispose()
    {
        _httpClient.PostAsync(_acumaticaBaseUrl + "/entity/auth/logout",
            new ByteArrayContent(new byte[0])).Wait();
        _httpClient.Dispose();
    }

    public string GetList(string entityName)
    {
        var res = _httpClient.GetAsync(_acumaticaEndpointUrl + entityName)
            .Result.EnsureSuccessStatusCode();

        return res.Content.ReadAsStringAsync().Result;
    }

    public string GetList(string entityName, string parameters)
    {
        var res = _httpClient.GetAsync(_acumaticaEndpointUrl + entityName + "?" + parameters)
            .Result.EnsureSuccessStatusCode();

        return res.Content.ReadAsStringAsync().Result;
    }
}
于 2017-09-21T21:15:22.240 回答