【问题标题】:Netsuite SuiteTalk - requesting list of invoices for a customer via PHPNetsuite SuiteTalk - 通过 PHP 为客户请求发票列表
【发布时间】:2014-11-12 11:34:18
【问题描述】:

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

我尝试了几种方法:

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

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

所以我有两个选择,都不是很可口,即:

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

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

我不知道您应该如何执行此操作,并且在 Internet 上找不到任何相关信息。这是我用过的最糟糕的接口之一(而且我用过一些非常糟糕的接口)。

任何帮助将不胜感激。

【问题讨论】:

    标签: php netsuite


    【解决方案1】:

    就像您一样,我开始尝试使用 Web 服务 API(又名 SuiteTalk)来做事。大多数情况下,这是一种沮丧的练习,因为最终我发现我无法对他们做我想做的事。那和性能很差,即使它运行正常也会杀死我的项目。

    与 Faz 一样,我发现使用 RESTlet 和 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,因为 requests 库非常棒。 下面是一些 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 客户端代码的好方法。

    希望对你有帮助。

    【讨论】:

      【解决方案2】:

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

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

      【讨论】:

      • 嗨,法兹,谢谢。我创建了一个已保存的搜索,但如何通过 PHP 使用 restlet?仍然使用网络服务来调用搜索。
      • 首先您需要创建一个套件脚本(restlet)。使用 nlapiLoadSearch 或 nlapiSearchrecord 执行保存的搜索。将结果转换为您想要的任何格式并从 restlet 返回。接下来,您需要使用客户端程序(例如 Java)通过 HttpPost 调用 reslet。
      【解决方案3】:

      创建一个新的套件脚本并部署

      以下脚本将按客户内部 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;
      

      }

      【讨论】:

        【解决方案4】:

        这是我获取客户发票的方法:

            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;
        
        }
        

        【讨论】:

        • 这一切都很好,但如果您只想要状态为 open 的发票怎么办?
        猜你喜欢
        • 1970-01-01
        • 2020-03-11
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多