I am not a suitescript coder. I have JS knowledge. A while back i came across a script which would create an SO for me. The script was similar to the one attached, just that it had the else condition for when "Typeof Value=='object'
function getItems(datain) {
var err = new Object();
// Validate if mandatory record type is set in the request
if (!datain.recordtype)
{
err.status = "failed";
err.message= "missing recordtype";
return err;
}
var record = nlapiCreateRecord(datain.recordtype);
for (var fieldname in datain)
{
if (datain.hasOwnProperty(fieldname))
{
if (fieldname != 'recordtype' && fieldname != 'id')
{
var value = datain[fieldname];
nlapiLogExecution('DEBUG', fieldname);
// ignore other type of parameters
if (value && typeof value != 'object')
{
record.setFieldValue(fieldname, value);
}
}
}
}
var recordId = nlapiSubmitRecord(record);
nlapiLogExecution('DEBUG','id='+recordId);
// returns the created record in JSON format
var nlobj = nlapiLoadRecord(datain.recordtype,recordId);
return nlobj;
}
Can someone help me fill the else section where I would process the Items array when the recordtype would be 'salesorder'
Greatly appreciate your help.
Thanks
Something like this:
nlapiSelectNewLineItem('item');
nlapiSetCurrentLineItemValue('item', 'item', 380, true, true);
nlapiSetCurrentLineItemValue('item', 'location', 102, true, true);
nlapiCommitLineItem('item');
Related
I'm trying to write a user event script which loads the current record and populates a line item value through search after submit record. But, it is giving an error RCRD_DSNT_EXIST, even though the record exists.
function afterSubmit_SO(type){
try
{
//var record_type = nlapiGetRecordType();
var recordID = nlapiGetRecordId();
var context = nlapiGetContext();
var recordOBJ = nlapiLoadRecord('salesorder',recordID);
var source = context.getExecutionContext();
if(source == 'userinterface')
{
var line_count = recordOBJ.getLineItemCount('item');
nlapiLogExecution('DEBUG', 'line count ', line_count);
for(var i = 1; i <= line_count; i++)
{
var itemID = recordOBJ.getLineItemValue('item','item',i);
nlapiLogExecution('DEBUG', 'item ID', itemID);
var filter = new Array();
filter[0] = new nlobjSearchFilter('internalid', null, 'is', itemID);
var columns = new Array();
columns[0] = new nlobjSearchColumn('custitem_web_market_availability');
var a_search_results = nlapiSearchRecord('item',null,filter,columns);
if(a_search_results)
{
for(var x = 0; x < a_search_results.length; x++)
{
var item_web_availability = a_search_results[x].getText('custitem_web_market_availability');
nlapiLogExecution('DEBUG', 'value', item_web_availability);
}
} recordOBJ.setLineItemValue('item','custcol_web_item_availability',i,item_web_availability);
}
var submitID = nlapiSubmitRecord(recordOBJ, true, true);
}
}
catch(exception)
{
nlapiLogExecution('DEBUG','Exception Caught ','' + exception);
}
return true;
}```
It could be that your script is executing on the delete operation. I did not see any checking for this in the code you provided. If it is a delete operation then the after submit user event script wont be able to load the deleted record, this is why you get the error.
The type parameter of your afterSubmit function should contain the operation type. You can something like if (type == 'delete') { return true;} at the top of your script.
I have an issue with handling parallel requests with cloud functions.
My scenario is to select a driver from the db and update its status.
I do check for that status property before updating it, but when I send multiple requests (database on create triggers to be specific) within a second it doesn't seem to read the updated status property. And it always updates with the information of the last request. I also have noticed that sometimes the requests are processed altogether.
What can I do to fix these issues?
index.js
const db = app.database();
const TripManagementUtil = require('./utils').TripManagementUtil;
exports.triggerNotifications = functions.database.ref('/Trip/{pushId}').onCreate( (snapshot, context) =>
{
var newTrip = snapshot.val();
var tripKey = context.params.pushId;
var tripManagementUtil = new TripManagementUtil();
tripManagementUtil.searchDrivers(tripKey, newTrip, db);
});
utils.js
searchDrivers(tripKey, trip, db){
const results = [];
var lat = trip.pickupLocation.lat, long = trip.pickupLocation.lng;
var vehicleTypeID = trip.vehicleTypeID;
var alreadyAssigned = trip.alreadyAssigned;
var self = this;
if(alreadyAssigned == null || alreadyAssigned == 'undefined'){
alreadyAssigned = [];
}
const geofireQuery = new GeoFire(db.ref('vehicleLocation').child(vehicleTypeID + "")).query({
center: [lat, long],
radius: constants.searchRadius
})
.on('key_entered', (key, coords, distance) => {
if(alreadyAssigned.indexOf(key) == -1){
var result = {
driverID: key,
distance: distance
}
results.push(result);
}
});
setTimeout(() => {
geofireQuery.cancel();
if (results.length === 0) {
self.noDriversHandler(alreadyAssigned, tripKey, db);
} else {
results.sort((a, b) => a.distance - b.distance);
var driversAvailable = false;
var index = 0;
function checkDriver(){
db.ref().child("driver").child("available").child(results[index].driverID).once('value').then(function(vehicleSnap){
var vehicle = vehicleSnap.val();
if(!driversAvailable){
if(vehicle != null && vehicle.vehicleTypeID == vehicleTypeID
&& (vehicle.tripStatus != TripVehicleActionEnum.DriverConfirmed && vehicle.tripStatus != TripVehicleActionEnum.VehicleAssigned)
&& alreadyAssigned.indexOf(vehicle.driverID +"") === -1){
driversAvailable = true;
self.driverExistsHandler(trip, tripKey, alreadyAssigned, vehicle, db);
}
if(!driversAvailable && index + 1 == results.length){
self.noDriversHandler(alreadyAssigned, tripKey, db);
}
index++;
}
else{
index++;
checkDriver();
}
});
}
checkDriver();
}
}, 1500);
}
To write data to the database where the value is based on an existing value, you'll want to use Firebase Realtime Database transactions. For more on this, and examples, see save data transactionally in the Firebase documentation.
I'm parsing a 2GB+ xml file, initially i process(multi-thread) records one by one.
But single insert sql query to DB it's too slow(DB bottle neck) hence I need to create a mass insert query/cvs file after going through the xml document. But unlike java, in nodejs i can't tell if the documents has been fully parse.
Been working on it for 12hrs+, would be great if anyone can help me out. Perhaps try other xml libraries ? or just use good old java.
var bigXml = require('big-xml');
reader = bigXml.createReader('dblp.xml', /^(article)$/, { gzip: false });
var count = 0;
var temp = [];
reader.on('record', async function (record) {
console.log("Processing article:" + count);
count++;
var pubBody = importPubBuilder(record);
temp.push(pubBody);
//taking temp Array to csv when finish reading file
});
reader.on('error', function (err) {
console.log(err);
});
function importPubBuilder(record) {
var body = {};
body.pubkey = record.attrs.key;
body.mdate = record.attrs.mdate;
body.title = null;
body.ee = null;
body.url = null;
if (record.children.find(obj => { return obj.tag == "title" }) != null) {
body.title = record.children.find(obj => { return obj.tag == "title" }).text;
}
if( record.children.find(obj => { return obj.tag == "ee" }) != null){
body.ee =record.children.find(obj => { return obj.tag == "ee" }).text
}
if( record.children.find(obj => { return obj.tag == "url" }) !=null){
body.url = record.children.find(obj => { return obj.tag == "url" }).text
}
return body
}
Updated added close event emitter when file stream close. Fork with improvement at npm big-xml-notify link
like i menthioned in the topic i'm looking for a plugin that save my marked text and could restore it after loose of focus. Like a JS Library called Rangy i used in the past. Is there such a plugin or does anyone has an idea how i could deal with this kind of problem?
Regardings Adrian
function gEBI(id) {
return document.getElementById(id);
}
var savedSel;
var savedSelActiveElement;
function saveSelection() {
if (savedSel) {
// rangy.removeMarkers(savedSel);
}
savedSel = rangy.saveSelection();
savedSelActiveElement = document.activeElement;
}
function restoreSelection() {
if (savedSel) {
rangy.restoreSelection(savedSel, true);
window.setTimeout(function() {
if (savedSelActiveElement && typeof savedSelActiveElement.focus != "undefined") {
savedSelActiveElement.focus();
}
}, 1);
}
}
$(document).ready(function()
{
try {
document.execCommand("MultipleSelection", null, true);
} catch(ex) {}
rangy.init();
// Enable buttons
var saveRestoreModule = rangy.modules.SaveRestore;
if (rangy.supported && saveRestoreModule && saveRestoreModule.supported) {
var saveButton = gEBI("saveButton");
//saveButton.disabled = false;
saveButton.ontouchstart = saveButton.onmousedown = function() {
saveSelection();
return false;
};
$('.EditorTab').mousedown(function(){
saveSelection();
return false;
});
});
The following solution would allow you to store and restore any number of ranges, but it assumes that you have not destroyed the nodes that the ranges are attached to when it comes time to restore those ranges.
var SelectionStore = (function() {
var savedRanges = {};
return {
store: function(saveIdentifier) {
var ranges = rangy.getSelection().getAllRanges();
savedRanges[saveIdentifier] = ranges;
return ranges;
},
restore: function(saveIdentifier) {
var i, selection;
selection = rangy.getSelection();
if (!savedRanges[saveIdentifier]) throw new Error('Invalid saved selection identifier used. Selection not found for ID: ' + saveIdentifier);
selection.removeAllRanges();
for (i in savedRanges[saveIdentifier]) selection.addRange(savedRanges[saveIdentifier][i]);
}
}
})();
Usage examples:
//store the current selection
SelectionStore.store('Tab1');
//restore a selection
SelectionStore.restore('Tab1');
jsfiddle link: http://jsfiddle.net/T8ee7/
When I call Knockout's subscribe method is there a way I can get both the previous and new value? Right now, I can only call get these values separately.
I want to trigger some code if the old and new value are different.
I suppose I could do the following, but it can get messy...
(http://jsfiddle.net/MV3fN/)
var sv = sv || {};
sv.PagedRequest = function (pageNumber, pageSize) {
this.pageNumber = ko.observable(pageNumber || 1);
this.numberOfPages = ko.observable(1);
this.pageSize = ko.observable(pageSize || sv.DefaultPageSize);
};
var _pagedRequest = new sv.PagedRequest();
var oldValue;
_pagedRequest.pageNumber.subscribe(function (previousValue) {
console.log("old: " + previousValue);
oldValue = previousValue;
}, _pagedRequest, "beforeChange");
_pagedRequest.pageNumber.subscribe(function (newValue) {
console.log("new: " + newValue);
if (oldValue != newValue) {
console.log("value changed!");
}
});
_pagedRequest.pageNumber(10);
_pagedRequest.pageNumber(20);
I prefer using an observable extender.
http://jsfiddle.net/neonms92/xybGG/
Extender:
ko.extenders.withPrevious = function (target) {
// Define new properties for previous value and whether it's changed
target.previous = ko.observable();
target.changed = ko.computed(function () { return target() !== target.previous(); });
// Subscribe to observable to update previous, before change.
target.subscribe(function (v) {
target.previous(v);
}, null, 'beforeChange');
// Return modified observable
return target;
}
Example Usage:
// Define observable using 'withPrevious' extension
self.hours = ko.observable().extend({ withPrevious: 1 });
// Subscribe to observable like normal
self.hours.subscribe(function () {
if (!self.hours.changed()) return; // Cancel if value hasn't changed
print('Hours changed from ' + self.hours.previous() + ' to ' + self.hours());
});
This seems to work for me
ko.observable.fn.beforeAndAfterSubscribe = function (callback, target) {
var _oldValue;
this.subscribe(function (oldValue) {
_oldValue = oldValue;
}, null, 'beforeChange');
this.subscribe(function (newValue) {
callback.call(target, _oldValue, newValue);
});
};
See more at: http://ideone.com/NPpNcB#sthash.wJn57567.dpuf
http://jsfiddle.net/MV3fN/3/
var sv = sv || {};
sv.PagedRequest = function (pageNumber, pageSize) {
var self = this;
self.pageNumber = ko.observable(pageNumber || 1);
self.numberOfPages = ko.observable(1);
self.pageSize = ko.observable(pageSize || sv.DefaultPageSize);
self.pageNumber.subscribe(function (previousValue) {
console.log(previousValue);
console.log(self.pageNumber.arguments[0]);
if (previousValue != _pagedRequest.pageNumber.arguments[0]) {
console.log('value changed');
}
else {
//This won't get executed because KO doesn't
//call the function if the value doesn't change
console.log('not changed');
}
}, _pagedRequest, "beforeChange");
};
var _pagedRequest = new sv.PagedRequest();
_pagedRequest.pageNumber(10);
_pagedRequest.pageNumber(20);
_pagedRequest.pageNumber(20);
_pagedRequest.pageNumber(5);
I don't know if you're really supposed to use arguments[0], but it seems to work.
You could also set up your own method to accomplish this in a much cleaner way:
http://jsfiddle.net/PXKgr/2/
...
self.setPageNumber = function(page) {
console.log(self.pageNumber());
console.log(page);
if (self.pageNumber() != page) {
console.log('value changed');
}
else {
console.log('not changed');
}
self.pageNumber(page);
};
...
_pagedRequest.setPageNumber(10);
_pagedRequest.setPageNumber(20);
_pagedRequest.setPageNumber(20);
_pagedRequest.setPageNumber(5);