Netsuite SuiteTalk-通过PHP为客户请求发票列表


Netsuite SuiteTalk - requesting list of invoices for a customer via PHP

我正在使用Netsuite PHP Toolkit来获取客户的发票列表。我可以毫无问题地打电话(使用TransactionSearch),但我很难理解如何获取发票的所有详细信息,即发票"标题"详细信息(如总额、货币、主菜单行等)以及每行项目的详细信息(净值、应纳税额、项目等)。

我尝试了几种方法:

  1. TransactionSearchAdvanced,指定了返回列,并将returnSearchColumns首选项设置为"false"。这会返回所有单独的行(哇!),但货币和术语等内容并没有展开——你只需要指定internalId,而不是实际的文本(或符号)。此外,对于TSA,您真的必须指定您想要的每一列吗?即,默认的真的只是一组空字段吗?难道没有一种方法可以说"给我每张发票所有行的所有详细信息吗?

  2. TransactionSearch,returnSearchColumns首选项设置为"true"。这提供了一个单一发票类型记录的列表,其中正确填充了所有货币和术语,但令人沮丧的是,没有一个单独的行项目。这更像是一个总结。

因此,我只剩下几个选项,它们都不太令人满意,即:

  1. 对所有发票执行两个调用并合并数据。这些搜索需要很长时间(性能对我来说是另一个难题,所以我真的不想这么做

  1. 找出一种请求条款、货币等数据的方法,以及获取发票行的方法

我不知道你应该怎么做,在互联网上也找不到任何关于它的信息。这是我用过的最糟糕的接口之一(我用过一些非常糟糕的接口)。

任何帮助都将不胜感激。

就像你一样,我开始尝试使用Web服务API(也称为SuiteTalk)。大多数情况下,这是一次沮丧的锻炼,因为最终我发现,我根本无法和他们一起做我想做的事。这和性能都很糟糕,即使我的项目运行正常,这也会扼杀我的项目。

和Faz一样,我发现使用RESTlets和Saved Searches的组合比使用web服务框架更容易、更快。

基本上将您的问题分解为以下几个部分:

  • 保存的搜索,返回您想要的结果(跟踪您稍后需要的内部ID)
  • RESTlet它只是一个Javascript文件,定义了用于返回搜索结果的函数
  • 调用RESTlet并获取结果的客户端代码

第一部分:因此,保存的搜索非常简单。我假设你可以做到这一点,而且你实际上可以在一个地方获得你想要的所有字段。根据我的经验,情况并非总是如此。

第二部分:RESTlet涉及更多的步骤,尽管它实际上是一件非常简单的事情。让它变得复杂的是将它上传并部署在NetSuite网站上。如果你还没有安装NetSuite IDE,我强烈建议你安装它,哪怕只是为了让部署脚本更容易一点。自动完成和工具提示也非常有用。

例如,这里是我用来从我关心的搜索中获得结果的代码。这是根据某个灵魂在互联网上的帖子改编的,但我忘了在哪里:

function getSearchResults(){
var max_rows = 1000;
var search_id = 1211;
var search = nlapiLoadSearch(null, search_id);
var results = search.runSearch();
var rows = [];
// add starting point for usage
var context = nlapiGetContext();
startingUsage = context.getRemainingUsage();
rows.push(["beginning usage", startingUsage]);
// now create the collection of result rows in 1000 row chunks
var index = 0;
do{
    var chunk = results.getResults(index, index+1000);
    if( ! chunk ) break;
    chunk.forEach( function(row){
        rows.push(row);
        index++;
    });
}while( chunk.length === max_rows);
// add a line that returns the remaining usage for this RESTlet
context = nlapiGetContext();
var remainingUsage = context.getRemainingUsage();
rows.push(["remaining usage",remainingUsage]);
// send back the rows
return rows;
}

这是你通过传递你保存的搜索内部ID:来做好准备的地方

var search = nlapiLoadSearch(null, SEARCH_ID);
var resultSet = search.runSearch();

然后代码重复调用getResults()以获得1000个结果的块,这是NetSuite的限制。一旦你写了这篇文章,你必须将脚本上传到NetSuite并配置和部署它。最重要的部分是告诉它给每个动词分配什么功能。在本例中,我指定GET执行getSearchResults。这里有很多工作要做,我不会把所有的都打出来,因为这部分值得你花时间学习。至少足以让IDE为你做这件事=D。您可以在"RESTlets简介"指南中阅读有关它的全部内容。

第三部分。客户端代码可以是任何你想要的,以你喜欢的方式进行REST。就我个人而言,我喜欢Python,因为请求库非常棒。下面是一些Python代码示例:

import requests
import json
url = 'https://rest.sandbox.netsuite.com/app/site/hosting/restlet.nl?script=123&deploy=1'
headers = {'Content-Type': 'application/json', 'Authorization':'NLAuth nlauth_account=1234567, nlauth_email=someone@somewhere.com, nlauth_signature=somepassword, nlauth_role=3'}
resp = requests.get(url, headers=headers)
data = resp.json()

URL将作为RESTlet部署的一部分显示给您。然后,你就可以对返回的数据做你想做的事情了。

所以我建议你花时间在上

  • 设置NetSuite IDE
  • 获取和阅读SuiteScript开发人员参考文档
  • 找到用您选择的语言创建REST客户端代码的好方法

我希望这能有所帮助。

我在Netsuite中创建了一个保存的搜索,并使用restlet调用该搜索。有了它,它非常轻量级,您可以在保存的搜索中原样调用数据。

性能方面,Restlet比Web服务要好得多。

创建一个新的suitelet脚本并部署

下面的脚本将按客户内部id 给您发票列表

function customSearch(request, response) {
	var rows = [];	
	var result;
	var filters = [];
	//9989 is customer internal id you can add more
	// by pushing additional ids to array
    filters.push(new nlobjSearchFilter('entity', null, 'anyOf', [9989] ));
	var invoiceList = nlapiSearchRecord('invoice', null, filters, []);
	// by default record limit is 1000 
	// taking 100 records 
  for (var i = 0; i < Math.min(100, invoiceList.length); i++)
    {
        if (parseInt(invoiceList[i].getId()) > 0) {
            recordid = invoiceList[i].getId();
            try {
               result=  nlapiLoadRecord(invoiceList[i].getRecordType(), recordid);   
			   // pushing in to result
			   rows.push(result);			
            } catch (e) {
                if (e instanceof nlobjError) {
                    nlapiLogExecution('DEBUG', 'system error', e.getCode() + ''n' + e.getDetails());
                } else {
                    nlapiLogExecution('DEBUG', 'unexpected error', e.toString());
                }
            }
        } 
    }
	response.setContentType('JSON');
	response.write(JSON.stringify({'records' : rows}));
	return;
}

    } 
}
response.setContentType('JSON');
response.write(JSON.stringify({'records' : rows}));
return;

}

以下是我获得客户发票的方法:

    public function getCustomerInvoices($customer_id)
{
    $service = new NetSuiteService($this->config);
    $customerSearchBasic = new CustomerSearchBasic();
    $searchValue = new RecordRef();
    $searchValue->type = 'customer';
    $searchValue->internalId = $customer_id;
    $searchMultiSelectField = new SearchMultiSelectField();
    setFields($searchMultiSelectField, array('operator' => 'anyOf', 'searchValue' => $searchValue));
    $customerSearchBasic->internalId = $searchMultiSelectField;
    $transactionSearchBasic = new TransactionSearchBasic();
    $searchMultiSelectEnumField = new SearchEnumMultiSelectField();
    setFields($searchMultiSelectEnumField, array('operator' => 'anyOf', 'searchValue' => "_invoice"));
    $transactionSearchBasic->type = $searchMultiSelectEnumField;
    $transactionSearch = new TransactionSearch();
    $transactionSearch->basic = $transactionSearchBasic;
    $transactionSearch->customerJoin = $customerSearchBasic;
    $request = new SearchRequest();
    $request->searchRecord = $transactionSearch;
    $searchResponse = $service->search($request);
    return $searchResponse->searchResult->recordList;
}