I'm trying to retrieve the list of valid Reasons for a WorkItem (MS Agile 5 template), which works correctly for a new work item.
However for editing existing work items, the AllowedValues is always empty, whatever the state.
WorkItem item = GetItem(...)
item.Fields["Reason"].AllowedValues.ToList() // always empty
(ToList is my own extension method).
The problem is, the Visual Studio UI correctly updates the Reasons list when you change the state in the drop down list.
The Reason field also has IsLimitedToAllowedValues=false but when you enter an arbitary value it complains that it's not a valid list item.
We also use MS Agile 5 & the following worked fine on an existing work items named myWorkItem (I tried with User Story & Task):
FieldDefinitionCollection fdc = myWorkItem.Type.FieldDefinitions;
Console.WriteLine(myWorkItem.Type.Name);
foreach (FieldDefinition fd in fdc)
{
if(fd.Name == "Reason")
{
AllowedValuesCollection avc = fd.AllowedValues;
foreach (string allowedValue in avc)
{
Console.WriteLine(allowedValue.ToString());
}
}
}
Related
I'm a newbie in NetSuite Scripting and was recently asked to apply the value from a date field (custbody_expiration_date) on item receipt transaction body to the expiration date field in the inventory details of all items when the item receipt is created.
Since there is no way to create a workflow on inventory details, I've managed to work out below codes however I'm keeping getting all sorts of different error message. Below is one of them after I click on save on item receipt.
Notice (SuiteScript)
org.mozilla.javascript.EcmaError: TypeError: Cannot find function getCurrentLineItemValue in object standard record. (/SuiteScripts/ARROW/Expiration_date_apply_to_all (1).js#27)
I am very confused on the difference between dynamic and standard mode, which functions should be used in which mode? Also, I am a bit hesitated on whether user event script is the correct way to go?
/**
*#NApiVersion 2.0
*#NScriptType UserEventScript
*#NModuleScope Public
*/
define(['N/record','N/search'], function (record, search) {
function beforeSubmit(context) {
var IRrecord = context.newRecord;
var numberOfLineItems = IRrecord.getLineCount({
sublistId: 'item'
});
var expirationdate = IRrecord.getValue({
fieldId: 'custbody_expiration_date'
});
for (var i=1; i<=numberOfLineItems; i++){
IRrecord.setSublistValue({
sublistId: 'item',
fieldId: 'item',
line: i,
value: true
});
//First get Lot Number and Quantity
var lotNumber = IRrecord.getCurrentLineItemValue('item', 'receiptinventorynumber');
var quantity = IRrecord.getCurrentLineItemValue('item', 'quantity');
var inventoryDetail = IRrecord.createCurrentLineItemSubrecord('item','inventorydetail');
inventoryDetail.selectNewLineItem('inventoryassignment');
inventoryDetail.setCurrentLineItemValue('inventoryassignment', 'issueinventorynumber', lotNumber);
inventoryDetail.setCurrentLineItemValue('inventoryassignment', 'quantity', quantity);
inventoryDetail.setCurrentLineItemValue('inventoryassignment', 'expirationdate', expirationdate);
inventoryDetail.commitLineItem('inventoryassignment');
inventoryDetail.commit();
IRrecord.commitLineItem('item');
}
nlapiSubmitRecord(IRrecord);
}
return {
beforeSubmit: beforeSubmit
}
});
Dynamic records are the kind you see client-side (as a rule) - modify a field value and some other field becomes refreshed and updated in real time. Forms sometimes need to have their fields filled in a particular order to prevent form completion errors triggering or field sourcing to work. For example, when entering a sales order, selecting the customer then defaults the sales tax when items are added to the order. Errors may be thrown at any point before the record save because a field is triggering dynamic sourcing (updating other fields), based on what has been entered.
Standard mode is - less dynamic. You populate the fields of the record in any order you choose, and when the save is performed, you choose whether sourcing (updating other fields from the data available) is triggered. Any errors in data entry are reported when the save is performed. I think it also has a lower client-side load as there are fewer AJAX queries being triggered.
Both are available in client-side and server-side javascript, but some record types cannot be updated client-side and must be done server-side using workflow actions, User Event, Restlet, Suitelets, or scheduled scripts. To the best of my knowledge, inventory subrecords on fulfillments, receipts and the like are one such type.
The way lines are updated changes between dynamic and standard mode. In dynamic mode, lines are selected, updated then committed and the methods used would be :
selectLine
setCurrentLineItemValue
commitLine (only do this if actually changing the line)
For standard mode, the way of changing lines is only to use setSublistValue and include the line number in the parameters.
Workflow action scripts will load the record in dynamic mode, but the load method can be investigated using the isDynamic() method on the record.
The other thing is, in SuiteScript 2, sublist lines are indexed from 0, not from 1 as your script is using. What's confusing is, in Suitescript 1, indexing was from 1. The code is using a mix of v1 & v2. nlapiSubmitRecord is v1, IRrecord.save is v2.
And for more information, see SuiteAnswer 79715 which explains how to set a value on the inventory detail on an item receipt. The example reloads the record in standard mode and updates the inventoryStatus field. SuiteAnswer 45372 explains the Record object and the difference between standard and dynamic modes. Take a look at SuiteAnswer 67605 which explains the basics of SuiteScript v2. SuiteAnswers is an amazing resource and the search is surprisingly good. I can also recommend Eric T Grubaugh's site (#erictgrubaugh) which has some great videos including comparisons between v1 & v2.
I have created dynamic attributes,
There are three products in the array, then each of them has its own attributes.
Everything works fine initially, once I run "Copy Attributes" code to copy attributes to all other products, the input model starts inserting model value to all other attributes too.
for(let i in this.products) {
if(i != this.product_active) {
this.products[i].attributes = this.products[this.product_active].attributes
}
}
Here is the fiddle i have created for this issue:
https://jsfiddle.net/sukhcha_in/4o9k2ezn/
In this fiddle you will see three products with their own attributes (Input model works fine),
Now press "Copy Attributes" button, attributes of the active product will be copied to other products too.
Now input data to any product, the input model will input same data to all products, instead of selected product. It completely ignores the selected product.
Is there any issue with my code?
You copy the same attributes object to all three products, hence the properties are shared.
Instead, you should create a new copy of the object when copying, e. g. like this using the spread syntax:
for(let i in this.products) {
if(i != this.product_active) {
this.products[i].attributes = {... this.products[this.product_active].attributes}
}
}
I'm working on a .NET application to add user stories to our Rally workspace, and I'd like to set one of the user stories as a predecessor to the next one. I can add the stories just fine, but the predecessor/successor relationship isn't being created. I'm not getting any errors, it's just not creating the predecessor. (I'm using the Rally.RestApi .NET library).
I have the _ref value for the first story, and I've tried setting the "Predecessors" property on the DynamicJsonObject to that.
followUpStory["Predecessors"] = firstStoryRef;
I also tried creating a string array, no luck.
followUpStory["Predecessors"] = new string[] { firstStoryRef };
I kept the code examples to a minimum since the stories are being created fine and this is the only issue, but let me know if sharing more would be helpful.
The easiest way is to use the AddToCollection method. Check out the docs:
http://rallytools.github.io/RallyRestToolkitFor.NET/html/efed9f73-559a-3ef8-5cd7-e3039040c87d.htm
So, something like this:
DynamicJsonObject firstStory = new DynamicJsonObject();
firstStory["_ref"] = firstStoryRef;
List<DynamicJsonObject> predecessors = new List<DynamicJsonObject>() { firstStory};
OperationResult updateResult = restApi.AddToCollection(followUpStoryRef, "Predecessors", predecessors);
In CRM 2013 and 2011 I have some data that I've imported in. When you view the records they have, at the top in big letters "New Contact" or "New Account" etc depending on their type. I've looked at the form header and tried adding a field there (that I want displayed) thinking that it defaults to to new whatever since there is no other field. This is not the case. Primarily I'm using 2013, but the same thing happens in 2011 as well.
I tested to see if it's just for the imported records, but it also happens when I create new ones. Is this something that CRM does usually, and if so is there a way to tell it to display something else?
I believe what you're asking about is the way CRM displays the name of the Entity in the page title and the form header. If so, this is a (completely unsupported) function that I call to update the name of an entity in CRM 2011. I'm guessing it won't work for 2013 though.
setDisplayName: function (name) {
// Updates the Document Title
var title = parent.document.title;
var start = title.indexOf(':') + 2;
var end = title.lastIndexOf('-') - 1;
parent.document.title = title.substring(0, start) + name + title.substring(end);
// Sets the div Name
document.getElementById("form_title_div").childNodes[2].childNodes[0].innerText = name;
},
You can call it on the onLoad of the Entity and clear it, or set it to whatever you like.
What OP wanted was to remove the New Case label when creating a new Case (or any other entity)
I've done this today in CRM 2013 with this line
//Remove New Case label
document.getElementById("FormTitle").style.visibility = "hidden";
I want to add property to existing document (using clues form http://ravendb.net/docs/client-api/partial-document-updates). But before adding want to check if that property already exists in my database.
Is any "special,proper ravendB way" to achieve that?
Or just load document and check if this property is null or not?
You can do this using a set based database update. You carry it out using JavaScript, which fortunately is similar enough to C# to make it a pretty painless process for anybody. Here's an example of an update I just ran.
Note: You have to be very careful doing this because errors in your script may have undesired results. For example, in my code CustomId contains something like '1234-1'. In my first iteration of writing the script, I had:
product.Order = parseInt(product.CustomId.split('-'));
Notice I forgot the indexer after split. The result? An error, right? Nope. Order had the value of 12341! It is supposed to be 1. So be careful and be sure to test it thoroughly.
Example:
Job has a Products property (a collection) and I'm adding the new Order property to existing Products.
ravenSession.Advanced.DocumentStore.DatabaseCommands.UpdateByIndex(
"Raven/DocumentsByEntityName",
new IndexQuery { Query = "Tag:Jobs" },
new ScriptedPatchRequest { Script =
#"
this.Products.Map(function(product) {
if(product.Order == undefined)
{
product.Order = parseInt(product.CustomId.split('-')[1]);
}
return product;
});"
}
);
I referenced these pages to build it:
set based ops
partial document updates (in particular the Map section)