Delegation Expiration- Scheduled Processing

Scenario

Once the delegation period is over we will set the status of the delegation record as Complted. Real time status updation is not considerd. That is the status is changed to Completed with the help of a scheduled script. This will chek if any delegation end date on yesterday and get the records, then empty the time approver field of the suboridates empty. And set the status as completed.  

And also it will check that if any of his subordinates has an active delegation record. Then Update these delegate To values with his supervisor value. Then the subordinates time approver field is also updated with the new delegate to person value. The we will send  a notification to the old delegating person as his delegation period is expired for the particular employee and a delegation request email to the new delegate person.  

Once the delegation is completed set the check box “Unable to approve” as unchecked. 

Solution

/**
 * @NApiVersion 2.1
 * @NScriptType MapReduceScript
 */

/***********************************************************************************************
 * CLIENT NAME : International Planned Parenthood Federation
 * IPPF-1342 Employee Delegation Approval (V2)
 * IPPF-1399 Employee Delegation V3
 * *********************************************************************************************
 * Date : 22-05-2023
 *
 * Author: Jobin & Jismi IT Services LLP
 * Script Description : The map reduce script is used to check if any delegation is expired
 * Created by: Aswathy Viswanathan, Jobin & Jismi IT Services LLP
 * REVISION HISTORY
 * Revision 1.0 ${22-05-2023} :Employee Delegation Approval
 * Revised by : Aswathy Viswanathan, Jobin & Jismi IT Services LLP

 ***************************************************************************************************/
define(['N/record', 'N/search','N/email','N/format'],
    /**
 * @param{record} record
 * @param{search} search
 * @param{search} email
 * @param{search} format
 */
    (record, search,email,format) => {

        /**
         * Function to get all the delegation records whose delegation end date is on yesterday
         * @returns {boolean|*[]}
         */

        function checkEmpDelegateExpirySearch()
        {
            try
            {
                let customrecord_jj_emp_delgSearchObj = search.create({
                    type: "customrecord_jj_emp_delg",
                    filters:
                        [
                            ["custrecord_jj_delg_end","on","yesterday"],
                            "AND", 
                            ["isinactive","is","F"], 
                            "AND", 
                            ["custrecord_jj_delegation_status","noneof","3"],

                        ],
                    columns:
                        [
                            search.createColumn({name: "internalid", label: "Internal ID"}),
                            search.createColumn({name: "custrecord_jj_empname_delg", label: "Employee Name"}),
                            search.createColumn({name: "custrecord_jj_delegateto_delg", label: "Delegate To"}),
                            search.createColumn({name: "custrecord_jj_div_head", label: "Division Head"}),
                        ]
                });
                let searchResultCount = customrecord_jj_emp_delgSearchObj.runPaged().count;
                let employee =[]
                if(searchResultCount > 0)
                {
                    customrecord_jj_emp_delgSearchObj.run().each(function(result){

                        let obj={}
                        obj.internalID = result.getValue({
                           name: "internalid", label: "Internal ID"
                       });
                        obj.employeeID = result.getValue({
                            name: "custrecord_jj_empname_delg", label: "Employee Name"
                        });
                        obj.divHead = result.getValue({
                            name: "custrecord_jj_div_head", label: "Division Head"
                        });

                        employee.push(obj);
                        return true;
                    });

                    return employee;
                  //  return customrecord_jj_emp_delgSearchObj ;

                }
                else
                {
                    return false
                }
            }
            catch(err)
            {
                log.debug("error@checkEmpDelegateExpirySearch",err)
            }
        }


        /**
         * Function to get the employee name
         * @param employee
         * @returns {boolean|*}
         */
                function empNameSearch(employee) {
                    try {
                        let employeeSearchObj = search.create({
                            type: "employee",
                            filters:
                                [
                                    ["internalid", "is", employee],
                                    "AND", 
                                    ["isinactive","is","F"], 
                                    "AND", 
                                    ["releasedate","isempty",""]
                                ],
                            columns:
                                [
                                    search.createColumn({name: "internalid", label: "Internal ID"}),
                                    search.createColumn({name: "altname", label: "Name"}),
        
        
                                ]
                        });
                        let searchResultCount = employeeSearchObj.runPaged().count;
                        let empName
                        if (searchResultCount > 0) {
                            employeeSearchObj.run().each(function (result) {
        
                                empName = result.getValue({
                                    name: "altname", label: "Name"
                                });
                                return true;
                            });
                            return empName;
                        } else {
                            return false
                        }
                    } catch (err) {
                        log.debug("error@empNameSearch", err)
                    }
                }


  /**
   * Function for check for parameter
   * @param {} parameter 
   * @returns{boolean}
   */

                const checkForParameter = function checkForParameter(parameter) {

                    if (parameter !== "" && parameter !== null && parameter !== undefined && parameter !== false && parameter !== "null" && parameter !== "undefined" && parameter !== " " && parameter !== 'false' && parameter !== 0 && parameter !== '0') {
                        return true;
                    }
        
                }


        /**
         * Function to get the subordinates of the current employee
         * @param employee
         * @returns {*[]}
         */

        function subordinateSearch(employeeArray) {
            try {
                let employeeSearchObj = search.create({
                    type: "employee",
                    filters:
                        [
                            ["supervisor", "is", employeeArray],
                            "AND", 
                            ["isinactive","is","F"],
                            "AND", 
                            ["releasedate","isempty",""]
                            // "AND",
                            // ["internalid","anyof","18679"]
                        ],
                    columns:
                        [
                            search.createColumn({name: "internalid", label: "Internal ID"}),
                            search.createColumn({name: "supervisor", label: "Supervisor"}),
                            search.createColumn({name: "timeapprover", label: "Time Approver"})
                        ]
                });
                let searchResultCount = employeeSearchObj.runPaged().count;
                log.debug("searchResultCount", searchResultCount)
                let subordinateArray = []
                if (searchResultCount > 0) {

                    employeeSearchObj.run().each(function (result) {
                        let subordinateObj = {};
                        subordinateObj.subId = result.getValue({
                            name: "internalid", label: "Internal ID"
                        })
                        subordinateObj.supervisor = result.getValue({
                            name: "supervisor", label: "Supervisor"
                        })
                        subordinateObj.timeApprover = result.getValue({
                            name: "timeapprover", label: "Time Approver"
                        })

                        subordinateArray.push(subordinateObj)

                        return true;
                    });

                    
                    return subordinateArray;
                } else {
                    return []
                }

            } catch (err) {
                log.debug("error@FunctionsubordinateSearch", err)
            }
        }



/**
 * Function to check the employee has an active delegation
 * @param {*} subordinateArray 
 * @returns {*[]}
 */
        function checkEmployeeHasActiveDelegation(subordinateArray)
        {
            try
            {
               let customrecord_jj_emp_delgSearchObj = search.create({
                    type: "customrecord_jj_emp_delg",
                    filters:
                        [
                            ["custrecord_jj_delegation_status","anyof","2"],
                            "AND",
                            ["custrecord_jj_empname_delg","anyof",subordinateArray],
                            "AND", 
                            ["isinactive","is","F"], 
                        ],
                    columns:
                        [
                            search.createColumn({
                                name: "name",
                                sort: search.Sort.ASC,
                                label: "ID"
                            }),
                            search.createColumn({name: "internalid", label: "Internal ID"}),
                            search.createColumn({name: "custrecord_jj_empname_delg", label: "Employee Name"}),
                            search.createColumn({name: "custrecord_jj_delegateto_delg", label: "Delegate To"}),
                            search.createColumn({name: "custrecord_jj_delg_start", label: "Delegation Start Date"}),
                            search.createColumn({name: "custrecord_jj_delg_end", label: "Delegation End Date"}),
                            search.createColumn({name: "custrecord_jj_emp_supervsr", label: "Employee Supervisor"}),
                            search.createColumn({name: "custrecord_jj_supervsr_email", label: "Supervisor Email"}),
                            search.createColumn({name: "custrecord_jj_delegate_email", label: "Delegation Email"})

                        ]
                });
              let searchResultCount = customrecord_jj_emp_delgSearchObj.runPaged().count;
              let activeEmpArray = []
                if(searchResultCount > 0)
                {
                    customrecord_jj_emp_delgSearchObj.run().each(function(result){
                        let activeEmpObj = {}
                        activeEmpObj.recordId = result.getValue({
                            name: "internalid", label: "Internal ID"
                        });
                        activeEmpObj.empName = result.getValue({
                            name: "custrecord_jj_empname_delg", label: "Employee Name"
                        });
                        activeEmpObj.empNameText = result.getText({
                            name: "custrecord_jj_empname_delg", label: "Employee Name"
                        });
                        activeEmpObj.supervisor = result.getValue({
                            name: "custrecord_jj_emp_supervsr", label: "Employee Supervisor"
                        });
                        activeEmpObj.supervisorText = result.getText({
                            name: "custrecord_jj_emp_supervsr", label: "Employee Supervisor"
                        });
                        activeEmpObj.supervisorEmail = result.getValue({
                            name: "custrecord_jj_supervsr_email", label: "Supervisor Email"
                        });
                        activeEmpObj.delegatedPerson = result.getValue({
                            name: "custrecord_jj_delegateto_delg", label: "Delegate To"
                        });
                        activeEmpObj.delegatedPersonText = result.getText({
                            name: "custrecord_jj_delegateto_delg", label: "Delegate To"
                        });
                        activeEmpObj.delegateEmail = result.getValue({
                            name: "custrecord_jj_delegate_email", label: "Delegation Email"
                        });
                       
                        activeEmpObj.deleEndDate = result.getValue({
                            name: "custrecord_jj_delg_end", label: "Delegation End Date"
                        });
                       
                        activeEmpArray.push(activeEmpObj);
                        return true;
                    });
                    return activeEmpArray;
                }
                else
                {
                    return []
                }

            }
            catch(err)
            {
                log.debug("error@checkEmployeeHasActiveDelegation",err)
            }
        }


        /**
         * Defines the function that is executed at the beginning of the map/reduce process and generates the input data.
         * @param {Object} inputContext
         * @param {boolean} inputContext.isRestarted - Indicates whether the current invocation of this function is the first
         *     invocation (if true, the current invocation is not the first invocation and this function has been restarted)
         * @param {Object} inputContext.ObjectRef - Object that references the input data
         * @typedef {Object} ObjectRef
         * @property {string|number} ObjectRef.id - Internal ID of the record instance that contains the input data
         * @property {string} ObjectRef.type - Type of the record instance that contains the input data
         * @returns {Array|Object|Search|ObjectRef|File|Query} The input data to use in the map/reduce process
         * @since 2015.2
         */

        const getInputData = (inputContext) => {

            try
            {

                let data = checkEmpDelegateExpirySearch();
                log.debug("data",data)
                return data;

            }
            catch(err)
            {
                log.debug("erro@getInputData",err)
            }

        }


        /**
         * Defines the function that is executed when the reduce entry point is triggered. This entry point is triggered
         * automatically when the associated map stage is complete. This function is applied to each group in the provided context.
         * @param {Object} reduceContext - Data collection containing the groups to process in the reduce stage. This parameter is
         *     provided automatically based on the results of the map stage.
         * @param {Iterator} reduceContext.errors - Serialized errors that were thrown during previous attempts to execute the
         *     reduce function on the current group
         * @param {number} reduceContext.executionNo - Number of times the reduce function has been executed on the current group
         * @param {boolean} reduceContext.isRestarted - Indicates whether the current invocation of this function is the first
         *     invocation (if true, the current invocation is not the first invocation and this function has been restarted)
         * @param {string} reduceContext.key - Key to be processed during the reduce stage
         * @param {List<String>} reduceContext.values - All values associated with a unique key that was passed to the reduce stage
         *     for processing
         * @since 2015.2
         */
        const reduce = (reduceContext) => {

            try
            {

                let dataObj = reduceContext.values.map(JSON.parse);
                let employee = dataObj[0].employeeID;
                let customrecordID = dataObj[0].internalID
                let currentDayDate = new Date()
                log.debug("currentDayDate",currentDayDate)
                let gmtDate = format.format({
                    value: currentDayDate,
                    type: format.Type.DATETIME,
                    timezone: format.Timezone.GMT
                });

                let finalCurrentDateArray = gmtDate.split(' ')
                let finalCurrentdate = finalCurrentDateArray[0]
               // let divHead = dataObj[0].divHead;
                
               record.submitFields({
                    type: 'customrecord_jj_emp_delg',
                    id: customrecordID,
                    values: {
                        'custrecord_jj_delegation_status': 3
                    },
                    options: {
                        enableSourcing: false,
                        ignoreMandatoryFields : true
                    }
                });

                record.submitFields({
                    type: record.Type.EMPLOYEE,
                    id: employee,
                    values: {
                        'custentity_unable_to_approve' : false
                        
                    },
                    options: {
                        enableSourcing: false,
                        ignoreMandatoryFields : true
                    }
                });

                if(checkForParameter(employee))
                {
                    let empText = empNameSearch(employee)
                    {
                        if(empText === false || empText == 'false')
                        {
                            return true;
                        }
                    }
                let employeeArray = [];
                employeeArray.push(employee);
                let subordiantes = subordinateSearch(employeeArray)
                log.debug("subordiantes",subordiantes);
                let subordinateArray = [];
                if(subordiantes.length > 0)
                {
                  
                  for( i = 0; i < subordiantes.length ; i++)
                  {
                    if(checkForParameter(subordiantes[i].subId))
                    {
                        subordinateArray.push(subordiantes[i].subId)

                         record.submitFields({
                            type: record.Type.EMPLOYEE,
                            id: subordiantes[i].subId,
                            values: {
                                'timeapprover' : "",
                                'custentity_stand_in_app' : employee
                            },
                            options: {
                                enableSourcing: false,
                                ignoreMandatoryFields : true
                            }
                        });

                    }
                  }

                }
                log.debug("subordinateArray",subordinateArray)
                
                if(subordinateArray.length > 0)
                {
                   let employeeActiveDelegation = checkEmployeeHasActiveDelegation(subordinateArray)
                    log.debug("employeeActiveDelegation",employeeActiveDelegation)
                    let newEmployeeArray = [];
                    if(employeeActiveDelegation.length > 0) 
                    {
                      for(let i = 0; i < employeeActiveDelegation.length; i++)
                      {
                        if(checkForParameter(employeeActiveDelegation[i].empName))
                        {
                            newEmployeeArray.push(employeeActiveDelegation[i].empName)
                        }
                        record.submitFields({
                            type: 'customrecord_jj_emp_delg',
                            id: employeeActiveDelegation[i].recordId,
                            values: {
                                'custrecord_jj_delegateto_delg': employee,
                                'custrecord_jj_delegate_email': employeeActiveDelegation[i].supervisorEmail,
                            },
                            options: {
                                enableSourcing: false,
                                ignoreMandatoryFields: true
                                }
                        });
                        let empNameCode = (employeeActiveDelegation[i].empNameText).substring(0, (employeeActiveDelegation[i].empNameText).indexOf(' '));
                        let empEmailNames = (employeeActiveDelegation[i].empNameText).split(empNameCode);                                   
                        let empEmailName = empEmailNames[1]
                        
                        let supervisorNameCode = (employeeActiveDelegation[i].supervisorText).substring(0, (employeeActiveDelegation[i].supervisorText).indexOf(' '));
                        let supervisorEmailNames = (employeeActiveDelegation[i].supervisorText).split(supervisorNameCode);                                   
                        let supervisorEmailName = supervisorEmailNames[1]
    
                        let emailContent = 'Hi ' + supervisorEmailName + ',' + '<br/>' + 'You have been delegated responsibility of ' + empEmailName + ' from ' + finalCurrentdate + ' to ' + employeeActiveDelegation[i].deleEndDate + '.' + '<br/>' + '<br/>' + 'Thank you!'
                       
                       
                        email.send({
                            author: employeeActiveDelegation[i].empName,
                            recipients: employeeActiveDelegation[i].supervisorEmail,
                            
                            subject: 'Delegation Request',
                            body: emailContent,
                            relatedRecords: {
                                entityId: employee,
                                customRecord: {
                                    id: employeeActiveDelegation[i].recordId,
                                    recordType: 530 //an integer value
                                }
                            }
                        });
    
    
    
                        let empCode = (employeeActiveDelegation[i].delegatedPersonText).substring(0, (employeeActiveDelegation[i].delegatedPersonText).indexOf(' '));
                        let emailNames = (employeeActiveDelegation[i].delegatedPersonText).split(empCode);                                   
                        let emailName = emailNames[1]
    
                        let emailBody = 'Hi ' + emailName + ',' + '<br/>' + 'Your delegation responsibility of ' + empEmailName + ' is expired. ' + '<br/>' + '<br/>' + 'Thank you!'       
                        log.debug("emailBody",emailBody)
                         email.send({
                            author:employeeActiveDelegation[i].empName,
                            recipients: employeeActiveDelegation[i].delegateEmail,
                            subject: 'Delegation Expiration Notification',
                            body: emailBody,
                            relatedRecords: {
                                entityId: employeeActiveDelegation[i].delegatedPerson,
                                customRecord: {
                                    id: employeeActiveDelegation[i].recordId,
                                    recordType: 530 //an integer value
                                }
                            }
                        });
    
        
                      }
                    
                    }
    
                   
                    
                    if(newEmployeeArray.length > 0)
                    {
                    let newEmployeeSubordinates = subordinateSearch(newEmployeeArray)
                    
                    if(newEmployeeSubordinates.length > 0)
                    {
                        for(let i = 0; i < newEmployeeSubordinates.length; i++)
                        {
                            for(let j = 0; j < employeeActiveDelegation.length ; j++)
                            {
                                if(newEmployeeSubordinates[i].supervisor === employeeActiveDelegation[j].empName){
                                
                                    record.submitFields({
                                        type: record.Type.EMPLOYEE,
                                         id:  newEmployeeSubordinates[i].subId,
                                         values: {
                                            timeapprover: employee
                                            
                                       },
                                         options: {
                                         enableSourcing: false,
                                         ignoreMandatoryFields: true
                                         }
                             
                                       });
    
                                }
                            }
                        }
                    }
                      
                    }
                   
                }
               
               
                

                }

            }
            catch(err)
            {
                log.debug("error@reduce",err)
            }

        }


        return {getInputData,reduce,}

    });

Leave a comment

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