C# NetSuite SuiteTalk:SavedSearch搜索;“已删除记录”;类型
如何在NetSuite中获得“已删除记录”类型的“已保存搜索”的结果?其他搜索类型很明显(CustomerSearchAdvanced、ItemSearchAdvanced等),但这一种似乎没有在线参考,只是文档,没有在其上运行保存的搜索 更新1 我应该进一步澄清一下我想做什么。在NetSuite中,您可以对记录类型“Deleted record”运行(并保存)保存的搜索,我相信您可以通过此过程从web界面访问至少5列(不包括用户定义的列):C# NetSuite SuiteTalk:SavedSearch搜索;“已删除记录”;类型,c#,web-services,soap,netsuite,suitetalk,C#,Web Services,Soap,Netsuite,Suitetalk,如何在NetSuite中获得“已删除记录”类型的“已保存搜索”的结果?其他搜索类型很明显(CustomerSearchAdvanced、ItemSearchAdvanced等),但这一种似乎没有在线参考,只是文档,没有在其上运行保存的搜索 更新1 我应该进一步澄清一下我想做什么。在NetSuite中,您可以对记录类型“Deleted record”运行(并保存)保存的搜索,我相信您可以通过此过程从web界面访问至少5列(不包括用户定义的列): 删除日期 被删除 上下文 记录类型 名字 您还可
- 删除日期
- 被删除
- 上下文
- 记录类型
- 名字
您还可以将搜索条件设置为“已保存搜索”的一部分。我想访问一系列这些“已保存的搜索”已在我的系统中使用其已设置的搜索条件,并从所有5个显示列中检索数据。自2016年版起,SuiteTalk不支持删除的记录记录,这意味着您无法运行已保存的搜索并下拉结果 这在与NetSuite集成时并不少见:( 在这种情况下,我通常会创建一个RESTlet(NetSuite想要的RESTful API框架)SuiteScript来运行搜索(或者使用SuiteScript执行任何可能的操作,而使用SuiteTalk执行任何不可能的操作)并返回结果 从文件中: 您可以部署与NetSuite数据交互的服务器端脚本 遵循RESTful原则。RESTlet将SuiteScript API扩展到 允许与NetSuite进行自定义集成。使用 RESTlet包括以下功能: 通过以下方式找到提高可用性和性能的机会 实现更轻量级、更安全的RESTful集成 比基于SOAP的web服务更灵活。支持无状态通信 在客户端和服务器之间。控制客户端和服务器的实现。 在中使用基于令牌或用户凭据的内置身份验证 HTTP头。在iPhone和iPhone等平台上开发移动客户端 集成外部基于Web的应用程序,如Gmail或 谷歌应用。为基于Suitelet的用户界面创建后端。 RESTlet为熟悉 SuiteScript比NetSuite基于SOAP的web支持更多的行为 服务,仅限于定义为SuiteTalk操作的服务。 restlet也比Suitelets更安全,后者是可用的 对于未登录的用户。有关更详细的比较,请参阅RESTlet 与其他NetSuite集成选项相比 在您的情况下,这将是一个几乎不需要创建的脚本,它将收集结果并返回JSON编码(最简单)或任何您需要的格式 与编写脚本相比,您可能要花费更多的时间来实现基于令牌的身份验证(TBA) [Update]添加一些与我在下面评论中提到的内容相关的代码示例: 请注意,SuiteTalk代理对象模型令人沮丧,因为它 缺乏继承性,它可以很好地利用。所以你以 像SafeTypeCastName()这样的代码。反射是最好的工具之一 在我的工具箱中,当涉及到使用SuiteTalk代理时 例如,所有*RecordRef类型都有公共字段/道具,因此反射 保存您在整个位置进行的类型检查,以便使用您要创建的对象 我怀疑你有
公共静态TType GetProperty(对象记录,字符串propertyID)
{
PropertyInfo pi=record.GetType().GetProperty(propertyID);
返回(TType)pi.GetValue(记录,空);
}
公共静态字符串GetInternalID(记录)
{
返回GetProperty(记录“internalId”);
}
公共静态字符串GetInternalID(BaseRef recordRef)
{
PropertyInfo pi=recordRef.GetType().GetProperty(“internalId”);
返回(字符串)pi.GetValue(recordRef,null);
}
公共静态CustomFieldRef[]GetCustomFieldList(记录)
{
返回GetProperty(记录,CustomFieldPropertyName);
}
自2016\u 2版起,SuiteTalk不支持已删除记录
记录,这意味着您无法运行已保存的搜索并下拉结果
这在与NetSuite集成时并不少见:(
在这种情况下,我通常会创建一个RESTlet(NetSuite想要的RESTful API框架)SuiteScript来运行搜索(或者使用SuiteScript执行任何可能的操作,而使用SuiteTalk执行任何不可能的操作)并返回结果
从文件中:
您可以部署与NetSuite数据交互的服务器端脚本
遵循RESTful原则。RESTlet将SuiteScript API扩展到
允许与NetSuite进行自定义集成。使用
RESTlet包括以下功能:
通过以下方式找到提高可用性和性能的机会
实现更轻量级、更安全的RESTful集成
比基于SOAP的web服务更灵活。支持无状态通信
在客户端和服务器之间。控制客户端和服务器的实现。
在中使用基于令牌或用户凭据的内置身份验证
HTTP头。在iPhone和iPhone等平台上开发移动客户端
集成外部基于Web的应用程序,如Gmail或
谷歌应用。为基于Suitelet的用户界面创建后端。
RESTlet为熟悉
SuiteScript比NetSuite基于SOAP的web支持更多的行为
服务,仅限于定义为SuiteTalk操作的服务。
restlet也比Suitelets更安全,后者是可用的
对于未登录的用户。有关更详细的比较,请参阅RESTlet
与其他NetSuite集成选项相比
在您的情况下,这将是一个几乎微不足道的脚本来创建,它将收集
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);
}
//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();