My Restlet should either add or update an invoice with the line items. The add bit works - invoice + line items, but the update doesn't appear to add a new line item. Code looks like this:
update_record = nlapiLoadRecord('invoice', invoice_id)
var itemcount = update_record.getLineItemCount('item');
for (var i = 0; itemcount != null && i < itemcount; i++) {
if (jsonobject.item[i].item) {
update_record.setLineItemValue('item', 'item', i + 1, jsonobject.item[i].item)
}
}
var id = nlapiSubmitRecord(update_record, true);
nlapiLogExecution('DEBUG', 'id = ', id)
return id;
Instead of setLineItemValue, try using the series of selectLineItem, setCurrentLineItemValue, and commitLineItem methods. setLineItemValue is not supported in all scenarios or on all fields.
See the NS Help article titled nlobjRecord for details on all of these methods.
Related
I am trying to get a count of the number of items in a Sharepoint List.
I can obtain counts for lists equal to or less than 200. But each page of results contains 200 items and I cannot figure out how to get the next pages.
int listCount = 0;
Microsoft.Graph.List list = new Microsoft.Graph.List();
var queryOptions = new List<QueryOption>()
{
new QueryOption("select", "id"),
new QueryOption("expand", "columns(select=name),items(expand=fields(select=CustomerName))")
};
GraphServiceClient graphServiceClient = GetAuthenticatedGraphClient(scopes).Result;
list = await graphServiceClient.Sites[$"{siteId}"].Lists[$"{listId}"].Request(queryOptions).GetAsync();
if (list.Items != null)
{
listCount = list.Items.Count;
}
I've read through this
https://learn.microsoft.com/en-us/graph/paging
and this
https://learn.microsoft.com/en-us/graph/sdks/paging?tabs=csharp
However #odata.nextLink isn't in the response, and converting the pageIterator code from messages to lists doesn't return any data at all.
The items object does have a field called NextPageRequest, but it is null.
Does anyone please have some example code on how to obtain more pages of Sharepoint List items after the first page?
I found an answer, with some inspiration from
https://github.com/microsoftgraph/msgraph-sdk-dotnet/issues/891
The answer was to request Lists[{}].Items, which retrieves a ListItemsCollectionPage object which contains a count. If that count is 200, then QueryOptions is used in to repeat the request for the next ItemsPage
int listCount = 0;
Microsoft.Graph.IListItemsCollectionPage listItems;
GraphServiceClient graphServiceClient = GetAuthenticatedGraphClient(scopes).Result;
listItems = await graphServiceClient.Sites[$"{siteId}"].Lists[$"{listId}"].Items.Request().GetAsync();
itemCount = listItems.Count();
var nextPage = listItems.NextPageRequest;
while (nextPage != null)
{
listItems = await graphServiceClient.Sites[$"{siteId}"].Lists[$"{listId}"].Items.Request(nextPage.QueryOptions).GetAsync();
itemCount = itemCount + listItems.Count();
nextPage = listItems.NextPageRequest;
}
I am trying to set quantity field value in my sublist and quantity in my sublist subrecord(inventorydetail). When I try to .editLineItemSubrecord(), system throws an error:
"code\":\"CANNOT_EDIT_SUBRECORD\",\"details\":\"Cannot edit this subrecord, it is either in readonly state or dead state.\"
My code is as follows:
function updateRec(matRecArr, request, qtySetByUser, itemToFind) {
var tranOrderRec = nlapiLoadRecord('transferorder', matRecArr)
var count = tranOrderRec.getLineItemCount('item');
for (var i = 1; i < count + 1; i++) {
var indx = tranOrderRec.findLineItemValue('item', 'item', itemToFind);
if (indx > -1) {
tranOrderRec.selectLineItem('item', indx);
tranOrderRec.setCurrentLineItemValue('item', 'quantity', qtySetByUser);
var subrecord = tranOrderRec.editLineItemSubrecord('item', 'inventorydetail', 1);
subrecord.selectLineItem('inventoryassignment', 1);
subrecord.setCurrentLineItemValue('inventoryassignment', 'quantity', qtySetByUser);
subrecord.commitLineItem('inventoryassignment');
subrecord.commit();
}
tranOrderRec.commitLineItem('item');
tranOrderRec.commit();
}
nlapiSubmitRecord(tranOrderRec, true, true);
nlapiLogExecution('debug', 'MATERIAL REC. UPDATED!', tranOrderRec);
}
can anyone tell me the mistake I am doing?
Refer "Editing an Address Subrecord on an Existing Customer Record" in help or suite answers
I have a client script which is doing two things:
Calculate total weight of sales order on add of line
Copy tax code from custom field to native field
The script deploys correctly when adding lines in the UI from the sublist but when using the "add multiple" button and selecting and adding multiple lines at once, the script does not trigger. Here is the script as I have it written so far (I have 2 versions, one which is validateLine and one which is postSourcing).
Validate Line:
function calculateTotalWeight(type){
var lines = nlapiGetLineItemCount('item');
var totalWeight = 0 ;
for(var i=1; i< lines+1 ; i++){
var weight = nlapiGetLineItemValue('item', 'custcol_itemweight', i);
var quantity = nlapiGetLineItemValue('item', 'quantity', i);
var weightTimesQuantity = weight * quantity;
totalWeight = totalWeight + weightTimesQuantity ;
}
nlapiSetFieldValue('custbody_items_total_weight', totalWeight);
}
function validateLine(type){
var taxableCustomer = nlapiGetFieldValue('custbody_taxable');
if (taxableCustomer == 'T'){
var customTax = nlapiGetCurrentLineItemValue(type,'custcol_taxcode');
nlapiLogExecution('DEBUG', 'Custom Tax Value',customTax);
nlapiSetCurrentLineItemValue('item','taxcode',customTax,true,true);
}
return true;
}
postSourcing:
function calculateTotalWeight(type){
var lines = nlapiGetLineItemCount('item');
var totalWeight = 0 ;
for(var i=1; i< lines+1 ; i++){
var weight = nlapiGetLineItemValue('item', 'custcol_itemweight', i);
var quantity = nlapiGetLineItemValue('item', 'quantity', i);
var weightTimesQuantity = weight * quantity;
totalWeight = totalWeight + weightTimesQuantity ;
}
nlapiSetFieldValue('custbody_items_total_weight', totalWeight);
}
function postSourcing(type, name)
{
if(type === 'item' && name === 'item')
{
var custcol_taxcode = nlapiGetCurrentLineItemValue('item', 'custcol_taxcode');
var line = nlapiGetCurrentLineItemIndex(type);
{
nlapiSetCurrentLineItemValue('item', 'taxcode', custcol_taxcode);
}
}
}
How can I get this script to trigger with the add multiple button?
You’ll need to calculate the weight on the recalc event. The following is from a script that works as a scriptable cart/checkout script. It can be deployed in an eCommerce context or the UI context. (i.e. a deployed client script as opposed to a client script attached to a form)
Note:You should set up your tax codes so that they are assigned automatically. It is possible to script those but it's a fair pain to do.
the field custbody_sco_toggle is a checkbox field that keeps the script out of an infinite loop if your recalc scripts might change the order total.
var scriptableCart = (function(){
var cartScript = {};
var isUI = ('userinterface' == nlapiGetContext().getExecutionContext());
var isWeb = !isUI;
function tty(type, title, detail){
var haveWindow = typeof window != 'undefined';
if(isUI && haveWindow && window.console) window.console.log(title, detail);
else if(isWeb || !haveWindow) nlapiLogExecution(type, title, (detail || '') +' '+entranceId +' '+nlapiGetContext().getExecutionContext()); // this slows down the NS GUI
}
function calculateTotalWeight(type){...}
cartScript.recalc = function(type){
tty("DEBUG", "entered "+ type +" with toggle: "+ nlapiGetFieldValue('custbody_sco_toggle'));
if('F' == nlapiGetFieldValue('custbody_sco_toggle')){
try{
nlapiSetFieldValue('custbody_sco_toggle', 'T', false, true);
if(type == 'item'){
calculateTotalWeight(type);
}
}catch(e){
tty('ERROR', 'In recalc for '+ type, (e.message || e.toString()) + (e.getStackTrace ? (' \n \n' + e.getStackTrace().join(' \n')) : ''));
}finally{
nlapiSetFieldValue('custbody_sco_toggle', 'F');
}
}
};
return cartScript;
})();
I am trying to get nlapiGetOldRecord sublist values.
var record= nlapiGetOldRecord();
var testCount= record.getLineItemCount('recmachcustrecord_test');
The above linecount api is working and output the number of lines. But when i try to get its line item values it's giving following error "Cannot find function nlapiGetLineItemValue in object nlobjRecord.". My code.
for (var i = 1; i <= testCount; i++) {
var name= record.nlapiGetLineItemText('recmachcustrecord_test', 'custrecord_name', i);
var quantity = record.nlapiGetLineItemValue('recmachcustrecord_test', 'custrecord_qty', i);
nlapiLogExecution('DEBUG', 'Detail: ', name + ' and ' + quantity);
}
I have found the solution. Basically i was trying to get line item text/value using nlapiGetLineItemText api and which is not nlobjRecord api. so for sublist nlobjRecord getLineItemText api works.
var record= nlapiGetOldRecord();
var testCount= record.getLineItemCount('recmachcustrecord_test');
for (var i = 1; i <= testCount; i++) {
var name= record.getLineItemText('recmachcustrecord_test', 'custrecord_name', i);
var quantity = record.getLineItemValue('recmachcustrecord_test', 'custrecord_qty', i);
nlapiLogExecution('DEBUG', 'Detail: ', name + ' and ' + quantity);
}
I was looking for a solution to the problem of getting a blank default when using a lookup in a field in Sharepoint. Kit Menke's solution to "Dropdown field - first item should be blank" question works perfectly for my first field with a lookup. But I can't make it work if have more that one field in the same list where I need to insert a blank for each lookup field (works only for the first field). I tried adding a new "Web Part" and applying the same code to the second field, but doesn't work. Any ideas? Thanks in advance
Follow-up to my answer here: Dropdown field - first item should be blank
Version 2.0 allows you to add the names of your dropdowns to dropdownNames in the MyCustomExecuteFunction function. As with the first one, this will work only with required single select lookup fields. Also, in order to edit the page again and update your Content Editor Web Part you may have to choose a value for your dropdowns otherwise you get the dreaded An unexpected error has occurred.. Good luck! :D
<script type="text/javascript">
function GetDropdownByTitle(title) {
var dropdowns = document.getElementsByTagName('select');
for (var i = 0; i < dropdowns.length; i++) {
if (dropdowns[i].title === title) {
return dropdowns[i];
}
}
return null;
}
function GetOKButtons() {
var inputs = document.getElementsByTagName('input');
var len = inputs.length;
var okButtons = [];
for (var i = 0; i < len; i++) {
if (inputs[i].type && inputs[i].type.toLowerCase() === 'button' &&
inputs[i].id && inputs[i].id.indexOf('diidIOSaveItem') >= 0) {
okButtons.push(inputs[i]);
}
}
return okButtons;
}
function AddValueToDropdown(oDropdown, text, value, optionnumber){
var options = oDropdown.options;
var option = document.createElement('OPTION');
option.appendChild(document.createTextNode(text));
option.setAttribute('value',value);
if (typeof(optionnumber) == 'number' && options[optionnumber]) {
oDropdown.insertBefore(option,options[optionnumber]);
}
else {
oDropdown.appendChild(option);
}
oDropdown.options.selectedIndex = 0;
}
function WrapClickEvent(element, newFunction) {
var clickFunc = element.onclick;
element.onclick = function(event){
if (newFunction()) {
clickFunc();
}
};
}
function MyCustomExecuteFunction() {
// **** ADD YOUR REQUIRED SINGLE SELECT FIELDS HERE ***
var dropdownNames = [
'Large Lookup Field',
'My Dropdown Field'
];
var dropdownElements = [];
for (var d = 0; d < dropdownNames.length; d++) {
// find the dropdown
var dropdown = GetDropdownByTitle(dropdownNames[d]);
// comment this IF block out if you don't want an error displayed
// when the dropdown can't be found
if (null === dropdown) {
alert('Unable to get dropdown named ' + dropdownNames[d]);
continue;
}
AddValueToDropdown(dropdown, '', '', 0);
// collect all of our dropdowns
dropdownElements.push(dropdown);
}
// add a custom validate function to the page
var funcValidate = function() {
var isValid = true;
var message = "";
for (var d = 0; d < dropdownElements.length; d++) {
if (0 === dropdownElements[d].selectedIndex) {
// require a selection other than the first item (our blank value)
if (isValid) {
isValid = false;
} else {
message += "\n"; // already had one error so we need another line
}
message += "Please choose a value for " + dropdownNames[d] + ".";
}
}
if (!isValid) {
alert(message);
}
return isValid;
};
var okButtons = GetOKButtons();
for (var b = 0; b < okButtons.length; b++) {
WrapClickEvent(okButtons[b], funcValidate);
}
}
_spBodyOnLoadFunctionNames.push("MyCustomExecuteFunction");
</script>
How about prepending a null option to the select menu of sharepoint.Like,
$('#idOfSelectMenu').prepend('<option value="" selected>(None)</option>');
I used this approach and append this code only in the NewForm.aspx because in EditForm.aspx it will override the selected option.