2016-11-17 4 views
0

Как получить результаты «Сохраненного поиска» типа «Удаленная запись» в NetSuite? Другие типы поиска очевидны (CustomerSearchAdvanced, ItemSearchAdvanced и т. Д.), Но у этого, похоже, нет ссылки в Интернете, а только документации около deleting records, не выполняются сохраненные поиски на них.NetSuite SuiteTalk: Сохраненный поиск «Удаленная запись» Тип

Update 1

я должен уточнить немного больше того, что я пытаюсь сделать. В NetSuite вы можете запускать (и сохранять) сохраненный поиск по типу записи «Удаленная запись», я считаю, что вы можете получить доступ к не менее чем 5 столбцам (исключая определенные пользователем) через этот процесс через веб-интерфейс:

  • Дата Удаляется
  • удален
  • Контекст
  • Тип записи
  • Имя

Вы также сможете настроить критерии поиска как часть «Сохраненного поиска». Я хотел бы получить доступ к ряду этих «сохраненных поисков», которые уже присутствуют в моей системе, используя уже установленные критерии поиска и извлекающие данные из всех 5 отображаемых столбцов.

ответ

2

Запись в формате Deleted Record не поддерживается в SuiteTalk версии 2016_2, что означает, что вы не можете запустить Сохраненный поиск и вывести результаты.

Это не редкость при интеграции с NetSuite. :(

Что я всегда делал в этих ситуациях, это создать RESTlet (инфраструктуру API RESTful NetSuite), который будет запускать поиск (или делать все возможное с помощью SuiteScript и не возможно с помощью SuiteTalk) и возвращать результаты .

Из документации:

Вы можете развернуть серверные сценарии, которые взаимодействуют с данными NetSuite следующие RESTful принципы RESTlets расширить API SuiteScript для позволяют пользовательские интеграции с NetSuite Некоторые преимущества использования .. RESTlets включают в себя возможность:

Найти возможности для повышения удобства и производительности, используя , реализуя интеграцию RESTful, которая является более легкой и гибкой, чем веб-службы на основе SOAP. Поддержка безстоящих сообщений между клиентом и сервером. Контролируйте реализацию клиента и сервера. Используйте встроенную аутентификацию на основе токенов или учетных данных пользователя в HTTP-заголовке . Разработка мобильных клиентов на таких платформах, как iPhone и Android. Интеграция внешних веб-приложений, таких как Gmail или Google Apps. Создайте серверы для пользовательских интерфейсов на основе Suitelet. RESTлеты предлагают легкость для разработчиков, знакомых с SuiteScript, и поддерживают больше поведения, чем сетевые службы NetSuite SOAP , которые ограничены функциями, которые называются операциями SuiteTalk. RESTлеты также более безопасны, чем Suitelets, которые становятся доступными пользователям без регистрации. Более подробное сравнение см. В разделе RESTлеты и другие варианты интеграции NetSuite.

В вашем случае это будет почти тривиальный скрипт для создания, он будет собирать результаты и возвращать JSON-кодированный (самый простой) или любой другой формат, который вам нужен.

Скорее всего, вы потратите больше времени на работу с аутентификацией на основе токенов (TBA), чем написание сценария.

[Update] Добавление некоторых примеров кода, связанные с тем, что я говорил в комментариях ниже:

Обратите внимание, что прокси-модель объекта 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); 
} 
+0

Да, это то, как вы получаете все удаленные записи, но вы не можете получить результаты «Сохраненного поиска» на «Удаленные записи». Не уверен, что это сработает для моего конкретного сценария ... И где источник вашей документации? –

+0

Я не понимаю, что вы хотите сделать. После удаления записей вы не можете получить доступ к записи, все, что вы можете сделать, это поиск по метаданным о действии удаления для целей аудита («Кто мы стреляем !!?») Документация из справки NetSuite, даже лучше представляет собой Руководство по платформе SuiteTalk PDF, которое доступно в SuiteAnswers, а также в базовой справочной системе. Чтобы получить доступ к справки и SuiteAnswers, вам необходимо войти в NetSuite. –

+0

Я добавил обновление к моему вопросу, надеюсь, он может прояснить, чего я пытаюсь выполнить. Может быть, я могу добавить некоторые снимки экрана, если это недостаточно ясно, для некоторых из них я предполагаю, что это немного для понимания, не видя веб-интерфейс NetSuite. –

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, и это возвращает только три колонки:

  • Дата Удаляется
  • Record Type (Не форматируется таким же образом, что и Веб-интерфейс пользователя)
  • Имя
+0

Ницца. Обратите внимание, что объектная модель прокси-сервера SuiteTalk расстраивает то, что ей не хватает наследования, что она может так хорошо использовать. Таким образом, вы заканчиваете с кодом как ваш 'SafeTypeCastName()'. Отражение - один из лучших инструментов в моей панели инструментов, когда речь заходит о работе с прокси-серверами SuiteTalk. Например, все типы * RecordRef имеют общие поля/реквизиты, поэтому отражение сохраняет вашу проверку типов повсюду, чтобы работать с объектом, который, как вы подозреваете. –

+0

Невозможно поместить многострочный код в комментарии, поэтому я добавил свой ответ несколькими примерами отраженного материала, о котором я говорил. –

 Смежные вопросы

  • Нет связанных вопросов^_^