I'm looking to try and see if there is a way to enable a Non-G/L "check box" custom field to be able to be checked or unchecked from the 'View' status of a G/L Posting Transaction (Item Receipt or Assembly Build, etc.). The purpose of the field is to be able to be used for audit error tracking and would like to see if it can be edited in such a way, and then by such logic, allow for those fields to be edited on Closed periods where "Allow Non-G/L Changes" has been checked on.
Can't seem to find any such options on the "Custom Record" field or the "Custom Transaction Form", so wondering if anyone knows if there's a specific permission or option that needs to be set aside from the "Allow Non-G/L Changes". Thanks!
Example Transaction Check Box Fields
TLDR: Allow Non-G/L Changes is enabled in the closed period of my transaction; however, since I am unable to "edit" this transaction, I cannot check the non-G/L impacting custom field Checkbox that is on those transactions, and need to figure out if there is a way to edit fields without being in "edit mode".
If I understand your problem correctly, you want to (from view context) be able to update the values of those 3 checkboxes. Correct?
There might be a better way to do this, but you can add buttons to the record using a UserEvent script that call a ClientScript similar to this.
/**
* #NApiVersion 2.x
* #NScriptType UserEventScript
*/
define([], function () {
function beforeLoad(context) {
// make sure not to add the button in create or edit context
if (context.type !== context.UserEventType.VIEW) return;
context.form.clientScriptModulePath = "SuiteScripts/Path/To/Your/Script.js";
context.form.addButton({
id: "custpage_button",
label: "My Label",
functionName: "checkBox.call(this)",
});
}
return {beforeLoad: beforeLoad};
});
/**
* #NApiVersion 2.x
* #NScriptType ClientScript
*/
define(["N/currentRecord", "N/record"], function (currentRecord, record) {
// this function should be named whatever you are defining in your user event script as the "functionName" when adding the button
function checkBox() {
var curr = currentRecord.get();
// check the checkbox
record.submitFields({
id: curr.id,
type: curr.type,
columns: {
custbody_mycheckbox: "T",
},
});
// reload the page to present the most up to date information
window.location.reload();
}
return {
pageInit: function () {},
checkBox: checkBox,
}
});
Related
I created a super basic user event script for Sales Order records, shown below. I enabled every execution context and have not set an Event Type filter.
The script executes as expected for events involving the Sales Order record itself, but it does not fire when a modification is made directly to a line item on the Sales Order record. For example, if inventory is committed or reallocated, these actions do not trigger the script.
Are sublist modifications not candidates for user event scripts?
/**
*#NApiVersion 2.x
*#NScriptType UserEventScript
*/
define(["N/record", "N/log"],
function (record, log) {
function beforeSubmit(context) {
log.debug("beforeSubmit:" + context.type);
}
function afterSubmit(context) {
log.debug("afterSubmit:" + context.type);
}
function beforeLoad(context) {
log.debug("beforeLoad:" + context.type);
}
return {
beforeLoad: beforeLoad,
beforeSubmit: beforeSubmit,
afterSubmit: afterSubmit
};
});
User Events are not triggered by changes to records related to the scripted record (e.g. another Transaction, an Item, a Customer, Inventory, etc). A change in Inventory is not a change to the Sales Order, thus it won't trigger Sales Order User Events.
If you want to monitor inventory movements in real-time, you'll need User Events on the records/transactions which cause the movement.
How can i hide a standard dashlet named "Product Catalog" from the list which gets displayed in the drawer named "Add a Sugar Dashlet". "Add a Sugar Dashlet" drawer gets displayed when user tries to add a dashlet in any dashbaord in Sugarcrm. Hiding should be done in an upgrade safe way.
Note: I am using Sugarcrm Ver 8.0.0 PRO
One way to accomplish this is by creating a custom override of the DashletselectView where you filter out the Dashlet in question.
The code below does so by overriding an internal function of the view, post-processing its results.
custom/clients/base/views/dashletselect/dashletselect.js
({
extendsFrom: "DashletselectView",
_getDashlets: function() {
var dashlets = this._super("_getDashlets", arguments);
return _.filter(dashlets, function (d) { return d.type !== "product-catalog-dashlet"; });
},
})
Then run Quick Repair & Rebuild so that Sugar detects the presence of the custom file and loads it.
I am trying to use the deleteConfimation function option but I find that the default confirmation box pops up before I even get into the deleteConfimation function - what am I missing?
In the code below I can set break points and watch the data object being set up correctly with its new defaultConfirmMessage, but the basic jtable default delete confirmation box has already appeared and I never see an altered one.
$(container).jtable({
title: tablename,
paging: true,
pageSize: 100,
sorting: true,
defaultSorting: sortvar + ' ASC',
selecting: false,
deleteConfirmation: function(data) {
var defaultMessage = 'This record will be deleted - along with all its assignments!<br>Are you sure?';
if(data.record.Item) { // deleting an item
// Check whether item is in any preset lists
var url = 'CampingTablesData.php?action=CheckPresets&Table=items';
$.when(
ReturnAjax(url, {'ID':data.record.ID}, MyError)
).done(
function(retdata, status) {
if(status=='success') {
if(retdata.PresetList) {
data.deleteConfirmMessage = 'Item is in the following lists: ' + retdata.PresetList + 'Do you still want to delete it?';
}
} else {
data.cancel = true;
data.cancelMessage = retdata.Message;
}
}
);
} else {
data.deleteConfirmMessage = defaultMessage;
}
},
messages: {
addNewRecord: 'Add new',
deleteText: deleteTxt
},
actions: {
listAction: function(postData, jtParams) {
<list action code>
},
createAction: function(postData) {
<create action code>
},
updateAction: 'CampingTablesData.php?action=update&Table=' + tablename,
deleteAction: 'CampingTablesData.php?action=delete&Table=' + tablename
},
fields: tableFields --- preset variable
});
==========
After further testing the problem is only when deleting an item and it goes through the $.when().done() section of code. The Ajax call to the deletion url does not wait for this to complete - how do I overcome this?
i don't think you can get your design to work. What does the A in ajax stand for? Asynchronous! Synchronous Ajax has been deprecated for all sorts of good design and performance reasons.
You need to design you application to function asynchronously. Looking at your code, it feels you are misusing the deleteConfirmation event.
Consider changing the default deleteConfirmation message to inform the user, that the delete might not succeed if certain condition are met. Say
messages: {
deleteConfirmation: "This record will be deleted - along with all its assignments, unless in a preset list. Do you wish to try to delete this record?"
},
Then on the server, check the preset lists, and if not deletable, return an error message for jTable to display.
Depending on how dynamic your preset lists are, another approach might be to let the list function return an additional flag or code indicating which, if any, preset lists the item is already in, then your confirmation function can check this flag / indicator without further access to the server.
Thanks to MisterP for his observation and suggestions. I also considered his last approach but ended up setting deleteConfirmation to false (so as not to generate a system prompt) then writing a delete function that did not actually delete, but returned the information I needed to construct my own deleteConfimation message. Then a simple if confirm(myMessage) go ahead and delete with another Ajax call.
I am using nodejs SDK for creating my bot with MSFT botframework.
The code snippet is as follows:
function(session, args, next){
builder.Prompts.choice(session, "Please select one of the options:", ['AAA', 'BBB','CCC'], {retryPrompt: "Invalid choice, Please pick below listed choices",
listStyle: builder.ListStyle.button,
maxRetries: 1
});
},
function(session,results){
if (results.response) {
//Do something
}
}
I have 2 questions:
I would like to navigate to a different dialog Flow in case the user types anything other then the options("AAA","BBB","CCC"). Is that possible?
I would like to change the retryPrompt everytime lets say pick the utterances from a list. Is that possible?
I would like to navigate to a different dialog Flow in case the user types anything other then the options("AAA","BBB","CCC"). Is that possible?
Yes, it's possible. You can define several dialogs with required waterfall steps related to the choices. Like:
bot.dialog('AAA',[...])
And leverage replaceDialog to redirect your user to new dialog flows:
(session,result)=>{
//result.response.entity should be one of string `AAA`,`BBB`,`CCC`
session.replaceDialog(result.response.entity);
}
I would like to change the retryPrompt everytime lets say pick the utterances from a list. Is that possible?
Yes, it's possible. According the choice definition, we can set options extends IPromptChoiceOptions which extends [IPromptOptions][2], we can find that retryPrompt?: TextOrMessageType;, dig into the source code for the definition of TextOrMessageType:
/**
* Flexible range of possible prompts that can be sent to a user.
* * _{string}_ - A simple message to send the user.
* * _{string[]}_ - Array of possible messages to send the user. One will be chosen at random.
...
...
*/
export type TextOrMessageType = string|string[]|IMessage|IIsMessage;
So we can set a string list for retryPrompt, bot builder will pick one randomly. Please try following:
builder.Prompts.choice(session, "Please select one of the options:", ['AAA', 'BBB', 'CCC'], {
listStyle: builder.ListStyle.button,
maxRetries: 1,
retryPrompt:['utterance 1','utterance 2','utterance 3','utterance 4']
});
As you can call a function in retryPrompt you can do both of them:
builder.Prompts.choice(
session,
'This is just a question?',
'Yes|No',
{ retryPrompt: particularRetry() }
);
In the above, you can do what you want in particularRetry function.
For example for the second question, you can call the new propmt with new choices.
You can see more details in this post.
This code work great for creating the employee, but the password and giveAccess fields are not set:
function CreateEmployee() {
nlapiLogExecution('DEBUG','running create employee',1);
var employeeRec = nlapiCreateRecord('employee');
employeeRec.setFieldValue('lastname', 'Aloe');
employeeRec.setFieldValue('firstname', 'Danny');
employeeRec.setFieldValue('email', 'test9475#test232.org');
employeeRec.setFieldValue('subsidiary', 3);
employeeRec.setFieldValue('giveAccess', true);
employeeRec.setFieldValue('role', 3);
employeeRec.setFieldValue('password', 'Somepassword1!');
employeeRec.setFieldValue('password2', 'Somepassword1!');
var id = nlapiSubmitRecord(employeeRec);
nlapiLogExecution('DEBUG','done: ' + id + ' employee',id);
var result = new Object();
result.id = id;
return result;
}
When I go to the web interface and pull up the employee record, the "Access" tab does not have the giveAccess checkbox checked. And trying to login as the new user does not work. Is there a trick other than employeeRec.setFieldValue to set these values?
Not sure if you ever found the answer or not... I know this is an old post.
I was able to update the user roles programmatically Below is the Mass Update Script I'm using. It can show you how to add a role to a user with SuiteScript.
function massUpdate(recType,recID){
var roleID=1234;
var empRec=nlapiLoadRecord(recType,recID);
var roleCount=empRec.getLineItemCount('roles');
var thiRole=empRec.setLineItemValue('roles','selectedrole',roleCount+1,roleID);
var submitRec=nlapiSubmitRecord(empRec);
}
The issue you had was that you were setting a field value, instead of a sublist field value. Hope that helps.
Checking the box by itself, whether through the UI or scripting, isn't enough to grant access. You also need to specify a role for the user to use.
First glance through the scriptable records browser, it doesn't seem that roles are scriptable except as search filters and search columns.
https://system.netsuite.com/help/helpcenter/en_US/RecordsBrowser/2013_2/Records/employee.html
Here is a working example in suitescrpit 2.0 to add a role on an employee.
/**
* #NApiVersion 2.x
* #NScriptType UserEventScript
* #NModuleScope SameAccount
*/
define(['N/record'],
/**
* #param {record} record
*/
function(record) {
function beforeSubmit(scriptContext) {
log.debug('in the script');
scriptContext.newRecord.setSublistValue({
sublistId: 'roles',//'jobresources
fieldId: 'selectedrole',//'jobresource',
line: 3,
value: 4
});
}
return {
beforeSubmit: beforeSubmit,
};
});