I have worked out how to add a reminder after setting a CalendarEventEntry using
insertedEntry = myService.insert( postUrl, myEntry )
reminder = new Reminder()
reminder.setMethod( Reminder$Method.ALERT )
//foo
insertedEntry.getReminder().add( reminder )
insertedEntry.update()
but if you update it becomes an EventEntry and the getReminder returns null and whatever you do it wipes all reminders
insertedEntry = myService.update(editUrl, myEntry)
can find nothing in the api or docs about this case.
Anyone solved this already??
Did you try to cast the update result ?
BaseEntry updateEntry = myService.update(editUrl, myEntry)
if (updatedEntry instanceOf CalendarEventEntry) {
insertEntry = (CalendarEventEntry) updatedEntry
}
Can't you simply update it with:
insertedEntry.update()
rather than
insertedEntry = myService.update(editUrl, myEntry)
Related
Here is my scenario, i am parsing via javascript a webpage and then post the result to an restApi to store the json in a db. The code works fine as long as all fields i defined in my script are send. Problem is over time they website might change names for fields and that would cause my code to crash.
Originally i used code like this
const mySchool = new mls.School();
mySchool.highSchoolDistrict = data["HIGH SCHOOL DISTRICT"].trim();
mySchool.elementary = data.ELEMENTARY.trim();
mySchool.elementaryOther = data["ELEMENTARY OTHER"].trim();
mySchool.middleJrHigh = data["MIDDLE/JR HIGH"].trim();
mySchool.middleJrHighOther = data["MIDDLE/JR HIGH OTHER"].trim();
mySchool.highSchool = data["HIGH SCHOOL"].trim();
mySchool.highSchoolOther = data["HIGH SCHOOL OTHER"].trim();
newListing.school = mySchool;
but when the element does not exist it complains about that it can not use trim of undefined. So to fix this i came up with this
if (data["PATIO/PORCH"]) {
newExterior.patioPorch = data["PATIO/PORCH"].trim();
}
this works but i am wondering if there is a more global approach then to go and check each field if it is defined ?
You could leverage a sort of helper function to check first if the item is undefined, and if not, return a trim()-ed version of the string.
var data = Array();
data["HIGH SCHOOL DISTRICT"] = " 123 ";
function trimString(inputStr) {
return (inputStr != undefined && typeof inputStr == "string") ? inputStr.trim() : undefined;
}
console.log(trimString(data["HIGH SCHOOL DISTRICT"]));
console.log(trimString(data["ELEMENTARY OTHER"]));
I found one other person asking about a value override, but its unanswered. Hopefully someone can point out the dumb thing im missing! Here's the gist...
var vote = req.body.vote;
var boolVote;
(vote === 'good') ? boolVote = true : boolVote = false;
// these square brackets were the issue ----------\/
Model.findOneAndUpdate({firstname:'Jane'},{$set:{'event.attempt.judge1':[boolvote]}},
{new: true},(err,lifter)=>{console.log(lifter.event.attempt.judge1})
Ive chopped it down to its basic function because in-program boolVote will console.log as the correct value (true if vote==='good', false otherwise) but no matter how i rearrange things it ALWAYS updates to the DB as true...
Originally boolVote was this
var boolVote = ()=>(vote === 'good') ? true : false;
which didnt work either. I can change the value in the mongo CLI without issue.
Has anyone else had issues saving a FALSE value to MongoDB? If so, what does it take to get this working, and if not what am i doing wrong???
Thanks in advance for any help, im pulling hair here.
You can write ternary simply like this, i'm not familiar with js but in other program languages like java the syntax is same as below
var boolVote = vote === 'good' ? true : false;
or
var boolVote = ( vote === 'good' ) ? true : false;
but when you do this
var boolVote = () => ( vote === 'good' ) ? true : false;
here boolVote is a Function with no arguments, so you need call boolVote() to get its value
EDIT
event.attempt.judge1 is a field, but when enclosed with square bracket as an array in the update method, regardless of true/false the non empty array resolved to true, same updated in db
Model.findOneAndUpdate(
{firstname:'Jane'},
{$set:{'event.attempt.judge1':boolvote}}, //removed []
{new: true},
(err,lifter)=>{console.log(lifter.event.attempt.judge1)}
)
I have really big problem, i mean im working in a company where we are using NetSuite as our business platform and now they updated our account with new APIs.
Developer before me wrote this code
for(var k = 0; k < ResultsPPCI.length; k++){
EmployeePPCI = ResultsPPCI[k].getValue('internalid'); //get the value
// log('Internal ID', EmployeePPCI);
// Merge, send, and associate an email with Purchase Order record (id=1000)
var mergeValuesPPCI = {};
mergeValuesPPCI.NLEMPFIRST = nlapiLookupField('employee', EmployeePPCI, 'firstname');
mergeValuesPPCI.NLEMPLAST = nlapiLookupField('employee', EmployeePPCI, 'lastname');
mergeValuesPPCI.NLSUPPLIER = nlapiLookupField('customer', cust, 'companyname');
mergeValuesPPCI.NLPRODUCTCODE = productcodehtml;
var emailBodyPPCI = nlapiMergeRecord(65, 'purchaseorder', poID, null, null, mergeValuesPPCI);
var recordsPPCI = {};
recordsPPCI['transaction'] = poID;
nlapiSendEmail(EmployeePPCI, EmployeePPCI, emailBodyPPCI.getName(), emailBodyPPCI.getValue(), null, null, recordsPPCI);
// log('EmployeePPCI',EmployeePPCI);
nlapiLogExecution('AUDIT', 'Potentional Problem', 'Email Sent');
}
I have problem now because nlapiMergeRecord is deprecated and it wont work. But i really cant find any working example online for hours... The most important part here is actually body of this email that has to be sent. In this case it is productcodehtml or mergeValuesPPCI.NLPRODUCTCODE.
This is how my template looks like :
<p>The QA Release has been submitted by <nlsupplier> for ${transaction.tranId}.</nlsupplier></p>
<p>The following item(s) have a short shelf life:</p>
<nlproductcode></nlproductcode>
Please can you help me with converting this code to new method? How can i connect nlproductcode from template with mergeValuesPPCI.NLPRODUCTCOD from my code?
Thanks in advance!
You can use kotnMergeTemplate as a drop in replacement for nlapiMergeRecord
e.g.:
kotnMergeTemplate(65, 'purchaseorder', poID, null, null, mergeValuesPPCI);
the nlobjEmailMerger does not take custom values so you'd have to post process the results. Again you can look at the example in my script where you'd get the merged string and then run:
var oldCustFieldPatt = /<(nl[^ >]+)>(\s*<\/\1>)?/ig;
content = content.replace(oldCustFieldPatt, function(a,m){
return mergeValuesPPCI[m.toUpperCase()] || mergeValuesPPCI[m.toLowerCase()] || '';
});
You can use the new nlapiCreateEmailMerger(templateId)
First you need to create your email template in netsuite and get the internal id.
Then:
Use nlapiCreateEmailMerger(templateId) to create an nlobjEmailMerger object.
var emailMerger = nlapiCreateEmailMerger(templateId);
Use the nlobjEmailMerger.merge() method to perform the mail merge.
var mergeResult = emailMerger.merge();
Use the nlobjMergeResult methods to obtain the e-mail distribution’s subject and body in string format.
var emailBody = mergeResult.getBody();
Send your email
nlapiSendEmail(senderInternalId, 'receiver#email.com','subject',emailBody, null, null, null);
Good luck!
I have a userevent script to change the Field in Contract record from PO record. The Script is running fine. But whenever I edit a contract record and try to submit it : It throws the error "Another user has updated this record since you began editing it. Please close the record and open it again to make your changes".
May I know the reason behind this ?
/*---------------------------------------------------------------------------------------------------------------
Description : Whenever the PO vendor is changed(due to Split vendor) that should replace the same in Contract page record automatically.
Script type : User Event Script
Script id : customscript452
Version : 1.0
Applied to : Contract
----------------------------------------------------------------------------------------------------------------*/
function srchfield()
{
var stRecordid = nlapiGetRecordId(); //returns the contract id
if(stRecordid== undefined || stRecordid== null || stRecordid==' ')
{
}
else
{
var stRecordtype = nlapiGetRecordType(); //returns the contract record type = jobs
var stRecord = nlapiLoadRecord(nlapiGetRecordType(), stRecordid);
nlapiLogExecution('debug','Load Object',stRecord);
var stContractID = stRecord.getFieldValue('entityid'); //returns the value of the field contractid whose fieldid is = entityid
nlapiLogExecution('debug','stContractID',stContractID);
var stCompanyName = stRecord.getFieldValue('companyname'); //returns the value of the field company name whose fieldid is = companyname
nlapiLogExecution('debug','stCompanyName',stCompanyName);
var stConcatenate = stContractID+" : "+stCompanyName; //Concatenate the two Fields to get the result which needs to be found in PO
var arrFilters = new Array(); // This is Array Filters all the Purchase Order Record Search
arrFilters.push(new nlobjSearchFilter('type', null, 'anyof',
[
'PurchOrd'
]));
arrFilters.push(new nlobjSearchFilter('mainline', null, 'is', 'T')); //This is to exclude line level results
arrFilters.push(new nlobjSearchFilter('custbodycontract', null, 'is', stRecordid)); //This is Filters in Contracts Search
var arrColumns = new Array();
arrColumns.push(new nlobjSearchColumn('entity')); //This is Search Column Field in Records
var arrSearchresults = nlapiSearchRecord('purchaseorder', null, arrFilters, arrColumns); //This is Filters in Search Result Purchase Order
if(arrSearchresults== undefined || arrSearchresults== null || arrSearchresults==' ')
{
}
else
{
var length = arrSearchresults.length;
}
if(length== undefined || length== null || length==' ')
{
}
else
{
for (var i = 0; arrSearchresults != null && i < arrSearchresults.length; i++)
{
var objResult = arrSearchresults[i];
var stRecId = objResult.getId();
var stRecType = objResult.getRecordType();
var stCntrctName = objResult.getValue('entity'); //This is Value are Get Purchase Order Records and Field for Vendor = entity
}
}
//var record = nlapiLoadRecord(nlapiGetRecordType(), stRecordid, stCntrctName);
if (stCntrctName =='custentityranking_vendor_name')
{
}
else
{
var stChangeName = stRecord.setFieldValue('custentityranking_vendor_name', stCntrctName); //This is Value are the Set in Main Vendor Field = custentityranking_vendor_name
nlapiSubmitRecord(stRecord, null, null); // Submit the Field Value in Record Type
}
}
}
The User Event script executes as the Contract record is being saved to the database. At the same time, you are loading a second copy of the record from the database and trying to submit the copy as well. This is causing the error you're seeing.
You fix this by just using nlapiSetFieldValue to set the appropriate field on the Contract.
I might also recommend getting more familiar with JavaScript by going through the JavaScript Guide over at MDN. In particular, take a look at the Boolean description so that you know how JavaScript evaluates Boolean expressions. This will help you greatly reduce the amount of code you've written here, as many of your conditionals are unnecessary.
What userevent do you have? It is happening depending on what type of user event and API you are using. Looking at your code, you are trying to load contract record that is already updated at the database. So you might consider below to address your issue. Hope, it helps.
If it is a before submit, you don't need to load the record where the script is deployed.
Just use nlapiGet* and nlapiSet* to get and set values. You also don't need to use nlapiSubmitRecord to reflect the change. With before submit, it executes before the record is being saved to the database. So your changes will still be reflected.
Then if it is after submit, it will be executed after the record has been saved to the database, Thus you might use the following API depending on your needs. Actually, this is the best practice to make sure the solution .
nlapiGetNewRecord - only use this if the script only needs to retrieve info from header and sublists. And nothing to set.
nlapiLookupField - use this if the script only needs to get value/s at the header and nothing from the line.
nlapiSubmitField - the script don't need to load and submit record if the changes only on header. Just use this API.
nlapiLoadRecord and nlapiSubmitRecord- use the former if the script will have changes at the line and then use the latter api to commit it on the database.
Being a user event script code, The code you showed is very not good considering performance.
Here is the sample you can merge
var stRecordid = nlapiGetRecordId(); //returns the contract id
// Every record has an internal id associated with it. No need to add condition explicitly to check if its null
var stRecordtype = nlapiGetRecordType();
var fields = ['entityid','companyname'];
var columns = nlapiLookupField(stRecordtype, stRecordid, fields);
var stContractID = columns.entityid;
var stCompanyName = columns.companyname;
nlapiLogExecution('debug','stContractID/stCompanyName',stContractID+'/'+stCompanyName);
var stConcatenate = stContractID+" : "+stCompanyName; //Concatenate the two Fields to get the result which needs to be found in PO
//
//your code of search
//you can improve that code also by using nlapilook up
nlapiSubmitField(stRecordtype, stRecordid, 'custentityranking_vendor_name', 'name to be updated');
Ran across the following problem in bxslider- how can you apply different delays between slides in the auto show?
I came up with the following solution which I will show here:
in the jquery.bxslider.js replace:
el.startAuto = function(preventControlUpdate){
// if an interval already exists, disregard call
if(slider.interval) return;
// create an interval
slider.interval = setInterval(function(){
slider.settings.autoDirection == 'next' ? el.goToNextSlide() : el.goToPrevSlide();
}, slider.settings.pause);
// if auto controls are displayed and preventControlUpdate is not true
if (slider.settings.autoControls && preventControlUpdate != true) updateAutoControls('stop');
}
With
/**EDITS: By CRB - techdude **/
el.startAuto = function(preventControlUpdate){
el.continueAuto();
}
el.continueAuto = function(){
//get how long the current slide should stay
var duration = slider.children.eq(parseInt(slider.active.index)).attr("duration");
if(duration == ""){
duration = slider.settings.pause;
} else {
duration = parseInt(duration);
}
console.log(duration);
// create a timeout
slider.timer = setTimeout(function(){
slider.settings.autoDirection == 'next' ? el.goToNextSlide() : el.goToPrevSlide();
el.continueAuto();
}, duration);
// if auto controls are displayed and preventControlUpdate is not true
if (slider.settings.autoControls && preventControlUpdate != true) updateAutoControls('stop');
}
//*End Edits*/
Then to change the duration of a slide, simply give its li tag a duration attribute like this:
where duration is the number of milliseconds for the slide to pause.
To set the default duration, simply use the pause: option in the settings:
$("element").bxSlider({
auto:true,
pause: 4000
};
Hope this helps. Maybe bx slider will even add it to a future version. :)
What are the you're using to pick this up? Any way you can put up a gist of it working?
Perhaps this will help clarify:
In principle, the way this works is I change the setInterval with a setTimeout so the interval can be changed each time.
The key to getting multiple elements to work on a page is to not use the slider.timer object, but probably to use the el.timer object so the line would read something like,
el.timer = setTimeout(function(){
slider.settings.autoDirection == 'next' ? el.goToNextSlide() : el.goToPrevSlide();
el.continueAuto();
}, duration);
Instead of
slider.timer = setTimeout(function(){
slider.settings.autoDirection == 'next' ? el.goToNextSlide() : el.goToPrevSlide();
el.continueAuto();
}, duration);
I haven't tested it with multiple sliders, but let me know if this works. That is the principle anyway. The only problem with this, however, is that I believe that you would need to modify the el.pause method to use the el.timer as well, otherwise the slideshow can't be paused. I think that was the reason I did it the way I did. However, it was a long time ago.