How can I clear an external ID on a record in NetSuite? - netsuite

I need to clear/reset the external ID on a record in NetSuite, but nothing I do is working.
Some of the InventoryItem records are incorrectly mapped to records in another system. I have an application that can sync up the two systems, but I need to clear NetSuite's external IDs first.
Responses don't really need to be SOAP-specific. If you know how to do it with some specific NetSuite/SuiteTalk client, that might point me in the right direction.
What I've Tried
First up, I tried using the nullFieldList... but maybe it doesn't work because externalId is an attribute, not an element?
<messages:update>
<messages:record internalId="7777" xsi:type="accounting:InventoryItem">
<core:nullFieldList xsi:type="core:NullField">
<core:name>externalId</core:name>
</core:nullFieldList>
</messages:record>
</messages:update>
The external ID is just a string, so I tried just setting it to blank. Didn't work either.
<messages:update>
<messages:record internalId="7777" xsi:type="accounting:InventoryItem">
<accounting:externalId></accounting:externalId>
</messages:record>
</messages:update>
I even tried setting the external ID to 0, but I get back a "not unique identifier" error
<messages:update>
<messages:record internalId="7777" xsi:type="accounting:InventoryItem">
<accounting:externalId>0</accounting:externalId>
</messages:record>
</messages:update>
Other Info
I'm using NetSuite's SOAP API v.2013_1
When I say "it doesn't work", I mean: after I do the update, I get a success response similar to the following:
<readResponse>
<platformCore:status isSuccess="true" xmlns:platformCore="urn:core_2013_1.platform.webservices.netsuite.com"/>
<record internalId="7777" externalId="42" xsi:type="listAcct:InventoryItem" xmlns:listAcct="urn:accounting_2013_1.lists.webservices.netsuite.com">
<!-- snip -->
</record>
</readResponse>

If you are using scripts in netsuite you can run a scheduled script to clear records in NS by loading each record and setting the externalid to '' using the following simple code:
var rec= nlapiLoadRecord(type,id);
rec.setFieldValue('externalid','');
nlapiSubmitRecord(rec);
This seemed to work for me in my enviornment which was on 2015.2.

Unfortunately my understanding is that once you set an externalid you cannot clear it, you can set it to another value, but not back to null. I have experienced this both using SuiteScript as well as a Boomi process that uses the 2014.1 endpoint. This may have changed in the recent releases, as I have not tried it recently with SuiteScript nor with a newer endpoint.

You can eliminate the externalId on a record once it's been set. Here's an example using the NetSuite gem:
ns_customer = NetSuite::Records::Customer.get external_id: 'ext_id'
ns_customer.external_id = ''
ns_customer.update
Here's the corresponding XML for update:
<env:Body>
<platformMsgs:update>
<platformMsgs:record xsi:type="listRel:Customer" platformMsgs:internalId="199113" platformMsgs:externalId=""/>
</platformMsgs:update>
</env:Body>

I have had to attempt this before as well. I know the pains you describe. I ended up putting a "-" in front of my external ID to unlink it between my systems. You can do this in SOAP or even as a simple one time csv upload. As it was one time, I did csv.

Related

Multiple member mdx query returns error (permission to access the specified member)

I want to mention that I'm new to SSAS and MDX.
In the past several days I've been dwelling with an excel generated query that errors out.
The problem is that a query is generated by excel when trying to read data from an online cube data source preventing other reads for that cube. The query is executed against an AZURE cube and I manage to profile it and get the following query:
with set __XLUniqueNames as {[Stores].[Chain].[Chain].&[SuperBrugsen], [Stores].[Chain].[Chain].&[Salling], [Stores].[Chain].[Chain].&[SuperBrugsen] }
set __XLDrilledUp as
Generate(__XLUniqueNames,
{ IIF([Stores].[Chain].currentmember.LEVEL_NUMBER <= 2147483647,
[Stores].[Chain].currentmember,
Ancestor([Stores].[Chain].currentmember,
[Stores].[Chain].currentmember.LEVEL_NUMBER - 2147483647)) } )
member [Measures].__XLPath as
Generate(
Ascendants([Stores].[Chain].currentmember),
[Stores].[Chain].currentmember.unique_name,
"__XLPSEP")
select { [Measures].__XLPath } on 0,
__XLDrilledUp on 1
from [SomeCube]
cell properties value
Each time query contains more than one member (an existing member from that dimension) it errors out with this message:
"Either you do not have permission to access the specified member or the specified member does not exist.".
What I have tried:
First, I tried to identify a pattern of member combinations that errors out, with no luck. It seems that for some certain members I get the error and for some, It doesn't. For single member, duplicate members and combination of members that don't exist in the cube it doesn't error.
Second, I did try the query on a different cube (on-premise SSAS) and I didn't get the error.
Third, by modifying the connection string I tried to make Excel ignore the missing members in the hope it will work using the "MDXMissingMemberMode" flag set to Ignore. I didn't work.
Forth, I tried to dissect the query to see which clause was giving the error. With my limited knowledge of MDX I suspect that "currentmember" with its "LEVEL_NUMBER" property is at fault. My guess is that it fails to get the current member for the next member in the set.
Fifth, the last thing and the longest, by accident I discovered that in SSMS you can execute a query in an mdx session (Right-click on cube -> New query) or you can open the cube in browse mode (Right-click on cube -> Browse) which results in a UI similar to the mdx query like.
No here comes the surprise, in this browse "mode" my query executes successfully each time. Intrigued by this I started to profile the request and see what was different. The difference was some additional xml structure like a list with properties. Seeing this I figured I could manipulate my connection string from excel to send some of the properties to make it work, but in the end, I didn't work.
Additional proprieties that worked:
<PropertyList xmlns="urn:schemas-microsoft-com:xml-analysis">
<Catalog>SomeCatalog</Catalog>
<ShowHiddenCubes>true</ShowHiddenCubes>
<SspropInitAppName>Microsoft SQL Server Management Studio</SspropInitAppName>
<Timeout>3600</Timeout>
<LocaleIdentifier>1033</LocaleIdentifier>
<ClientProcessID>24400</ClientProcessID>
<DataSourceInfo/>
<Format>Tabular</Format>
<Content>Schema</Content>
<DbpropMsmdFlattened2>true</DbpropMsmdFlattened2>
<ReturnCellProperties>true</ReturnCellProperties>
<DbpropMsmdActivityID>2309dfa2-3607-41b2-9446-8ece2f5ababa</DbpropMsmdActivityID>
<DbpropMsmdCurrentActivityID>2309dfa2-3607-41b2-9446-8ece2f5ababa</DbpropMsmdCurrentActivityID>
<DbpropMsmdRequestID>d3dbd079-5ca7-496c-ab55-afea71889238</DbpropMsmdRequestID>
</PropertyList>
Additional properties that didn't work:
<PropertyList xmlns="urn:schemas-microsoft-com:xml-analysis">
<Catalog>SomeCatalog</Catalog>
<SspropInitAppName>Microsoft SQL Server Management Studio - Query</SspropInitAppName>
<LocaleIdentifier>1033</LocaleIdentifier>
<ClientProcessID>24400</ClientProcessID>
<DataSourceInfo/>
<Format>Native</Format>
<AxisFormat>TupleFormat</AxisFormat>
<Content>SchemaData</Content>
<Timeout>0</Timeout>
<DbpropMsmdActivityID>e5e75ad6-8fca-4f25-abba-047f86198602</DbpropMsmdActivityID>
<DbpropMsmdCurrentActivityID>e5e75ad6-8fca-4f25-abba-047f86198602</DbpropMsmdCurrentActivityID>
<DbpropMsmdRequestID>8901787f-15a7-48a0-86eb-18ff0b92bdc4</DbpropMsmdRequestID>
</PropertyList>
Excel additional properties:
<PropertyList xmlns="urn:schemas-microsoft-com:xml-analysis" xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
<Catalog>SomeCatalog</Catalog>
<Timeout>0</Timeout>
<Format>Native</Format>
<DbpropMsmdFlattened2>false</DbpropMsmdFlattened2>
<SafetyOptions>2</SafetyOptions>
<Dialect>MDX</Dialect>
<MdxMissingMemberMode>Error</MdxMissingMemberMode>
<DbpropMsmdOptimizeResponse>9</DbpropMsmdOptimizeResponse>
<DbpropMsmdActivityID>9D69640F-553A-4970-BD4E-7234F1CD928C</DbpropMsmdActivityID>
<DbpropMsmdRequestID>B5E10FF0-EF2F-409E-83BF-CD2DBA20C2BE</DbpropMsmdRequestID>
<LocaleIdentifier>1030</LocaleIdentifier>
<DbpropMsmdMDXCompatibility>1</DbpropMsmdMDXCompatibility>
</PropertyList>
Result of a single member working mxd query:
SuperBrugsen [Stores].[Chain].[Chain].&[SuperBrugsen]__XLPSEP[Stores].[Chain].[All]
This all the info that I could gather for my problem. My next step is to get to Microsoft for help by I don't want to do that just yet due to the costs.
Can someone of you guys please help me out? any ideas or suggestion are most welcomed because I ran out of ideas.
It seems that the problem solved itself. Most likely there was an update that solved this issue. Ref. to azure update logs page: https://azure.microsoft.com/en-us/updates/?product=analysis-services&status=nowavailable

Netsuite bug when creating customerdeposit record

Im trying to create a customer deposit record in Netsuite using suitescript 1.0.
The original code I had in place which had been working perfectly up until the 2016.2 release broke it.
The update broke it, in that it would override the value submitted in the payment field and instantly make it the full amount of the sales order from the sales order ID. Which is not what we need it to do.
Original Code
function createDeposit(request,response)
{
var record = nlapiCreateRecord('customerdeposit');
record.setFieldValue('salesorder','1260');
record.setFieldValue('customer','1170');
record.setFieldValue('payment','100');
record.setFieldValue('account','2');
record.setFieldValue('memo','this is a test');
deposit = nlapiSubmitRecord(record,true,false);
response.write(deposit);
}
After a reply on the Netsuite user group prompted me to use the {recordmode:'dynamic'} attributes I am getting a strange error..
Test Replacement Function which doesnt work
function createDeposit(request,response)
{
var record = nlapiCreateRecord('customerdeposit',{recordmode:'dynamic'});
record.setFieldValue('salesorder','1260');
record.setFieldValue('customer','1170');
record.setFieldValue('payment','100');
record.setFieldValue('account','2');
record.setFieldValue('memo','this is a test');
deposit = nlapiSubmitRecord(record,true,false);
response.write(deposit);
}
The error message Im getting now is
Invalid salesorder reference key 1260 for customer .
The thing I dont get is how it is now considered NULL, when the value is hardcoded into this test script after I apply the {recordmode:'dynamic'} value.
Ive tried a wide variety of things, but as I dont have Netsuite support, its proving to be something I simply cant figure out.
Any hints, suggestions would be greatly appreciated as Ive been on this for several days
When you use dynamic the order you set fields makes a difference. So when you set the sales order prior to setting the customer you are actually getting the error message "Invalid salesorder reference key 1260 for customer blank"
What I do is create the customer deposit like:
var depRec = nlapiCreateRecord('customerdeposit', {entity:soRec.getFieldValue('entity'), salesorder:soId});
also setting the undeposited funds flag seems to be required (but not always for some reason) so since you are supplying an account id also do this:
depRec.setFieldValue('undepfunds', 'F');

ScriptError using Google Apps Script Execution API

Following these guides https://developers.google.com/apps-script/guides/rest/quickstart/target-script and https://developers.google.com/apps-script/guides/rest/quickstart/nodejs, I am trying to use the Execution API in node to return some data that are in a Google Spreadsheet.
I have set the script ID to be the Project Key of the Apps Script file. I have also verified that running the function in the Script Editor works successfully.
However, when running the script locally with node, I get this error:
The API returned an error: Error: ScriptError
I have also made sure the script is associated with the project that I use to auth with Google APIs as well.
Does anyone have any suggestion on what I can do to debug/ fix this issue? The error is so generic that I am not sure where to look.
UPDATE: I've included a copy of the code in this JSBin (the year function is the entry point)
https://jsbin.com/zanefitasi/edit?js
UPDATE 2: The error seems to be caused by the inclusion of this line
var spreadsheet = SpreadsheetApp.open(DriveApp.getFileById(docID));
It seems that I didn't request the right scopes. The nodejs example include 'https://www.googleapis.com/auth/drive', but I also needed to include 'https://www.googleapis.com/auth/spreadsheets' in the SCOPES array. It seems like the error message ScriptError is not very informative here.
In order to find what scopes you'd need, to go the Script Editor > File > Project Properties > Scopes. Remember to delete the old credentials ~/.credentials/old-credential.json so that the script will request a new one.
EDIT: With the update in information I took a closer look and saw you are returning a non-basic type. Specifically you are returning a Sheet Object.
The basic types in Apps Script are similar to the basic types in
JavaScript: strings, arrays, objects, numbers and booleans. The
Execution API can only take and return values corresponding to these
basic types -- more complex Apps Script objects (like a Document or
Sheet) cannot be passed by the API.
https://developers.google.com/apps-script/guides/rest/api
In your Account "Class"
this.report = spreadsheet.getSheetByName(data.reportSheet);
old answer:
'data.business_exp' will be null in this context. You need to load the data from somewhere. Every time a script is called a new instance of the script is created. At the end of execution chain it will be destroyed. Any data stored as global objects will be lost. You need to save that data to a permanent location such as the script/user properties, and reloaded on each script execution.
https://developers.google.com/apps-script/reference/properties/

Updating the Shipping Carrier on a Netsuite Customer Record

Just as a test to see if it worked on one record I created the following mass update script and it doesn't seem to be updating the record I am telling it to but I get no errors. What am I doing wrong?
function shipCarrier(rec_type) {
var recid=11952;
var cust=nlapiLoadRecord(rec_type, recid);
cust.setFieldValue('shippingcarrier','UPS');
nlapiSubmitRecord(cust);
}
When I change your code to use cust.setFieldText() rather than cust.setFieldValue(), it works for me as a mass update script.
setFieldValue() is looking for the integer ID of the UPS item rather than the text.

Grocery crud : How to get the current id that had been used when editing and viewing a record?

How to get the current id that had been used when editing and viewing a record?
I am currently following the instruction by Alfonso Secas that he posted in this topic..
http://www.grocerycrud.com/forums/topic/1326-how-to-use-grocery-crud-and-image-crud-together/page-2
And now on the part where he said "When editing a record, get the current ID from $this->getStateInfo(); to compose the iframe's source url."
It seems like getStateInfo doesn't exist yet so it shows an error "Fatal error: Call to undefined method Examples::getStateInfo() "
http://www.grocerycrud.com/documentation/options_functions/getState
this will do what u want . give it a try
u need to use the CRUD object to call this function instead of $this ..
You have some options:
Primary key
getStateInfo()->get_primary_key
Last uri segment
end($this->uri->segments)
Does not work in list action.
As a workaround you can use one of CodeIgniter's methods to get id from page url
https://www.codeigniter.com/userguide3/libraries/uri.html
You need to take last segment from URI
$segmentsCount = $this->uri->total_segments();
$itemID = intval($this->uri->segment($segmentsCount));
p.s. it is not best solution but it can do the trick

Resources