Control budgeted hours for a project using the project budget feature and a custom hours field

This script controls the budgeted hours for a project using the project budget feature and a custom hours field.

Note:

Requires "Project budgets" feature enabled.

Follow the steps below or download the solutions file, see Creating Solutions for details.

Setup

  1. Create a new Budget form script deployment.

  2. Enter a Filename and click SAVE. The extension ‘.js’ is automatically appended if not supplied.

  3. Click on the script link to launch the Scripting Studio.

  4. (1) Copy the Program Listing below into the editor, (2) set the After save event, and set updateProjectBudgetHours as the Entrance Function.

    Scripting Studio tools and settings panel showing the form association, the user event association and the selected entrance function.
  5. Set up an Hours custom field for Project and an Hours custom field for Budget.

    Custom field list view showing the Budget hours and Project budget hours custom fields.

Program Listing

          function updateProjectBudgetHours(type) {
    try {
        // DEBUG: Uncomment next line to enable XML logging
        // var wsLog = NSOA.wsapi.enableLog(true);
        // list all fields used in script
        var FLD_PRJ_ID = 'id',
            FLD_PRJ_BUD_HRS = 'prj_budget_time__c',
            FLD_BUD_PID = 'projectid';

        // store newly saved budget record
        var updBudget = NSOA.form.getNewRecord();

        // create new budget object to store information
        var budRec = new NSOA.record.oaBudget();
        budRec.projectid = updBudget.projectid;
        var budRequest = {
            type: "Budget",
            method: "equal to",
            fields: "id,budget_hours__c", // budget_hours__c is a custom hours field
            attributes: [{
                name: "limit",
                value: "100"
            }],
            objects: [budRec]
        };

        // disable the current user's filter set while script runs
        NSOA.wsapi.disableFilterSet(true);

        // search for all budget transactions with current projectid
        var budResults = NSOA.wsapi.read(budRequest);
        if (!budResults || !budResults[0]) {
            NSOA.meta.log('error', 'Unexpected error! Could not return project budgets.');
            return;
        } else if (budResults[0].errors !== null && budResults[0].errors.length > 0) {
            prjResults[0].errors.forEach(function(err) {
                var fullError = err.code + ' - ' + err.comment + ' ' + err.text;
                NSOA.meta.log('error', 'Error: ' + fullError);
            });
            return;
        }
        var b,
            totalBudHrs = 0,
            budObj = budResults[0].objects,
            budObjLen = budObj.length;
        for (b = 0; b < budObjLen; b++) {
            var budHrs = parseInt(budObj[b].budget_hours__c, 10);
            totalBudHrs += budHrs; // add all hours together
        }
        // create new project object to store information
        var prjRec = new NSOA.record.oaProject();
        prjRec[FLD_PRJ_ID] = updBudget[FLD_BUD_PID];
        prjRec[FLD_PRJ_BUD_HRS] = totalBudHrs;

        // disable the current user's filter set while script runs
        NSOA.wsapi.disableFilterSet(true);

        // update the project budget
        var prjResults = NSOA.wsapi.modify(
            [{
                name: "update_custom",
                value: "1"
            }], [prjRec]
        );
        if (!prjResults || !prjResults[0]) {
            NSOA.meta.log('error', 'Unexpected error! Project was not updated.');
        } else if (prjResults[0].errors !== null && prjResults[0].errors.length > 0) {
            prjResults[0].errors.forEach(function(err) {
                var fullError = err.code + ' - ' + err.comment + ' ' + err.text;
                NSOA.meta.log('error', 'Error: ' + fullError);
            });
            return;
        }

    } catch (e) {
        NSOA.meta.log('error', 'Try/catch error: ' + e);
    }
}