Search code examples
web-servicessoapnetsuiteadvanced-search

Convert NetSuite TransactionSearch into Advanced Search with only internalId column to return


I've got the ordinary Transaction Search, SOAP looks like this:

<?xml version="1.0" encoding="UTF-8"?>
<search xsi:type="sales:TransactionSearch" 
        xmlns="urn:messages_2013_1.platform.webservices.netsuite.com" 
        xmlns:sales="urn:sales_2013_1.transactions.webservices.netsuite.com" 
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
        xmlns:common="urn:common_2013_1.platform.webservices.netsuite.com" 
        xmlns:core="urn:core_2013_1.platform.webservices.netsuite.com">
    <sales:basic xsi:type="common:TransactionSearchBasic" xmlns:common="urn:common_2013_1.platform.webservices.netsuite.com">
        <common:type operator="anyOf" xsi:type="core:SearchEnumMultiSelectField">
            <core:searchValue xsi:type="xsd:string">_invoice</core:searchValue>
        </common:type>
        <common:customFieldList xsi:type="core:SearchCustomFieldList">          
            <core:customField operator="anyOf" xsi:type="core:SearchMultiSelectCustomField" internalId="custbodyintegrationstatus">
                <core:searchValue xsi:type="core:ListOrRecordRef" internalId="1" name="customlistintegrationstatuses"></core:searchValue>
            </core:customField>                 
        </common:customFieldList>
    </sales:basic>
</search>

This search works now in production, but sometimes when I run this search I get the UNEXPECTED_ERROR in result. So the guys from NetSuite recommended to use advanced search instead. The idea is to find all the invoices with a pre-defined value of custom field called custbodyintegrationstatus. The custom field is a list of values and I need to select the value with internalId = "1". The only thing I want in response is internalId for each found invoice. The problem is I don't know how to do this. Here's my code (C#):

TransactionSearchAdvanced advancedSearchEntity = new TransactionSearchAdvanced();

TransactionSearch ts = new TransactionSearch();
TransactionSearchBasic tsb = new TransactionSearchBasic();
// condition 1: on SO only
SearchEnumMultiSelectField semsfTranType = new SearchEnumMultiSelectField();
semsfTranType.operatorSpecified = true;
semsfTranType.@operator = SearchEnumMultiSelectFieldOperator.anyOf;
semsfTranType.searchValue = new[]{"_salesOrder"};


SearchMultiSelectCustomField spsIntegrationStatusField = new SearchMultiSelectCustomField();
spsIntegrationStatusField.operatorSpecified = true;
spsIntegrationStatusField.@operator = SearchMultiSelectFieldOperator.anyOf;
spsIntegrationStatusField.internalId = "custbodyintegrationstatus";

ListOrRecordRef searchRecordEntity = new ListOrRecordRef();
searchRecordEntity.name = "customlistintegrationstatuses";
searchRecordEntity.internalId = "1";        // indicates record status - ready / test ready / etc
spsIntegrationStatusField.searchValue = new[] { searchRecordEntity };

tsb.type = semsfTranType;
tsb.customFieldList = new SearchCustomField[] { spsIntegrationStatusField };

TransactionSearchRow tsr = new TransactionSearchRow();
TransactionSearchRowBasic tsrb = new TransactionSearchRowBasic();

SearchColumnSelectField[] selcols = new SearchColumnSelectField[1];
selcols[0] = new SearchColumnSelectField();

// Set return columns 
tsrb.internalId = selcols;
tsr.basic = tsrb;

ts.basic = tsb;
advancedSearchEntity.criteria = ts;
advancedSearchEntity.columns = tsr; //note - columns previously defined above.
_service.searchPreferences.returnSearchColumns = true;
SearchResult savedSearchResult = _service.search(advancedSearchEntity);

The SOAP request in WebServices Usage logs looks like this:

<search xmlns="urn:messages_2013_1.platform.webservices.netsuite.com">
    <searchRecord xsi:type="q1:TransactionSearchAdvanced" xmlns:q1="urn:sales_2013_1.transactions.webservices.netsuite.com">
        <q1:criteria>
            <q1:basic>
                <type operator="anyOf" xmlns="urn:common_2013_1.platform.webservices.netsuite.com">
                    <searchValue xmlns="urn:core_2013_1.platform.webservices.netsuite.com">_salesOrder</searchValue>
                </type>
                <customFieldList xmlns="urn:common_2013_1.platform.webservices.netsuite.com">
                    <customField operator="anyOf" internalId="custbodyintegrationstatus" xsi:type="SearchMultiSelectCustomField" xmlns="urn:core_2013_1.platform.webservices.netsuite.com">
                        <searchValue internalId="1">
                            <name>customlistintegrationstatuses</name>
                        </searchValue>
                    </customField>
                </customFieldList>
            </q1:basic>
        </q1:criteria>
        <q1:columns>
            <q1:basic>
                <internalId xmlns="urn:common_2013_1.platform.webservices.netsuite.com"/>
            </q1:basic>
        </q1:columns>
    </searchRecord>
</search>

And here's the response:

<searchResponse xmlns="urn:messages_2013_1.platform.webservices.netsuite.com">
    <platformCore:searchResult xmlns:platformCore="urn:core_2013_1.platform.webservices.netsuite.com">
        <platformCore:status isSuccess="true"/>
        <platformCore:totalRecords>108956</platformCore:totalRecords>
        <platformCore:pageSize>5</platformCore:pageSize>
        <platformCore:totalPages>21792</platformCore:totalPages>
        <platformCore:pageIndex>1</platformCore:pageIndex>
        <platformCore:searchId>WEBSERVICES_TSTDRV961603_060120141461034810519911044_b227f55</platformCore:searchId>
        <platformCore:searchRowList>
            <platformCore:searchRow xsi:type="tranSales:TransactionSearchRow" xmlns:tranSales="urn:sales_2013_1.transactions.webservices.netsuite.com">
                <tranSales:basic xmlns:platformCommon="urn:common_2013_1.platform.webservices.netsuite.com">
                    <platformCommon:internalId>
                        <platformCore:searchValue internalId="134200"/>
                    </platformCommon:internalId>
                </tranSales:basic>
            </platformCore:searchRow>
            <platformCore:searchRow xsi:type="tranSales:TransactionSearchRow" xmlns:tranSales="urn:sales_2013_1.transactions.webservices.netsuite.com">
                <tranSales:basic xmlns:platformCommon="urn:common_2013_1.platform.webservices.netsuite.com">
                    <platformCommon:internalId>
                        <platformCore:searchValue internalId="134200"/>
                    </platformCommon:internalId>
                </tranSales:basic>
            </platformCore:searchRow>
            <platformCore:searchRow xsi:type="tranSales:TransactionSearchRow" xmlns:tranSales="urn:sales_2013_1.transactions.webservices.netsuite.com">
                <tranSales:basic xmlns:platformCommon="urn:common_2013_1.platform.webservices.netsuite.com">
                    <platformCommon:internalId>
                        <platformCore:searchValue internalId="134200"/>
                    </platformCommon:internalId>
                </tranSales:basic>
            </platformCore:searchRow>
            <platformCore:searchRow xsi:type="tranSales:TransactionSearchRow" xmlns:tranSales="urn:sales_2013_1.transactions.webservices.netsuite.com">
                <tranSales:basic xmlns:platformCommon="urn:common_2013_1.platform.webservices.netsuite.com">
                    <platformCommon:internalId>
                        <platformCore:searchValue internalId="134200"/>
                    </platformCommon:internalId>
                </tranSales:basic>
            </platformCore:searchRow>
            <platformCore:searchRow xsi:type="tranSales:TransactionSearchRow" xmlns:tranSales="urn:sales_2013_1.transactions.webservices.netsuite.com">
                <tranSales:basic xmlns:platformCommon="urn:common_2013_1.platform.webservices.netsuite.com">
                    <platformCommon:internalId>
                        <platformCore:searchValue internalId="134255"/>
                    </platformCommon:internalId>
                </tranSales:basic>
            </platformCore:searchRow>
        </platformCore:searchRowList>
    </platformCore:searchResult>
</searchResponse>

It is obvious that I'm doing something wrong, even not unqueue internalIds in search rows indicates that. So, tell me please what is wrong. Both SOAP or any C#/Java/etc code sample will be very helpful.


Solution

  • Pipechang was right. The correct SOAP request looks like this:

    <search xmlns="urn:messages_2013_1.platform.webservices.netsuite.com">
                <searchRecord xsi:type="q1:TransactionSearchAdvanced" xmlns:q1="urn:sales_2013_1.transactions.webservices.netsuite.com">
                    <q1:criteria>
                        <q1:basic>
                            <mainLine xmlns="urn:common_2013_1.platform.webservices.netsuite.com">
                                <searchValue xmlns="urn:core_2013_1.platform.webservices.netsuite.com">true</searchValue>
                            </mainLine>
                            <type operator="anyOf" xmlns="urn:common_2013_1.platform.webservices.netsuite.com">
                                <searchValue xmlns="urn:core_2013_1.platform.webservices.netsuite.com">_salesOrder</searchValue>
                            </type>
                            <customFieldList xmlns="urn:common_2013_1.platform.webservices.netsuite.com">
                                <customField operator="anyOf" internalId="custbodyintegrationstatus" xsi:type="SearchMultiSelectCustomField" xmlns="urn:core_2013_1.platform.webservices.netsuite.com">
                                    <searchValue internalId="2">
                                        <name>customlistintegrationstatuses</name>
                                    </searchValue>
                                </customField>
                            </customFieldList>
                        </q1:basic>
                    </q1:criteria>
                    <q1:columns>
                        <q1:basic>
                            <internalId xmlns="urn:common_2013_1.platform.webservices.netsuite.com"/>
                        </q1:basic>
                    </q1:columns>
                </searchRecord>
            </search>