Using AfterSubmit UserEventScript with SuiteScript 2.0 - suitescript2.0

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
}
});

Related

VueJS 3 composition API randomly updating reactive variable

I have in my setup function this reactive variable:
const publication = reactive({
title: '',
illustration: {
type: '',
val: '',
},
id: '',
});
I can update the illustration.val with 2 functions:
function selectBiblio(e) {
publication.illustration.val = e.id;
}
or
watch(otherIllustration, (n, o) => {
if (n && n[0] && n[0].id) {
publication.illustration.val = n[0].id;
console.log(`OK: ${publication.illustration.val}`);
} else {
publication.illustration.val = '';
}
});
The first one is a click on a button and the new publication.illustration.val is immediately taken into account.
The second watches anoher ref (const otherIllustration = ref([]);) to change and should also update publication.illustration.val immediately when the new otherIllustration is loaded, but it doesn't, although the log (the line with "OK") shows that the variable assignment is OK.
I really don't understand, because when I change otherIllustration AGAIN, publication.illustration.valgets the previous value. It seems to always be one assignment late... If I change publication.title, it updates to the correct value. Very strange!
Another thing very strange: if I assign '0' instead of '', it works perfectly.
Could anybody explain me what happens here?
Thanks a lot :)

PreliminaryEstimate's Value resets to old value on saving with new value

I am trying to edit and save the PreliminaryEstimate Value of a portfolio item through Estimation Board but it reset it back to the original value. I am using PreliminaryEstimateValue in the board but when the card is moved, i reset the PreliminaryEstimate to new column value.
var store = Ext.create('Rally.data.wsapi.Store', {
model: 'PreliminaryEstimate',
fetch: ['ObjectID','ObjectUUID','VersionId','Description','Name','Value','CreationDate','Subscription','Workspace','RevisionHistory'],
autoLoad: false,
limit: Infinity,
disableMetaChangeEvent: true
});
beforecarddroppedsave: function (scope, card, type, sourceColumn, eOpts) {
card.record.data.PreliminaryEstimate = _.omit(_.filter(this.preliminaryEstimateStore.getRange(), function (pe) { return pe.data.Value === card.record.data.PreliminaryEstimateValue })[0]
.data, ['Summary', 'creatable', 'deletable', 'updatable', '_CreatedAt', '_objectVersion', '_uuidRef']);
the options also has the new value. It saves succesfully but the old value does not change to new
handleBeforeCardDroppedSave: function (options) {
options.record.save({})
Thanks!
If you inspect the network traffic is it actually sending that value over the wire? I'd try using the setter method rather than directly manipulating the data object. My guess is that the record does not think it has any changes to save with the way your current code is written.
card.record.set('PreliminaryEstimate', '/preliminaryestimatevalue/12345');

Accessing properties of ember-data through relationship (Not in the template)

I want to stress that this problem only occurs outside of a template, such as when I try to access properties of related objects while in a controller, unit test, etc. Rendering the template seem to get the property well and work as expected.
Here is a simple example in JS Bin with a failing test http://jsbin.com/ihumuk/4/edit which repros my problem. The passing test asserts that the property is accessible and rendered in the template as expected. The failing test shows that I get null when I try to access the property with get. Really nothing fancy here but I don't understand why it's returning null.
Here is the application part of the JS Bin example:
App.ApplicationRoute = Em.Route.extend({
model: function() {
return App.Foo.find();
}
});
App.Store = DS.Store.extend({
adapter: DS.FixtureAdapter.create()
});
App.Foo = DS.Model.extend({
name: DS.attr("string"),
/**
* The subject under test
*/
childName: function() {
return this.get("child.name");
}.property("child.name"),
child: DS.belongsTo("App.Bar")
});
App.Bar = DS.Model.extend({
name: DS.attr("string")
});
App.Foo.FIXTURES = [{
id: 1,
name: "Fred",
child: 3
}, {
id: 2,
name: "Barney",
child: 4
}];
App.Bar.FIXTURES = [{
id: 3,
name: "Pebbles"
}, {
id: 4,
name: "Bam Bam"
}];
This passes.
test("Child name is rendered", function() {
expect(1);
visit("/").then(function() {
ok(find("div:contains(Pebbles)").length);
});
});
This fails.
test("Child name is accessed", function() {
expect(2);
var foo = App.Foo.find(1);
equal(foo.get("childName"), "Pebbles");
equal(foo.get("child.name"), "Pebbles");
});
This has to be something simple/stupid like forgetting a character or something, but I think I've driven myself too far into frustration to think clearly for a while. Thanks in advance for any help.
You need to use the then to know when the data is loaded
asyncTest("Child name is accessed", function() {
expect(2);
// load the data from server
App.Foo.find(1).then(function(foo) {
// the child id is 3, we need to fetch the remaining data
// and this is async, because of the ajax request
foo.get("child").then(function(child) {
equal(child.get("name"), "Pebbles");
// childName call child.name, but since the
// data is loaded, isn't necessary to use a second then
equal(foo.get("childName"), "Pebbles");
start();
});
});
});
In ember data, like major of the orm's, the data is lazy loaded, for relationships. This is because, isn't needed to return all loaded object graph, let's leave the user ask for what it want, and then load.
Because some implementations are async, like: websql, indexeddb, ajax, websockets etc. The interface of ember-data is async, so you need to use the then method to know when the data is loaded or failed.
The things work in your template, because it are binding aware. Even when the change are async, it will be finished later, and the bindings will be notified and updated.
I have updated your demo, and the tests pass http://jsbin.com/eqojaj/1/edit

Search in dijit.Tree

In one of my projects I use a dijit.Tree control. I need to add a search to the tree and show only those nodes/leafs which have the searched term in them. However I can't seem to figure out how that can be achieved. Could anybody please help me?
im not entirely sure that your question entirely but it should give hint whereas to go.
Lets use reference documentation example as offset, there is 1) a store 2) a model and 3) the tree
var store = new ItemFileReadStore({
url: "{{dataUrl}}/dijit/tests/_data/countries.json"
});
var treeModel = new ForestStoreModel({
store: store,
query: {"type": "continent"}, // note, this bit
rootId: "root",
rootLabel: "Continents",
childrenAttrs: ["children"]
});
new Tree({
model: treeModel
}, "treeOne");
Interpret the above as such; You have loaded all known countries and continents but 'user' has selected only to show continents by using query on the model - and the hierachy is then represented in a tree structure.
You want a textbox with searching capeabilities, so we hook into onChange
new dijit.form.TextBox({
onChange: function() {
...
}
});
First bit, getting variables
var searchByName = this.get("value");
var oQuery = treeModel.query;
Next, set a new query on the model - preserving the old ones with an object mixin
treeModel.query = dojo.mixin(oQuery, { name: '*'+searchByName+'*' });
Last, notify the model and its tree that changes has occurred - and requery the visible items.
treeModel._requeryTop();
NB If the top-level item (for ForestModel) is not visible, none of its child elements will show, even if the search-string matches those. (Examplewise, Alabama is not shown if US Continent is not matched by query)
EDIT
As OP has the agenda to go by the 'NB', this may not fit needs 100% but its what dojo offers with dijit.Tree.. As it will get rather a lengthy process to recode the model/store queries to include parentbranches up until root i will not do this here - but there are a few tricks still ;)
var tree = new dijit.Tree( {
/**
* Since TreeNode has a getParent() method, this abstraction could be useful
* It sets the dijit.reqistry id into the item-data, so one l8r can get parent items
* which otherwise only can be found by iterating everything in store, looking for item in the parent.children
*
*/
onLoad : function() {
this.forAllNodes(function(node) {
// TreeNode.item <-- > store.items hookup
node.item._NID = node.domNode.id
});
},
/* recursive iteration over TreeNode's
* Carefull, not to make (too many) recursive calls in the callback function..
* fun_ptr : function(TreeNode) { ... }
*/
forAllNodes : function(parentTreeNode, fun_ptr) {
parentTreeNode.getChildren().forEach(function(n) {
fun_ptr(n);
if(n.item.children) {
n.tree.forAllNodes(fun_ptr);
}
})
}
});
(non-tested, but might just work) Example:
// var 'tree' is your tree, extended with
tree.forAllNodes = function(parentTreeNode, fun_ptr) {
parentTreeNode.getChildren().forEach(function(n) {
fun_ptr(n);
if(n.item.children) {
n.tree.forAllNodes(fun_ptr);
}
})
};
// before anything, but the 'match-all' query, run this once
tree.forAllNodes(tree.rootNode, function(node) {
// TreeNode.item <-- > store.items hookup
node.item._NID = node.domNode.id
});
// hopefully, this in end contains top-level items
var branchesToShow = []
// run fetch every search (TextBox.onChange) with value in query
tree.model.store.fetch(query:{name:'Abc*'}, onComplete(function(items) {
var TreeNode = null;
dojo.forEach(items, function(item) {
TreeNode = dijit.byId(item._NID+'');
while(TreeNode.getParent()
&& typeof TreeNode.getParent().item._RI == 'undefined') {
TreeNode = TreeNode.getParent();
}
branchesToShow.push(TreeNode.item);
});
}});
// Now... If a success, try updating the model via following
tree.model.onChildrenChange(tree.model.root, branchesToShow);

Set Value on dijit/form/FilteringSelect after its already been created

I have FilteringSelect using a MemoryStore. When a user types a value that is not in the store, they are prompted, asking if they would like to add the new value to the store.
If they do, we call the server, create the new item, and on the response, we publish an event.
The topic subscriber is notified that a new item was created and added to the MemoryStore, which adds the option to the filteringselect.
At this point, the filtering select still has the same displayValue, and the option exists in the select. FilteringSelect.get("value") still returns "".
If you were to type a space, then hit backspace, (ending up with the same value), FilteringSelect.get("value") would return the correct item id.
FilteringSelect.set("value", data[0].id) doesn't do anything, no exception thrown, no affect.
Here's the code, contains some of the random calls I tried.
require(["dojo/store/Memory", "dojo/_base/array", "dojo/topic"],
lang.hitch(this, function(Memory, array, topic) {
this.liftStore = new Memory({
data: []
});
array.forEach(data, lang.hitch(this, function(entry, i) {
this.liftStore.data.push({
name: entry.Name,
id: entry.ID,
identifier: entry.ID
});
}));
this.lift.set("store", this.liftStore);
topic.subscribe("LiftLog/NewLift", lang.hitch(this, function(data) {
debugger;
data[0].selected = true;
data[0].identifier = data[0].id;
this.liftStore.data.push(data[0]);
this.lift.reset();
this.lift.set("value", data[0].id);
this.lift.set("value", data[0].id.toString());
}));
}));
Have you tried setting the item (i.e. filteringSelect.set("item", newItem) instead of setting the value? Note that you should give it the whole item, not just the id or the displayed value.
So, push the item into the store, and then set the item on the FilteringSelect:
this.liftStore.data.push(newItem);
this.lift.set("item", newItem);