Copy previous value in a sublist field - netsuite

I'm trying to add a field to item sublist on sales order record that copies the original value of another field when ever it is changed. It pretty much preserves the previous value of another field. When ever I do a nlapiGetCurrentLineItemValue at Validate field trigger in my client script, it is giving me the new value(changed by user) not the one before changing it. Is there a way to get the value of a field before it is edited at validatefield event in client script? or by any other ways?
function validateFieldChanged(type, name, linenum) {
if (type == 'item' && name == 'custcol_commit_date') {
nlapiSetCurrentLineItemValue('item', 'custcol_last_commit_date', nlapiGetCurrentLineItemValue('item', 'custcol_commit_date'), true,true);
}
return true;
}

I've previously done something similar.
At the top of your script, declare a variable such as var existingValue;
Then in your lineInit function, get the field value and store it in existingValue.
Then when you have your validateField, you compare the be value with the existingValue.

Related

Applying logic to button Make Copy - Netsuite

I just started with Netsuite and Suitescript 2.1. I am wondering if I can apply any logic to the "Make Copy" button via suitescript.
The make copy button is on the opportunity > sublist Item > Line item.
Examples of what I want to do:
Reset certain fields of the copied line
Fill in certain fields of the copied line (with a certain logic
behind it)
I already found a solution. I use the validateLine function. When making a copy of a lineitem in Netsuite the lineitem field: "line" has an empty string value until the line is created by clicking the "Add" button or clicking outside of the copied lineitem. I will check if that field is empty, if yes it means the line is a copy. Afterwards I can also set a custom field isCopy = true.
const lineIsCopied = () => {
let lineNumber = opportunity.getCurrentSublistValue({
sublistId: 'item',
fieldId: 'line'
});
if (lineNumber) {
//linenumber is existing this means line is not a copy
return false;
} else {
//linenumber is empty this mean line is a copy
return true;
}
};
Try the 'validateInsert' within a Client Script.
Make sure your function return 'true' for a valid insert, otherwise any insert for any sublist won't succeed.

How to move sublist fields created from User Event script

I added a sublist field on a transaction. For instance a Sales Order. When you add the field via user event script, it positions the field at the end of the sublist. Is there a way to position the field? This can't be accomplished in the UI as the field is added via script. It's a select type field, so I am trying to modify the list values with client script and can only do that if the field is created in my user even script. My code works perfectly fine, it's just the field is at the end of the sublist line(far right and have to scroll). I am using SuiteScript 1.0 but am open to using 2.0 if I need to.
This is for suitescript 2.0
This has sort of turned into two questions so I will give an answer for one and then the solution, for clarity. The short answer is you cannot move a sublist field when created in a user event (however there is a solution to that.)
you can add a sublist field by getting the sublist and using the sublist.addField method.
function beforeLoad(context){
var form = context.form;
var sublist = form.getSublist({
id : 'item'
});
sublist.addField({
id: 'fieldid you want to use for script reference ect.',
type: serverWidget.FieldType.CHECKBOX, //any supported TYPE
label: 'Label users will see in sublist'
});
}
If done this way, there will be a new column on the end of the items sublist that cannot be moved.
To be able to move the location of the column do the following.
Navigate to
Customization
Lists, Records, & Fields
Transaction Line Fields
add a new field and apply to the sublist you want it used on.
you can assign and id which will be prefixed with custcol so start your id with an _ and give it a name.
Once this is complete you can access the field by id and change the value in your user event script before load
function beforeLoad(context){
var form = context.form;
var sublist = form.getSublist({
id : 'item'
});
sublist.setSublistValue({
id: 'customcol_id_created_in_ui',
line: 1, //line you want to access if needing to set all you will have to loop through and set each one.
value: "your value"
});
}
If you go to the API reference and look at the ui/serverWidget module and navigate to sublist you can find all of the methods and options for manipulating sublist there.
In SuiteScript 2.x you would use the N/ui/serverWidget module, create the field and then use the Form.insertField(options) method, passing in the field you created as options.field and the existing field which you want to insert your field before as options.nextfield. Note that Form refers to the form object passed to the user event script in the scriptContext.
i don't believe there is a SS1.0 equivalent.

Netsuite - Set Line Item Value

I am trying to figure out how to set a custom value item from the value of another field on the item field. I am not getting any errors, but it is not changing the value.
Here is the code:
function validatePOLineItem(type){
if(type == 'item'){
for (var i = 0; i <= nlapiGetLineItemCount('item'); i++) {
// Get the value for amount on the item line
var amount = nlapiGetCurrentLineItemValue('item', 'amount');
// Get the value for the PO Amount on the item line
var po_amount = nlapiGetCurrentLineItemValue('item', 'custcol_po_amount');
// Set PO Amount equal to Amount on the item line
nlapiSetCurrentLineItemValue('item', po_amount, amount);
}
}
}
Looks like you left off the column name you are trying to set. Also, you should just have to update the "current" lineā€¦
function validatePOLineItem(type){
if(type == 'item'){
var amount = nlapiGetCurrentLineItemValue('item', 'amount');
nlapiSetCurrentLineItemValue('item', 'custcol_po_amount', amount);
}
}
Is this a client side script or a user event script? If it is a client side script that is deployed on the validate line event, then you do not need to do a loop. Since the function will trigger every time a line is added. Also you will need to add 'return true' as the last line for the line to be added.
You cannot manipulate the amount field programmatically. You need to modify the quantity or the rate instead. If you are trying to apply a discount or something like that, then I recommend using NetSuite's Discount Items or Promo Codes mechanisms.
Question: Why do you need to have a loop if you are just dealing with the current line item?
Suggested Solution: If you want to achieve it, you can set the Rate equal to 'custcol_po_amount' but this will only work if the quantity is 1 and assuming that the value on 'custcol_po_amount' is accurate.

Can't modify/remove a field from an ActivityNode using sbt

I created an ActivityNode (an Entry) and I can add custom fields with the
setFields(List<Field> newListField)
fonction.
BUT
I am unable to modify these fields. (In this case I try to modify the value of the field named LIBENTITE)
FieldList list = myEntry.getTextFields();
List<Field> updatedList = new ArrayList<Field>();
//I add each old field in the new list, but I modify the field LIBENTITE
for(Field myField : list){
if(myField.getName().equals("LIBENTITE")){
((TextField)myField).setTextSummary("New value");
}
updatedList.add(myField);
}
myEntry.setFields(updatedList);
activityService.updateActivityNode(myEntry);
This code should replace the old list of fields with the new one, but I can't see any change in the custom field LIBENTITE of myEntry in IBM connections.
So I tried to create a new list of fields, not modifying my field but adding a new one :
for(Field myField:list){
if(!myField.getName().equals("LIBENTITE")){
updatedList.add(myField);
}
}
Field newTextField = new TextField("New Value");
newTextField .setFieldName("LIBENTITE");
updatedList.add(newTextField );
And this code is just adding the new field in myEntry. What I see is that the other custom fields did not change and I have now two custom fields named LIBENTITE, one with the old value and the second with the new value, in myEntry.
So I though that maybe if I clear the old list of Fields, and then I add the new one, it would work.
I tried the two fonctions
myEntry.clearFieldsMap();
and
myEntry.remove("LIBENTITE");
but none of them seems to work, I still can't remove a custom field from myEntry using SBT.
Any suggestions ?
I have two suggestions, as I had (or have) similar problems:
If you want to update an existing text field in an activity node, you have to call node.setField(fld) to update the field in the node object.
Code snippet from my working application, where I'm updating a text field containing a (computed) start time:
ActivityNode node = activityService.getActivityNode(id);
node.setTitle(formatTitle()); // add/update start and end time in title
boolean startFound = false;
// ...
FieldList textfields =node.getTextFields();
Iterator<Field> iterFields = textfields.iterator();
while (iterFields.hasNext()) {
TextField fld = (TextField) iterFields.next();
if (fld.getName().equals(Constants.FIELDNAME_STARTTIME)) {
fld.setTextSummary(this.getStartTimeString()); // NOTE: .setFieldValue does *not* work
node.setField(fld); // write updated field back. This seems to be the only way updating fields works
startFound=true;
}
}
If there is no field with that name, I create a new one (that's the reason I'm using the startFound boolean variable).
I think that the node.setField(fld) should do the trick. If not, there might be a way to sidestep the problem:
You have access to the underlying DOM object which was parsed in. You can use this to tweak the DOM object, which finally will be written back to Connections.
I had to use this as there seems to be another nasty bug in the SBT SDK: If you read in a text field which has no value, and write it back, an error will be thrown. Looks like the DOM object misses some required nodes, so you have to create them yourself to avoid the error.
Some code to demonstrate this:
// ....
} else if (null == fld.getTextSummary()) { // a text field without any contents. Which is BAD!
// there is a bug in the SBT API: if we read a field which has no value
// and try to write the node back (even without touching the field) a NullPointerException
// will be thrown. It seems that there is no value node set for the field. We
// can't set a value with fld.setTextSummary(), the error will still be thrown.
// therefore we have to remove the field, and - optionally - we set a defined "empty" value
// to avoid the problem.
// node.remove(fld.getName()); // remove the field -- this does *not* work! At least not for empty fields
// so we have to do it the hard way: we delete the node of the field in the cached dom structure
String fieldName = fld.getName();
DeferredElementNSImpl fldData = (DeferredElementNSImpl) fld.getDataHandler().getData();
fldData.getParentNode().removeChild(fldData); // remove the field from the cached dom structure, therefore delete it
// and create it again, but with a substitute value
Field newEmptyField = new TextField (Constants.FIELD_TEXTFIELD_EMPTY_VALUE); // create a field with a placeholder value
newEmptyField.setFieldName(fieldName);
node.setField(newEmptyField);
}
Hope that helps.
Just so that post does not stay unanswered I write the answer that was in a comment of the initial question :
"currently, there is no solution to this issue, the TextFields are read-only map. we have the issue recorded on github.com/OpenNTF/SocialSDK/issues/1657"

Can't set Orchard field values unless item already created

I seem to be having a problem with assigning values to fields of a content item with a custom content part and the values not persisting.
I have to create the content item (OrchardServices.ContentManager.Create) first before calling the following code which modifies a field value:
var fields = contentItem.As<MyPart>().Fields;
var imageField = fields.FirstOrDefault(o => o.Name.Equals("Image"));
if (imageField != null)
{
((MediaLibraryPickerField)imageField).Ids = new int[] { imageId };
}
The above code works perfectly when against an item that already exists, but the imageId value is lost if this is done before creating it.
Please note, this is not exclusive to MediaLibraryPickerFields.
I noticed that other people have reported this aswell:
https://orchard.codeplex.com/workitem/18412
Is it simply the case that an item must be created prior to amending it's value field?
This would be a shame, as I'm assigning this fields as part of a large import process and would inhibit performance to create it and then modify the item only to update it again.
As the comments on this issue explain, you do need to call Create. I'm not sure I understand why you think that is an issue however.

Resources