0

如何在 NetSuite 中获得类型为“已删除记录”的“已保存搜索”的结果?其他搜索类型很明显(CustomerSearchAdvanced、ItemSearchAdvanced 等),但这个似乎没有在线参考,只是有关删除记录的文档,而不是对它们运行保存的搜索。

更新 1

我应该澄清一下我正在尝试做的事情。在 NetSuite 中,您可以在记录类型“已删除记录”上运行(并保存)已保存的搜索,我相信您可以通过 Web 界面通过此过程访问至少 5 列(不包括用户定义的列):

  • 删除日期
  • 删除者
  • 语境
  • 记录类型
  • 姓名

您还可以将搜索条件设置为“已保存搜索”的一部分。我想使用他们已经设置的搜索条件并从他们显示的所有 5 个列中检索数据来访问我的系统中已经存在的一系列这些“保存的搜索”。

4

2 回答 2

2

从 2016_2 版开始,SuiteTalk 不支持该Deleted Record记录,这意味着您无法运行已保存的搜索并下拉结果。

在与 NetSuite 集成时,这种情况并不少见。:(

在这些情况下,我一直在做的是创建一个 RESTlet(NetSuite 的 RESTful API 框架)SuiteScript,它将运行搜索(或使用 SuiteScript 做任何可能的事情,而使用 SuiteTalk 做不到的事情)并返回结果。

从文档中:

您可以按照 RESTful 原则部署与 NetSuite 数据交互的服务器端脚本。RESTlet 扩展了 SuiteScript API 以允许与 NetSuite 进行自定义集成。使用 RESTlet 的一些好处包括:

通过实现比基于 SOAP 的 Web 服务更轻量级和更灵活的 RESTful 集成,寻找增强可用性和性能的机会。支持客户端和服务器之间的无状态通信。控制客户端和服务器的实现。在 HTTP 标头中使用基于令牌或用户凭据的内置身份验证。在 iPhone 和 Android 等平台上开发移动客户端。集成外部基于 Web 的应用程序,例如 Gmail 或 Google Apps。为基于 Suitelet 的用户界面创建后端。RESTlet 让熟悉 SuiteScript 的开发人员易于采用,并且支持比 NetSuite 基于 SOAP 的 Web 服务更多的行为,后者仅限于定义为 SuiteTalk 操作的那些。RESTlet 也比 Suitelet 更安全,Suitelets 无需登录即可供用户使用。

在您的情况下,这将是一个几乎可以创建的脚本,它将收集结果并返回 JSON 编码(最简单)或您需要的任何格式。

与编写脚本相比,您可能会花费更多时间让基于令牌的身份验证 (TBA) 正常工作。

[更新]添加一些与我在下面的评论中提到的相关的代码示例:

请注意,SuiteTalk 代理对象模型令人沮丧,因为它缺少可以很好利用的继承。因此,您以 SafeTypeCastName() 之类的代码结束。在使用 SuiteTalk 代理时,反射是我工具箱中最好的工具之一。例如,所有 *RecordRef 类型都有共同的字段/道具,因此反射可以节省您在所有地方进行类型检查以使用您怀疑拥有的对象。

public static TType GetProperty<TType>(object record, string propertyID)
{
    PropertyInfo pi = record.GetType().GetProperty(propertyID);
    return (TType)pi.GetValue(record, null);
}

public static string GetInternalID(Record record)
{
    return GetProperty<string>(record, "internalId");
}

public static string GetInternalID(BaseRef recordRef)
{
    PropertyInfo pi = recordRef.GetType().GetProperty("internalId");
    return (string)pi.GetValue(recordRef, null);
}

public static CustomFieldRef[] GetCustomFieldList(Record record)
{
    return GetProperty<CustomFieldRef[]>(record, CustomFieldPropertyName);
}
于 2016-11-17T21:27:52.840 回答
0

感谢@SteveK 的修订和最终答案。我认为从长远来看,我将不得不实施建议的内容,从短期来看,我尝试实施他的第一个解决方案(“getDeleted”),我想对此添加更多细节,以防有人需要使用此方法未来:

//private NetSuiteService nsService = new DataCenterAwareNetSuiteService("login");
//private TokenPassport createTokenPassport() { ... }

private IEnumerable<DeletedRecord> DeletedRecordSearch()
{
    List<DeletedRecord> results = new List<DeletedRecord>();
    int totalPages = Int32.MaxValue;
    int currentPage = 1;

    while (currentPage <= totalPages)
    {
        //You may need to reauthenticate here
        nsService.tokenPassport = createTokenPassport();

        var queryResults = nsService.getDeleted(new GetDeletedFilter
        {
            //Add any filters here...
            //Example
            /*
            deletedDate = new SearchDateField()
                    {
                        @operator = SearchDateFieldOperator.after,
                        operatorSpecified = true,
                        searchValue = DateTime.Now.AddDays(-49),
                        searchValueSpecified = true,
                        predefinedSearchValueSpecified = false,
                        searchValue2Specified = false
                    }
            */
        }, currentPage);

        currentPage++;
        totalPages = queryResults.totalPages;

        results.AddRange(queryResults.deletedRecordList);
    }

    return results;
}

private Tuple<string, string> SafeTypeCastName(
    Dictionary<string, string> customList, 
    BaseRef input)
{
    if (input.GetType() == typeof(RecordRef)) {
        return new Tuple<string, string>(((RecordRef)input).name, 
            ((RecordRef)input).type.ToString());
    }
    //Not sure why "Last Sales Activity Record" doesn't return a type...
    else if (input.GetType() == typeof(CustomRecordRef)) {
        return new Tuple<string, string>(((CustomRecordRef)input).name, 
            customList.ContainsKey(((CustomRecordRef)input).internalId) ? 
                customList[((CustomRecordRef)input).internalId] : 
                "Last Sales Activity Record"));
    }
    else {
        return new Tuple<string, string>("", "");
    }
}

public Dictionary<string, string> GetListCustomTypeName()
{
    //You may need to reauthenticate here
    nsService.tokenPassport = createTokenPassport();

    return
        nsService.search(new CustomListSearch())
            .recordList.Select(a => (CustomList)a)
            .ToDictionary(a => a.internalId, a => a.name);
}

//Main code starts here
var results = DeletedRecordSearch();
var customList = GetListCustomTypeName();

var demoResults = results.Select(a => new
{
    DeletedDate = a.deletedDate,
    Type = SafeTypeCastName(customList, a.record).Item2,
    Name = SafeTypeCastName(customList, a.record).Item1
}).ToList();

我必须应用所有过滤器 API 端,这只返回三列:

  • 删除日期
  • 记录类型(格式与 Web UI 不同
  • 姓名
于 2016-11-18T15:18:41.943 回答