Я использую Netsuite PHP Toolkit, чтобы попытаться получить список счетов для клиента. Я могу сделать звонок (используя TransactionSearch) без проблем, но я изо всех сил пытаюсь понять, как я должен получить все детали счета-фактуры — то есть детали заголовка счета (например, общая сумма, валюта, строка главного меню и т. д.), а также детали каждой позиции (чистая стоимость, налогооблагаемая стоимость, позиция и т. д.).
Я попробовал несколько подходов:
TransactionSearchAdvanced, с указанием возвращаемых столбцов и параметром returnSearchColumns, установленным на «false». Это возвращает все отдельные строки (woo!), Но такие вещи, как валюта и термин, не раскрываются — вы просто получаете innerId, а не фактический текст (или символ). Кроме того, с TSA, вы действительно нужно указать каждый столбец, который вы хотите? т.е. по умолчанию действительно просто пустой набор полей? Разве нет способа просто сказать «дайте мне все детали для всех строк каждого счета?»
TransactionSearch с параметром returnSearchColumns, установленным в значение «true». Это дает список отдельных записей типа «Счет-фактура», в котором правильно указаны все данные о валюте и терминах, но, к сожалению, нет ни одной из отдельных позиций. Это скорее резюме.
Таким образом, у меня осталось несколько вариантов, ни один из которых не очень приятный, а именно:
или же
Я понятия не имею, как ты должен это делать, и не могу найти в Интернете ничего об этом. Это один из худших интерфейсов, которые я использовал (и я использовал несколько довольно плохих).
Любая помощь будет принята с благодарностью.
Так же, как и вы, я начал пытаться делать что-то с помощью API веб-сервисов (или SuiteTalk). В основном это было разочаровывающее упражнение, потому что в итоге я обнаружил, что я не могу делать с ними то, что хочу. Это и производительность была довольно плохой, что убило бы мой проект, даже если бы он работал должным образом.
Как и в случае с Faz, я обнаружил, что гораздо проще и быстрее использовать комбинацию RESTlets и сохраненных поисков, чем работать со структурой веб-сервисов.
В основном разбейте вашу проблему на следующие части:
Часть I:
Таким образом, сохраненный поиск довольно прост. Я собираюсь предположить, что вы можете сделать это, а также что вы можете получить все поля, которые вы хотите, в одном месте. Это не всегда так в моем опыте.
Часть II:
RESTlet включает в себя гораздо больше шагов, хотя это действительно очень простая вещь. Что делает его сложным, так это его загрузка и развертывание на вашем сайте NetSuite. Если у вас еще не установлена среда IDE NetSuite, я очень рекомендую ее, чтобы сделать развертывание сценариев немного проще. Автозаполнение и всплывающие подсказки также чрезвычайно полезны.
Например, вот код, который я использую, чтобы получить результаты поиска, который меня волновал. Это было адаптировано из сообщений какой-то души в Интернете, но я забыл, где:
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;
}
Вот где вы получаете информацию, передавая свой внутренний идентификатор сохраненного поиска:
var search = nlapiLoadSearch(null, SEARCH_ID);
var resultSet = search.runSearch();
Затем код повторно вызывает getResults (), чтобы получить фрагменты с 1000 результатами, это ограничение NetSuite. После того, как вы написали это, вы должны загрузить скрипт в NetSuite, настроить и развернуть его. Самая важная часть рассказывает, какую функцию назначить каждому глаголу. В этом случае я назначил GET для выполнения getSearchResults. Здесь предстоит проделать большую работу, и я не собираюсь все это печатать, потому что стоит потратить время на изучение этой части. По крайней мере, достаточно, чтобы заставить IDE сделать это за вас = D. Вы можете прочитать все об этом в руководстве «Введение в RESTlets».
Часть III
Код клиента может быть любым, что вы хотите, что делает 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, [email protected], nlauth_signature=somepassword, nlauth_role=3'}
resp = requests.get(url, headers=headers)
data = resp.json()
URL будет отображаться вам как часть развертывания RESTlet. Тогда вам решать, что вы хотите с данными, которые возвращаются.
Так что вещи, с которыми я бы посоветовал вам провести время, были бы
Надеюсь, это поможет.
Я создал сохраненный поиск в Netsuite и вызвал его с помощью рестлета. При этом он довольно легкий, и вы можете вызывать данные, как в сохраненном поиске.
Мудрый по производительности рестлет намного лучше, чем веб-сервисы.
Создайте новый скрипт-пакет и разверните
Ниже скрипт даст вам список счетов по внутреннему идентификатору клиента
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;
}
Вот что у меня есть для получения счетов клиента:
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;
}