I am using a restlet to check whether a contact exist in netsuite or not. I am calling this restlet from an external environment. The problem I'm facing is the search should be marked unrestricted in order to get results otherwise its returning nothing. How should I mark the search unrestricted? This is my code
var result = search.create({
type : record.Type.CONTACT,
filters:['email','IS',contact_mail],
ispublic : true,
unrestricted: true,
columns: ['email']
}).run().getRange({
start: 0,
end: 1
});
Can someone help me with this!
You can create the contact saved search in the UI without any filters and mark it as unrestricted.
In your script, load the search with search.load, and then add the the email filter to the search before running it.
var searchObj = search.load({
type: record.Type.CONTACT,
id: customsearch_contact_search
});
searchObj.filters.push(['email','IS',contact_mail]);
var result = searchObj.run().getRange({start:0, end:1});
Related
I'm pretty new to SuiteScript 2.0, so far it has been an insane learning experience.
Currently I am trying to write a script that will take a new Item Fulfillment record that is just being created, get the newly generated ID and place that value onto another record. I have been trying to test this by setting the value of a field on the same record with no luck. The script will run, but nothing sticks. The field I am setting the value of always remains blank.
/**
#NapiVersion 2.0
#NScriptType UserEventScript
*/
define(['N/record'],
function(record) {
function afterSubmit(scriptContext) {
if (scriptContext.type !== scriptContext.UserEventType.CREATE)
return;
var rec = scriptContext.newRecord;
rec.load({
type: record.type.ITEMFULFILLMENT,
id: rec
});
var itemFul = rec.getValue({
fieldId : 'tranid'
});
rec.setValue({
fieldId: 'custbody_mod_billoflading_ref',
value: itemFul
});
rec.save();
};
return{
afterSubmit: afterSubmit
};
});
What am I doing wrong? Again I am fairly new to SuiteScript 2.0 and learning a ton along the way! I appreciate any help I can get!
First of all, is your UserEvent deployment on an Item Fulfillment?
If YES, there's no need of loading the record again
However, you will need to load the 'other' record in which you need to set the value. Store the loaded record in a variable
var otherRecord = rec.load({
type: 'OTHER RECORD TYPE'
id: 'OTHER RECORD ID'
});
Also, you are trying to perform setValue on the current Record (i.e. rec)
You will need to do setValue on the record you loaded, following a record.save() to save it.
otherRecord.setValue({
fieldId: 'custbody_mod_billoflading_ref'
value: itemFul //your code variable
});
otherRecord.save();
ALTERNATIVELY,
You can use record.submitFields() API which would make your life much easier. Syntax is as below -
var id = record.submitFields({
type: record.Type.SALES_ORDER,
id: 1,
values: {
memo: 'ABC'
},
options: {
enableSourcing: false,
ignoreMandatoryFields : true
}
});
I want to update my snippet.description on my Youtube channel using the API exposed through Google Apps Script. I know the videoId already so there is no need to create and loop through a search list like they show in the example here.
I expect to see my script complete with the new description on my Youtube video. But I get the following error message instead.
API call to youtube.videos.update failed with error: Forbidden (line 90, file "Youtube")
Code.gs
function updateVideo( data ) {
var videoId = 'foo';
var title = 'bar';
var description = 'baz';
var resource = {
id: videoId,
snippet: {
title: title,
description: description,
categoryId: '22'
}
};
YouTube.Videos.update(resource, 'id,snippet'); // this is line 90
}
What am I doing wrong?
Note
To clarify: By "only the videoId", I mean without creating a list of channels to find it like they do here.
var myChannels = YouTube.Channels.list('contentDetails', {mine: true});
Edit
This question is different because the other asks specifically about HTML. This question is not about using HTML in the description. It's about making any changes whatsoever to the description.
Summary from comments:
This is an authorization error. The account making the API request was not the same account as the owner of the YouTube video.
I am using this filter hook in my Auth0 Delegated Administration Extension.
function(ctx, callback) {
// Get the company from the current user's metadata.
var company = ctx.request.user.app_metadata && ctx.request.user.app_metadata.company;
if (!company || !company.length) {
return callback(new Error('The current user is not part of any company.'));
}
// The GREEN company can see all users.
if (company === 'GREEN') {
return callback();
}
// Return the lucene query.
return callback(null, 'app_metadata.company:"' + company + '"');
}
When user logged in whose company is GREEN can see all users. But when user logged in whose company is RED can't see any users whose company is RED.
I need to make this when user logged in, user should only be able to access users within his company. (except users from GREEN company).
But above code is not giving expected result. What could be the issue?
This might be related to a little warning note on the User Search documentation page
Basically they don't let you search for properties in the app_metadata field anymore. Unfortunately, this change was breaking and unannounced.
We had to make changes to our API so that we keep a copy of the app_metadatas in a separate database and convert lucene syntax to MongoDB queries, so that we can query by a chain of user_id:"<>" OR user_id:"<>" OR ....
One caveat though, you can't pass a query that's longer than 72 user_ids long. This number is so far undocumented and obtained empirically.
Also, you can't rely on Auth0's hooks to add new users to your database, as these don't fire for social logins, only for Username-Password-Authentication connections.
I hope this gave you some explanation as for why it wasn't working as well as a possible solution.
If I were you, I would look for an alternative for Auth0, which is what we are currently doing.
I finally ended up with this solution.
Used search functionality to filter users. I had to change below two files.
fetchUsers function in client\actions\user.js
changed
export function fetchUsers(search = '', reset = false, page = 0)
to
export function fetchUsers(search = '#red.com', reset = false,
page = 0)
AND
onReset function in client\containers\Users\Users.jsx
changed
onReset = () => { this.props.fetchUsers('', true); }
to
onReset = () => { this.props.fetchUsers('#red.com', true); }
I am using jQrid version 3.8.1 with inline editing and each row in the grid has several dropdown lists to populate. When the user edits the row, I need to do an AJAX query to get the values for each of these lists. I've seen this post regarding how to do that. It appears that the dataUrl and buildSelect features are the standard answer here. There are a few issues I can't figure out though:
The row the user is editing has a value that must be passed into the dataUrl value. For example, say each row contains a field called "SpecialValue" and that for row 1, SpecialValue = 100. The dataUrl field for row 1 would be "http://my.services.com?SpecialValue=100". How do I do that?
Each row in the grid has about 10 select boxes that need to be populated. For efficiency reasons, I don't want to make 10 separate AJAX calls. It would be much better to make one call to get all the data, split it up, and fill each select box accordingly. Is that possible? I tried doing this inside onSelectRow but the grid ended up ignoring the values I put in there (I'm guessing do the ordering of the events that fire when you edit a row).
Edit:
After reading Oleg's answers and working on it more, it's clear to me that using dataUrl and buildSelect are not going to work well for me. The version of jqGrid I'm using doesn't support using dataUrl the way I would need. And even if it did I don't want to send multiple separate requests for each dropdown list.
I've decided to do one request when gridComplete fires to pull all the data needed for all dropdown lists into a single JSON structure. Then when the user selects a row to do inline editing, I will populate each list in the row from that JSON structure (the code below uses the getSelectValuesFromJSON() function for that--I don't give its definition but you can imaging it looks through the structure and gets an appropriate list of values to but in the list box).
I have a few candidate solutions but I'm not 100% happy with either one.
Solution 1:
Inside onSelectRow, I call editRow overriding the on oneditfunc to get the data out of the grid that I need. Assume that the value in Field1 is required to get the values to be put into the list in Field2.
onSelectRow: function (index, status, e) {
jQuery('#my_grid').jqGrid('editRow', index, true, function(rowId) {
var f1Val = $('#my_grid').jqGrid('getCell', index, 'Field1');
var selectVals = getSelectValuesFromJSON(f1Val); //gets data out of previously loaded JSON structure
var select = $('#my_grid').find('tr[id="' + index + '"] td[aria-describedby="my_grid_Field2"] select');
_.each(selectVals, function(selectVal) {
$(select).append($("<option></option>").attr("value", selectVal).text(selectVal));
});
});
}
This works but I'm hesitant about the line
var select = $('#my_grid').find('tr[id="' + index + '"] td[aria-describedby="my_grid_Field2"] select');
which relies on this aria-describedby attribute that I don't know much about. Seems hacky and brittle.
Solution 2:
Make use of beforeSelectRow to dynamically change the model of the Field2 column when the user selects a row.
beforeSelectRow: function(index, e) {
var f1Val = getGridCellValue('#my_grid', index, 'Field1');
var values = getSelectValuesFromJSON(f1Val); //gets data out of previously loaded JSON structure
var valStr = "";
_.each(values, function(value) {
valStr += value + ":" + value + ";"
});
jQuery('#grid_pipes').setColProp('Field2', { editoptions: { value: valStr } });
return true;
}
This also works but I'm not sure about whether or not this is really a good idea. Is it valid to dynamically change the model of a column like that? What if the user has several rows selected at the same time? Isn't there only one model for a column? What would that mean?
To answer some of Oleg's questions, the dataType has been set to a function that uses $.ajax to post data to the server. I think I read that's not the recommended approach anymore. I inherited this code so I'm not sure why it was done that way but it probably won't change unless there is a really compelling reason.
The loadonce boolean is not specified so I guess that means it defaults to false.
Here is an abbreviated version of the column model (nothing terribly out of the ordinary):
colModel: [
{ name: 'PK', index: 'PK', hidden: true, editable: true, sortable: true, search: true },
{ name: 'Field1', index: 'Field1', hidden: true, editable: true, sortable: true, search: true },
{ name: 'Field2', index: 'Field2', sortable: false, editable: true, search: false, edittype: "select", editoptions: {} },
{ name: 'Field3', index: 'Field3', sortable: false, editable: true, search: false, edittype: "select", editoptions: {} },
...
]
You don't wrote which version of jqGrid you use currently, but dataUrl can be defined as callback function with (rowid, value, name) parameters, which have to return the URL which you can build dynamically based on the information. The feature exist starting with v4.5.3 (see the line). You can use getCell, getRowData or getLocalRow inside of the callback to get the data from another columns of the row. Thus you can solve your first problem relatively easy.
You second question seems to me absolutely independent from the first one. It's better to separate such questions in different posts to allow the searching engine better to index the information and so to help other people to find it.
There are no simple way how to solve the second problem, but one can sure suggest a solution, but one have to know much more details what you do and how you do. How you start inline editing (do you use inlineNav, formatter: "actions" or you call editRow directly)? Which version of jqGrid (till version 4.7), free jqGrid or Guriddo jqGrid JS you use? How the columns with selects are defined in colModel? Which datatype you use and whether loadonce: true you use? I recommend you to post separate question with the information.
UPDATE: If you have to use old version of jqGrid then you can't generate dataUrl full dynamically, but because you need to add only SpecialValue=100" part to the URL you can follow the trick which I described in many my old answers (the first one was probably here, but the choice on property names which asked the user could be misunderstood). You can use ajaxSelectOptions.data which will define the data parameters of jQuery.ajax request. The problem only that you can define only one ajaxSelectOptions.data property. So you can add the following jqGrid option:
ajaxSelectOptions: {
data: {
SpecialValue: function () {
var rowid = $myGrid.jqGrid("getGridParam", "selrow");
return $myGrid.jqGrid("getCell", rowid, "SpecialValue");
}
}
}
($myGrid is something like $("#grid"))
UPDATED: You used unknown functions getSelectValuesFromJSON, getLookupValuesFromJSON in the updated part of your question. Both of there seems to use synchronous Ajax request which is not good. Moreover you set editoptions.value for only one Field2 instead of setting all selects.
onSelectRow: function (rowid) {
var $myGrid = $(this);
$.ajax({
url: "someUrl",
dataType: "json";
data: {
specialValue: $myGrid.jqGrid("getCell", rowid, "Field1")
},
success: function (data) {
// for example response data have format:
// { "Field2": ["v1", "v2", ...], "Field3": ["v3", "v4", ...] }
var filed, str;
for (filed in data) {
if (data.hasOwnProperty(filed)) {
str = $.map(data[filed], function (item) {
return item + ":" + item
}).join(";");
$myGrid.jqGrid("setColProp", filed, {
editoptions: {
value: str
}
});
}
}
$myGrid.jqGrid("editRow", rowid, true);
}
});
}
Nevertheless the "Solution 2" is more close to what I would recommend you. It's not really important whether to use onSelectRow or beforeSelectRow. You can make asynchronous Ajax request to the server which returns information for all select which you need. After you get the response from the server (inside of success callback) you can set editoptions.value for all selects and only then you can start editRow. In the way you will be sure that editing of the line will use row specific options in all select.
Some additional remarks. I recommend you to verify gridview: true option in the grid. Additionally I suspect that you fill the grid in not full correct way because you have hidden PK column and you use index instead of rowid as the first parameter of beforeSelectRow and onSelectRow. It's very important to understand that the current implementation of jqGrid always assign id attribute on every row (<tr> element) of the grid. So you have to provide id information in every item of input data. If you want to display the id information to the user (and so to have column in colModel with the primary key) then you should just include key: true property in the column definition. For example you can add key: true to the definition of PK column and so you will have rowid (or index in your case) with the same value like PK. It simplify many parts of code. For example jqGrid send id parameter in the editing request to the server. It's practical to have PK in the request. Moreover if you use repeatitems: false format of jsonReader the you can include id: "PK" in the jsonReader instead of having hidden PK column. It informs jqGrid to get rowid from PK. jqGrid will save PK in id attribute of <tr> and you will don't need to have additional <td style="display:none"> with the same information in the grid.
The last remark. I would strictly recommend you to update the retro version jqGrid 3.8.1 to some more recent version, for example to free jqGrid. Even if you would use no features (like Font Awesome for example) you will have performance advantages, and the look of modern web browsers will looks much better. You should understand the jqGrid 3.8.1 was tested with old (and slow jQuery 1.4.2). The version used with Internet Explorer 8 as the latest IE version (IE9 was published later in March 2011) and it's more oriented on IE6/IE7. The look in modern Chrome/Firefox/Safari can be bad. Is it what you want?
Is it possible to fetch a traffic variable sProp1 along with PageName and Url when issuing a GetReport request of a Ranked report?
Let us say I have the following passed to SiteCatalyst (Omniture) via Java Script.
s.pageName = o_title; // Page Name
s.channel = o_structure; // SiteSection
s.prop1 = o_inode // Traffic variable also the Primary Key Id of the PageName
Now, if I run a RankedReport, I will get the following
PageName
PageViews
Url
Along with this info, I will also be interested in fetching the s.prop1 value. I will need the s.prop1 value to use it on my db to query the first sentence of the article from db (and other metadata) and show the results on the results page that shows the most popular pages. Can this be achieved? I mean is it possible to get the traffic variable associated with the pageName?
Thanks,
Rag
OK. I think I if I add another element (prop1) I get the breakdown. {
"reportDescription":{
"reportSuiteID":"*",
"dateFrom":"2013-03-06",
"dateTo":"2013-03-15",
"metrics":[
{
"id":"pageviews",
"name":"Page Views",
"type":"number"
}
],
"sortBy":"pageviews",
"elements":[
{
"id":"siteSection"
},
{
"id":"page"
},
{
"id":"prop1"
}
],
"locale":"en_US"
},
"validate":"false"
}