Implementation of Maker checker policy using User Event and client scripts

User event script:

/**

 * @NApiVersion 2.1

 * @NScriptType UserEventScript

 */

define([‘N/currentRecord’, ‘N/record’, ‘N/search’, ‘N/runtime’, ‘N/ui/serverWidget’],

    /**

 * @param{currentRecord} currentRecord

 * @param{record} record

 * @param{search} search

 * @param{runtime} runtime

 */

    (currentRecord, record, search, runtime, serverWidget) => {

        /**

         * Defines the function definition that is executed before record is loaded.

         * @param {Object} scriptContext

         * @param {Record} scriptContext.newRecord – New record

         * @param {string} scriptContext.type – Trigger type; use values from the context.UserEventType enum

         * @param {form1} scriptContext.form – Current form

         * @param {ServletRequest} scriptContext.request – HTTP request information sent from the browser for a client action only.

         * @since 2015.2

         */

        const beforeLoad = (scriptContext) => {

            try {

                let form1 = scriptContext.form;

                form1.clientScriptFileId = 4;

                let currentRecordObj = scriptContext.newRecord;

                let currentUser = runtime.getCurrentUser();

                let userId = currentUser.id;

                let userRole = currentUser.role;

                let creatorId = currentRecordObj.getValue({

                    fieldId: ‘custentity_jj_created_user’

                });

                let creatorRole = currentRecordObj.getValue({

                    fieldId: ‘custentity_jj_user_role’

                });

                let approvalStatus = currentRecordObj.getValue({

                    fieldId: ‘custentity_jj_approvalstatus’

                });

                let isinactiveField = form1.getField({

                    id: ‘isinactive’

                });

                isinactiveField.updateDisplayType({

                    displayType: serverWidget.FieldDisplayType.DISABLED

                });

                if (userId == creatorId && scriptContext.type === ‘view’) {

                    form1.addButton({

                        id: ‘custpage_bn_submit for approval’,

                        label: ‘SUBMIT FOR APPROVAL ‘,

                        functionName: `submitApprove(‘${creatorId}‘,’${creatorRole}‘,’${approvalStatus}‘)`

                    });

                }

                if (approvalStatus == 3 || approvalStatus == 2) {

                    if (userId == creatorId) {

                        form1.removeButton(‘custpage_bn_submit for approval’);

                    }

                }

                if (userRole == creatorRole && userId != creatorId) {

                    if (scriptContext.type === ‘view’) {

                        form1.addButton({

                            id: ‘custpage_bn_approve’,

                            label: ‘APPROVE ‘,

                            functionName: ‘onButtonClick()’

                        });

                        form1.addButton({

                            id: ‘custpage_bn_reject’,

                            label: ‘REJECT’,

                            functionName: `onRejectButtonClick(‘${creatorId}‘)`

                        });

                        form1.addButton({

                            id: ‘custpage_bn_resubmit’,

                            label: ‘REJECT AND RESUBMIT ‘,

                            functionName: `onResubmitButtonClick(‘${creatorId}‘)`

                        });

                    }

                }

            }

            catch (error) {

                log.error(‘Error in Before load:’, error);

            }

        }

        /**

         * Defines the function definition that is executed before record is submitted.

         * @param {Object} scriptContext

         * @param {Record} scriptContext.newRecord – New record

         * @param {Record} scriptContext.oldRecord – Old record

         * @param {string} scriptContext.type – Trigger type; use values from the context.UserEventType enum

         * @since 2015.2

         */

        const beforeSubmit = (scriptContext) => {

            try {

                let currentUser = runtime.getCurrentUser();

                let userId = currentUser.id;

                let userRole = currentUser.role;

                let currentRecord = scriptContext.newRecord;

                if (scriptContext.type === ‘create’) {

                    currentRecord.setValue({

                        fieldId: ‘custentity_jj_created_user’,

                        value: userId

                    });

                    currentRecord.setValue({

                        fieldId: ‘custentity_jj_user_role’,

                        value: userRole

                    });

                    currentRecord.setValue({

                        fieldId: “isinactive”,

                        value: true,

                    });

                }

            }

            catch (error) {

                log.error(‘Error in Before submit:’, error);

            }

        }

        /**

         * Defines the function definition that is executed after record is submitted.

         * @param {Object} scriptContext

         * @param {Record} scriptContext.newRecord – New record

         * @param {Record} scriptContext.oldRecord – Old record

         * @param {string} scriptContext.type – Trigger type; use values from the context.UserEventType enum

         * @since 2015.2

         */

        const afterSubmit = (scriptContext) => {

        }

        return { beforeLoad, beforeSubmit, afterSubmit }

    });

client script :

/**

 * @NApiVersion 2.1

 * @NScriptType ClientScript

 * @NModuleScope SameAccount

 */

define([‘N/currentRecord’, ‘N/record’, ‘N/search’, ‘N/email’],

    /**

     * @param{currentRecord} currentRecord

     * @param{record} record

     */

    function (currentRecord, record, search, email) {

        /**

         * Function to be executed after page is initialized.

         *

         * @param {Object} scriptContext

         * @param {Record} scriptContext.currentRecord – Current form record

         * @param {string} scriptContext.mode – The mode in which the record is being accessed (create, copy, or edit)

         *

         * @since 2015.2

         */

        function pageInit(scriptContext) {

        }

        /**

        * Function to fetch employee details based on user role and excluding given user ID.

        * @param {number} userId – ID of the user to exclude from search.

        * @param {string} userRole – Role of the user to filter employee search.

        * @returns {Array} – Array of objects containing employee details (internalId and name).

        */

        function getEmployee(userId, userRole) {

            try {

                let employeeSearchObj = search.create({

                    type: “employee”,

                    filters:

                        [

                            [“role”, “anyof”, userRole],

                            “AND”,

                            [“internalid”, “noneof”, userId]

                        ],

                    columns:

                        [

                            search.createColumn({ name: “entityid”, label: “Name” }),

                            search.createColumn({ name: “internalid”, label: “Internal ID” }),

                        ]

                });

                let searchResultCount = employeeSearchObj.runPaged().count;

                if (searchResultCount <= 0) return false;

                let employeeDetailsArray = [];

                employeeSearchObj.run().each(function (result) {

                    let employeeObj = {};

                    employeeObj.internalId = result.getValue({

                        name: “internalid”,

                        label: “Internal ID”,

                    });

                    employeeObj.name = result.getValue({ name: “entityid”, label: “Name” });

                    employeeDetailsArray.push(employeeObj);

                    return true;

                });

                log.debug(“employee details”, employeeDetailsArray);

                return employeeDetailsArray;

            }

            catch (e) {

                log.debug(‘Error@EmployeeSearch’, e)

                return [];

            }

        }

        /**

       * Function to fetch record details and generate link based on record type.

       * @param {number} recid – ID of the record to fetch details.

       * @returns {Array} – Array of objects containing link and record type.

       */

        function recordSearch(recid) {

            try {

                let entityType;

                let entitySearchObj = search.create({

                    type: “entity”,

                    filters: [

                        [“internalid”, “anyof”, recid]

                    ],

                    columns: [

                        search.createColumn({

                            name: “formulatext”,

                            formula: “CASE WHEN {type} = ‘Customer’ THEN (‘https://8314533-rp.app.netsuite.com/app/common/entity/custjob.nl?id=’||{internalid}) WHEN {type} = ‘Vendor’ THEN (‘https://8314533-rp.app.netsuite.com/app/common/entity/vendor.nl?id=’||{internalid}) ELSE ‘Invalid Record Type’ END”,

                            label: “Link to Entity”

                        }),

                        search.createColumn({ name: “type”, label: “Primary Type (Deprecated)” })

                    ]

                });

                let searchResult = entitySearchObj.run().getRange({

                    start: 0,

                    end: 1

                });

                if (!searchResult || searchResult.length === 0) return false;

                let recordlinkArray = [];

                searchResult.forEach(function (result) {

                    let link = result.getValue({

                        name: “formulatext”,

                        label: “Link”

                    });

                    let eType = result.getValue({

                        name: “type”,

                        label: “Primary Type (Deprecated)”

                    });

                    if (eType === “CustJob”) {

                        entityType = “customer”

                        recordlinkArray.push({ link: link, entityType: entityType })

                    }

                    else {

                        entityType = result.getValue({

                            name: “type”,

                            label: “Primary Type (Deprecated)”

                        });

                        recordlinkArray.push({ link: link, entityType: entityType })

                    }

                });

                //log.debug(“recarray”, recordlinkArray);

                return recordlinkArray;

            } catch (e) {

                log.debug(‘Error@record Search’, e)

                return [];

            }

        }

        /**

        * Function to submit approval status and notify users accordingly.

        * @param {number} creatorId – ID of the creator.

        * @param {string} creatorRole – Role of the creator.

        * @param {number} approvalStatus – Approval status (1 for approve, 5 for resubmit).

        */

        function submitApprove(creatorId, creatorRole, approvalStatus) {

            try {

                let currentRecordObj = currentRecord.get();

                let recid = currentRecordObj.id;

                let recResult = recordSearch(recid);

                let reclink = recResult[0].link;

                let recType = recResult[0].entityType;

                let employeeResult = getEmployee(creatorId, creatorRole);

                if (employeeResult && reclink && approvalStatus == 1) {

                    for (let j = 0; j < employeeResult.length + 1; j++) {

                        if (employeeResult[j]) {

                            let emailContent = “Dear “ +

                                employeeResult[j].name + “,<br/><br/>” + “A New Record has been created with inactive status. Approve the Record to come to active status.” + “<br>”

                                + ‘<br>Please click “Approve Record” to navigate to the Record page.</p><a href=”‘ + reclink + ‘” style=”display: inline-block; padding: 10px 10px; background-color:#39e600; color:#FFFFFF;  border-radius: 10px; text-align: center; text-decoration: none; font-size: 14px; cursor: pointer;”>Approve Record</a><p>Thank you</p>’

                            email.send({

                                author: 11,

                                recipients: 11, // Assuming you have valid recipient IDs here

                                subject: ‘New Record has been created’,

                                body: emailContent,

                            });

                        }

                    }

                }

                if (!approvalStatus || approvalStatus == 1) {

                    record.submitFields({

                        type: recType,

                        id: recid,

                        values: {

                            custentity_jj_approvalstatus: 1

                        },

                        options: {

                            ignoreMandatoryFields: true

                        }

                    });

                    window.location.reload();

                } else {

                    record.submitFields({

                        type: recType,

                        id: recid,

                        values: {

                            custentity_jj_approvalstatus: 5 // Or the appropriate status code for rejection

                        },

                        options: {

                            ignoreMandatoryFields: true

                        }

                    });

                    window.location.reload();

                    if (approvalStatus == 5) {

                       

                        for (let j = 0; j < employeeResult.length + 1; j++) {

                            if (employeeResult[j]) {

                                let emailContent = “Dear “ +

                                    employeeResult[j].name + “,<br/><br/>” + “Record has been resubmitted for approval.” + “<br>”

                                    + ‘<br>Please review the record by clicking the below button.</p>’ + “<br/><br/>” + ‘<a href=”‘ + reclink + ‘” style=”display: inline-block; padding: 10px 10px; background-color:#39e600; color:#FFFFFF;  border-radius: 10px; text-align: center; text-decoration: none; font-size: 14px; cursor: pointer;”>Resubmitted Record</a>’ + “<br/><br/>” + ‘Thank you.’;

                                email.send({

                                    author: 11,

                                    recipients: 11, // Assuming you have valid recipient IDs here

                                    subject: ‘ Record has been Resubmitted for the Approval’,

                                    body: emailContent,

                                });

                            }

                        }

                    }

                }

            }

            catch (error) {

                log.error(‘Error in submitApprove function:’, error);

            }

        }

        /**

        * Function to handle button click event.

        */

        function onButtonClick() {

            try {

                let currentRecordObj = currentRecord.get();

                let recid = currentRecordObj.id;

                let recResult = recordSearch(recid);

                let recType = recResult[0].entityType;

                record.submitFields({

                    type: recType,

                    id: recid,

                    values: {

                        custentity_jj_approvalstatus: 2,

                        isinactive: false

                    },

                    options: {

                        ignoreMandatoryFields: true

                    }

                });

                window.location.reload();

            }

            catch (error) {

                log.error(‘Error in onButton click function:’, error);

            }

        }

        /**

        * Function to handle button click event.

        */

        function onRejectButtonClick(creatorId) {

            try {

                let currentRecordObj = currentRecord.get();

                let recid = currentRecordObj.id;

                let recResult = recordSearch(recid);

                let reclink = recResult[0].link;

                let recType = recResult[0].entityType;

                let employeeLookup = search.lookupFields({

                    type: search.Type.EMPLOYEE,

                    id: creatorId,

                    columns: ‘entityid’

                });

                let employeeName = employeeLookup.entityid;

                if (creatorId) {

                    let emailContent = “Dear “ +

                        employeeName + “,<br/><br/>” + “Record has been Rejected by the Approver.” + “<br>”

                        + ‘<br>Please check the record by clicking the below button.</p>’ + “<br/><br/>” + ‘<a href=”‘ + reclink + ‘” style=”display: inline-block; padding: 10px 10px; background-color:#39e600; color:#FFFFFF;  border-radius: 10px; text-align: center; text-decoration: none; font-size: 14px; cursor: pointer;”>Rejected Record</a>’ + “<br/><br/>” + ‘Thank you.’

                    email.send({

                        author: 11,

                        recipients: 11,

                        subject: recType + ‘ Record has been Rejected’,

                        body: emailContent,

                    });

                }

                record.submitFields({

                    type: recType,

                    id: recid,

                    values: {

                        custentity_jj_approvalstatus: 3,

                        isinactive: true

                    },

                    options: {

                        ignoreMandatoryFields: true

                    }

                });

                window.location.reload();

            }

            catch (error) {

                log.error(‘Error while updating approval status:’, error);

            }

        }

        /**

        * Function to handle button click event for rejecting a record.

        * @param {number} creatorId – ID of the creator.

         */

        function onResubmitButtonClick(creatorId) {

            try {

                let currentRecordObj = currentRecord.get();

                let recid = currentRecordObj.id;

                let recResult = recordSearch(recid);

                let reclink = recResult[0].link;

                let recType = recResult[0].entityType;

                let employeeLookup = search.lookupFields({

                    type: search.Type.EMPLOYEE,

                    id: creatorId,

                    columns: ‘entityid’

                });

                let employeeName = employeeLookup.entityid;

                if (creatorId) {

                    let emailContent = “Dear “ +

                        employeeName + “,<br/><br/>” + “Record  has been rejected for resubmited by the Approver.” + “<br>”

                        + ‘<br>Please check the record by clicking the below button and submit again for approval.</p>’ + “<br/><br/>” + ‘<a href=”‘ + reclink + ‘” style=”display: inline-block; padding: 10px 10px; background-color:#39e600; color:#FFFFFF;  border-radius: 10px; text-align: center; text-decoration: none; font-size: 14px; cursor: pointer;”>Rejected Record</a>’ + “<br/><br/>” + ‘Thank you.’

                    email.send({

                        author: 11,

                        recipients: 11,

                        subject: ‘ Record has been Rejected for Resubmit’,

                        body: emailContent,

                    });

                } record.submitFields({

                    type: recType,

                    id: recid,

                    values: {

                        custentity_jj_approvalstatus: 4,

                        isinactive: true

                    },

                    options: {

                        ignoreMandatoryFields: true

                    }

                });

                window.location.reload();

            }

            catch (e) {

                log.error(‘Error while updating approval status:’, e);

            }

        }

        return {

            pageInit: pageInit,

            onButtonClick: onButtonClick,

            submitApprove: submitApprove,

            onRejectButtonClick: onRejectButtonClick,

            onResubmitButtonClick: onResubmitButtonClick,

        };

    });

Leave a comment

Your email address will not be published. Required fields are marked *