xml OA:SuiteSolution - OpenAir风险标签

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了xml OA:SuiteSolution - OpenAir风险标签相关的知识,希望对你有一定的参考价值。

/* jshint shadow:true, curly:true, undef:true, quotmark:true, sub:true */
/* globals NSOA */

/**
 * @name SuiteSolution: Risk Tags
 * @copyright Oracle, Inc. 2017. All rights reserved.
 * @version 1.0
 *
 * Create HTML elements of type TAG. These are based on the Bootstrap
 * tag element which can be found here:
 * http://v4-alpha.getbootstrap.com/components/tag/
 *
 * This SuiteSolution requires the use of the extended category 1 feature.
 * Please talk to your NetSuite account manager or PS contact before
 * installing and using this solution.
 *
 * This SuiteSolution requires the use of field whitelisting to allow for
 * the injection of HTML tags into textarea fields. Please consult with your
 * local IT & Security personnel before installing and using this solution.
 * You will need to whitelist FLD.OVERALL, FLD.BUDGET and FLD.SCHEDULE to
 * allow for the injection of HTML content.
 *
 */


/**
 * The main runtime function.
 *
 * @param {string} type OpenAir form script event type (new | edit).
 */
function main(type) {
    // Custom fields used in this solution
    var FLD = {
        OVERALL: 'ss_iss_overall_risk__c',
        OVERALLCOLOR: 'ss_iss_overall_risk_tag__c',
        BUDGET: 'ss_iss_budget_risk__c',
        BUDGETCOLOR: 'ss_iss_budget_risk_tag__c',
        SCHEDULE: 'ss_iss_schedule_risk__c',
        SCHEDULECOLOR: 'ss_iss_schedule_risk_tag__c',
        FOREGROUND: 'ss_svcln_risk_foreground__c',
        BACKGROUND: 'ss_svcln_risk_background__c'
    };
    // Script parameters used in this solution
    var PARAM = {
        FILTER: 'ss_iss_item_type_filter'
    };

    /**
     * DO NOT CHANGE ANYTHING ABOVE THIS LINE BEFORE CONSULTING NETSUITE
     * TECHNICAL SERVICES, AS THEY ARE PRE-BUILT INTO THE SUITESOLUTION.
     */

    try {
        // Only run script for issue stages set as script parameter
        var ITEM_FILTER = parseInt(NSOA.context.getParameter(PARAM.FILTER));

        if (!ITEM_FILTER) {
            NSOA.meta.log('debug', 'No project item type filter set. Running for all item types.');
        }

        // Get new and old issue records
        var recIss = NSOA.form.getNewRecord(),
            recIssOld = NSOA.form.getOldRecord();

        // This should should never trigger
        if (!recIss || recIss === undefined) {
            return;
        }

        // Only run for project item types (issue stages) that match
        // the set scripting parameter. Only one item type filter is
        // currently allowed. If no project item type filter is
        // defined, run for all items.
        if (ITEM_FILTER && recIss.issue_stage_id !== ITEM_FILTER) {
            return;
        }

        // Create issue object for modify later
        var objIss = new NSOA.record.oaIssue();
        objIss.id  = recIss.id;

        // Set dirty flag for triggering update
        var needsUpdate = false;

        /*
         * OVERALL RISK
         */

        // Only trigger dirty flag for new issues, or issues with changed values
        if (type === 'new' || recIss[FLD.OVERALL] !== recIssOld[FLD.OVERALL]) {
            // Record is dirty, set flag
            needsUpdate = true;
            if (recIss[FLD.OVERALL]) {
                var overall_risk     = NSOA.record.oaCategory_1(recIss[FLD.OVERALL]);
                var overall_risk_tag = createTag(overall_risk[FLD.FOREGROUND], overall_risk[FLD.BACKGROUND], overall_risk.name);

                if (!overall_risk_tag || overall_risk_tag.error) {
                    NSOA.meta.log('error', 'Error generating OVERALL tag: ' + overall_risk_tag.error.message);
                } else {
                    objIss[FLD.OVERALLCOLOR] = overall_risk_tag.html;
                }
            } else {
                // Null or blank value was found, set blank/empty string
                objIss[FLD.OVERALLCOLOR] = '';
            }
        }

        /*
         * BUDGET RISK
         */

        // Only trigger dirty flag for new issues, or issues with changed values
        if (type === 'new' || recIss[FLD.BUDGET] !== recIssOld[FLD.BUDGET]) {
            // Record is dirty, set flag
            needsUpdate = true;

            if (recIss[FLD.BUDGET]) {
                var budget_risk     = NSOA.record.oaCategory_1(recIss[FLD.BUDGET]);
                var budget_risk_tag = createTag(budget_risk[FLD.FOREGROUND], budget_risk[FLD.BACKGROUND], budget_risk.name);
                if (!budget_risk_tag || budget_risk_tag.error) {
                    NSOA.meta.log('error', 'Error generating BUDGET tag: ' + budget_risk_tag.error.message);
                } else {
                    objIss[FLD.BUDGETCOLOR] = budget_risk_tag.html;
                }
            } else {
                // Null or blank value was found, set blank/empty string
                objIss[FLD.BUDGETCOLOR] = '';
            }
        }

        /*
         * SCHEDULE RISK
         */

        // Only trigger dirty flag for new issues, or issues with changed values
        if (type === 'new' || recIss[FLD.SCHEDULE] !== recIssOld[FLD.SCHEDULE]) {
            // Record is dirty, set flag
            needsUpdate = true;

            if (recIss[FLD.SCHEDULE]) {
                var schedule_risk     = NSOA.record.oaCategory_1(recIss[FLD.SCHEDULE]);
                var schedule_risk_tag = createTag(schedule_risk[FLD.FOREGROUND], schedule_risk[FLD.BACKGROUND], schedule_risk.name);
                if (!schedule_risk_tag || schedule_risk_tag.error) {
                    NSOA.meta.log('error', 'Error generating SCHEDULE tag: ' + schedule_risk_tag.error.message);
                } else {
                    objIss[FLD.SCHEDULECOLOR] = schedule_risk_tag.html;
                }
            } else {
                // Null or blank value was found, set blank/empty string
                objIss[FLD.SCHEDULECOLOR] = '';
            }
        }

        // If issue is dirty, perform update
        if (needsUpdate) {
            NSOA.wsapi.disableFilterSet(true);
            var results = NSOA.wsapi.modify([{name: 'update_custom', value: '1'}], [objIss]);
        }
    } catch (e) {
        NSOA.meta.log('error', 'Try/catch error: ' + e);
    }
}

/**
 * Create an HTML element styled as a Tag.
 *
 * @private
 * @param  {string} foreground   Foreground color string (can be keyword, HEX, RGB, RGBA, HSL).
 * @param  {string} background   Foreground color string (can be keyword, HEX, RGB, RGBA, HSL).
 * @param  {string} text         Text label for HTML tag.
 * @param  {object} options      Override CSS settings for HTML tag (optional).
 * @return {data}                A data object.
 * @return {data.error}          An error string.
 * @return {data.html}           An HTML string.
 */
function createTag(foreground, background, text, options) {
    var fg   = (foreground || '#fff'),     // white
        bg   = (background || '#818a91'),  // gray
        text = (text || ''),
        opt  = (options || {}),

        /**
         * A default styling object for HTML tags.
         *
         * @type {object}
         * @type {object.width}        CSS width attribute (rem or em preferred).
         * @type {object.padding}      CSS padding attribute (rem or em preferred).
         * @type {object.fontSize}     CSS font-size attribute.
         * @type {object.fontWeight}   CSS font-weight attribute.
         * @type {object.lineHeight}   CSS line-height attribute.
         * @type {object.borderRadius} CSS border-radius attribute (rem preferred).
         */
        defaults = {
            width: '3.75rem',
            padding: '.25em .4em',
            fontSize: '75%',
            fontWeight: '700',
            lineHeight: '1',
            borderRadius: '.25rem'
        }
    ;

    // Set defaults with optional overrides
    for (var name in defaults) {
        if (!(name in opt)) {
            opt[name] = defaults[name];
        }
    }

    /**
     * A risk tag return object.
     *
     * @type {object}
     * @type {object.html}  An HTML string.
     * @type {object.error} An error string.
     */
    var data = {
        html: null,
        error: null
    };

    /*
     * Regular expression for HEX color code validation. This will match
     * both 3 and 6 character HEX color codes, with or without a leading
     * hash character.
     *
     * ^                     Match start of string
     * (?:                   Non-capturing group
     *     #                 Hash character
     *     ?                 Optional match of previous character
     * )                     End of non-capturing group
     * [0-9a-f]{3}           Characters 0-9 or a-f appear exactly 3 times
     * (:?                   Non-capturing group
     *     [0-9a-f]{3}       Characters 0-9 or a-f appear exactly 3 times
     * )                     End of non-capturing group
     * ?                     Optional match of previous group
     * $                     Match end of string
     * i                     Flag: Ignore case
     *
     */
    var regex = /^(?:#?)[0-9a-f]{3}(?:[0-9a-f]{3})?$/i;

    // Test string for valid 3-character or 6-character hex color codes
    var isValidHexFg = regex.test(fg);
    if (!isValidHexFg) {data.error = 'Parsing error: Invalid foreground HEX color code ' + fg + ' for ' + text;}

    // Test string for valid 3-character or 6-character hex color codes
    var isValidHexBg = regex.test(bg);
    if (!isValidHexBg) {data.error = 'Parsing error: Invalid background HEX color code ' + bg + ' for ' + text;}

    // Test string for leading hash, otherwise prepend it to create valid HEX color code
    if (fg.charAt(0) !== '#') {fg = '#' + fg;}

    // Test string for leading hash, otherwise prepend it to create valid HEX color code
    if (bg.charAt(0) !== '#') {bg = '#' + bg;}

    try {
        data.html = '<div style="margin:0 auto;">' +
            '<span style="-webkit-box-sizing:inherit;box-sizing:inherit;display:inline-block' +
            ';min-width:' + opt.width +
            ';padding:' + opt.padding +
            ';font-size:' + opt.fontSize +
            ';font-weight:' + opt.fontWeight +
            ';line-height:' + opt.lineHeight +
            ';color:' + fg +
            ';border-radius:' + opt.borderRadius +
            ';background-color:' + bg +
            ';text-align:center;white-space:nowrap;vertical-align:baseline;">' + text +
            '</span>' +
            '</div>'
        ;
    } catch (e) {
        data.error += e;
    } finally {
        return data;
    }
}
<platform_solution>
    <objects>
        <pick_list_parameter>
            <list_source>issue_stage</list_source>
            <name>ss_iss_item_type_filter</name>
            <description>SuiteSolution: Project item type filter</description>
        </pick_list_parameter>
        <text_cust_field>
            <field_size>25</field_size>
            <never_copy>false</never_copy>
            <required>false</required>
            <association>category_1</association>
            <divider_text></divider_text>
            <unique>false</unique>
            <name>ss_svcln_risk_foreground</name>
            <description>Foreground Color</description>
            <with_notes>false</with_notes>
            <hint>Enter a 3 or 6 character hex color code (e.g. #FFF or e3e3e3)</hint>
            <title>Foreground color</title>
            <hidden>false</hidden>
            <max_length>25</max_length>
            <divider>false</divider>
        </text_cust_field>
        <text_cust_field>
            <field_size>25</field_size>
            <never_copy>false</never_copy>
            <required>false</required>
            <association>category_1</association>
            <divider_text></divider_text>
            <unique>false</unique>
            <name>ss_svcln_risk_background</name>
            <description>Background Color</description>
            <with_notes>false</with_notes>
            <hint>Enter a 3 or 6 character hex color code (e.g. #FFF or e3e3e3)</hint>
            <title>Background color</title>
            <hidden>false</hidden>
            <max_length>25</max_length>
            <divider>false</divider>
        </text_cust_field>
        <pick_list_cust_field>
            <divider_text></divider_text>
            <name>ss_iss_overall_risk</name>
            <never_copy>false</never_copy>
            <description>Overall risk</description>
            <with_notes>false</with_notes>
            <list_source>category_1</list_source>
            <hint></hint>
            <hidden>false</hidden>
            <title>Overall risk</title>
            <association>issue</association>
            <divider>true</divider>
        </pick_list_cust_field>
        <text_area_cust_field>
            <divider_text></divider_text>
            <name>ss_iss_overall_risk_text</name>
            <never_copy>false</never_copy>
            <rows>3</rows>
            <description>Overall risk notes</description>
            <with_notes>false</with_notes>
            <required>false</required>
            <hint></hint>
            <field_width>50</field_width>
            <hidden>false</hidden>
            <title>Overall risk notes</title>
            <association>issue</association>
            <divider>false</divider>
        </text_area_cust_field>
        <text_area_cust_field>
            <divider_text></divider_text>
            <name>ss_iss_overall_risk_tag</name>
            <never_copy>false</never_copy>
            <rows>3</rows>
            <description>Overal risk tag</description>
            <with_notes>false</with_notes>
            <required>false</required>
            <hint></hint>
            <field_width>75</field_width>
            <hidden>true</hidden>
            <title>Overall risk tag</title>
            <association>issue</association>
            <divider>false</divider>
        </text_area_cust_field>
        <pick_list_cust_field>
            <divider_text></divider_text>
            <name>ss_iss_budget_risk</name>
            <never_copy>false</never_copy>
            <description>Budget risk</description>
            <with_notes>false</with_notes>
            <list_source>category_1</list_source>
            <hint></hint>
            <hidden>false</hidden>
            <title>Budget risk</title>
            <association>issue</association>
            <divider>false</divider>
        </pick_list_cust_field>
        <text_area_cust_field>
            <divider_text></divider_text>
            <name>ss_iss_budget_risk_text</name>
            <never_copy>false</never_copy>
            <rows>3</rows>
            <description>Budget risk notes</description>
            <with_notes>false</with_notes>
            <required>false</required>
            <hint></hint>
            <field_width>50</field_width>
            <hidden>false</hidden>
            <title>Budget risk notes</title>
            <association>issue</association>
            <divider>false</divider>
        </text_area_cust_field>
        <text_area_cust_field>
            <divider_text></divider_text>
            <name>ss_iss_budget_risk_tag</name>
            <never_copy>false</never_copy>
            <rows>3</rows>
            <description>Budget risk tag</description>
            <with_notes>false</with_notes>
            <required>false</required>
            <hint></hint>
            <field_width>75</field_width>
            <hidden>true</hidden>
            <title>Budget risk tag</title>
            <association>issue</association>
            <divider>false</divider>
        </text_area_cust_field>
        <pick_list_cust_field>
            <divider_text></divider_text>
            <name>ss_iss_schedule_risk</name>
            <never_copy>false</never_copy>
            <description>Schedule risk</description>
            <with_notes>false</with_notes>
            <list_source>category_1</list_source>
            <hint></hint>
            <hidden>false</hidden>
            <title>Schedule risk</title>
            <association>issue</association>
            <divider>false</divider>
        </pick_list_cust_field>
        <text_area_cust_field>
            <divider_text></divider_text>
            <name>ss_iss_schedule_risk_text</name>
            <never_copy>false</never_copy>
            <rows>3</rows>
            <description>Schedule risk notes</description>
            <with_notes>false</with_notes>
            <required>false</required>
            <hint></hint>
            <field_width>50</field_width>
            <hidden>false</hidden>
            <title>Schedule risk notes</title>
            <association>issue</association>
            <divider>false</divider>
        </text_area_cust_field>
        <text_area_cust_field>
            <divider_text></divider_text>
            <name>ss_iss_schedule_risk_tag</name>
            <never_copy>false</never_copy>
            <rows>3</rows>
            <description>Schedule risk tag</description>
            <with_notes>false</with_notes>
            <required>false</required>
            <hint></hint>
            <field_width>75</field_width>
            <hidden>true</hidden>
            <title>Schedule risk tag</title>
            <association>issue</association>
            <divider>false</divider>
        </text_area_cust_field>
        <form_script>
            <custom_fields>
                <custom_field>ss_svcln_risk_foreground</custom_field>
                <custom_field>ss_svcln_risk_background</custom_field>
                <custom_field>ss_iss_overall_risk</custom_field>
                <custom_field>ss_iss_schedule_risk</custom_field>
                <custom_field>ss_iss_budget_risk</custom_field>
                <custom_field>ss_iss_overall_risk_text</custom_field>
                <custom_field>ss_iss_schedule_risk_text</custom_field>
                <custom_field>ss_iss_budget_risk_text</custom_field>
                <custom_field>ss_iss_overall_risk_tag</custom_field>
                <custom_field>ss_iss_schedule_risk_tag</custom_field>
                <custom_field>ss_iss_budget_risk_tag</custom_field>
            </custom_fields>
            <name>SuiteSolution_RiskTags_Prj.nsoa.js</name>
            <event>after_save</event>
            <libraries></libraries>
            <comments></comments>
            <entrance_function>main</entrance_function>
            <parameters>
                <parameter>ss_iss_item_type_filter</parameter>
            </parameters>
            <__is_linked>true</__is_linked>
            <association>project_issue_edit_form</association>
            <code><![CDATA[/* jshint shadow:true, curly:true, undef:true, quotmark:true, sub:true */
/* globals NSOA */

/**
 * @name SuiteSolution: Risk Tags
 * @copyright Oracle, Inc. 2017. All rights reserved.
 * @version 1.0
 *
 * Create HTML elements of type TAG. These are based on the Bootstrap
 * tag element which can be found here:
 * http://v4-alpha.getbootstrap.com/components/tag/
 *
 * This SuiteSolution requires the use of the extended category 1 feature.
 * Please talk to your NetSuite account manager or PS contact before
 * installing and using this solution.
 *
 * This SuiteSolution requires the use of field whitelisting to allow for
 * the injection of HTML tags into textarea fields. Please consult with your
 * local IT & Security personnel before installing and using this solution.
 * You will need to whitelist FLD.OVERALL, FLD.BUDGET and FLD.SCHEDULE to
 * allow for the injection of HTML content.
 *
 */


/**
 * The main runtime function.
 *
 * @param {string} type OpenAir form script event type (new | edit).
 */
function main(type) {
    // Custom fields used in this solution
    var FLD = {
        OVERALL: 'ss_iss_overall_risk__c',
        OVERALLCOLOR: 'ss_iss_overall_risk_tag__c',
        BUDGET: 'ss_iss_budget_risk__c',
        BUDGETCOLOR: 'ss_iss_budget_risk_tag__c',
        SCHEDULE: 'ss_iss_schedule_risk__c',
        SCHEDULECOLOR: 'ss_iss_schedule_risk_tag__c',
        FOREGROUND: 'ss_svcln_risk_foreground__c',
        BACKGROUND: 'ss_svcln_risk_background__c'
    };
    // Script parameters used in this solution
    var PARAM = {
        FILTER: 'ss_iss_item_type_filter'
    };

    /**
     * DO NOT CHANGE ANYTHING ABOVE THIS LINE BEFORE CONSULTING NETSUITE
     * TECHNICAL SERVICES, AS THEY ARE PRE-BUILT INTO THE SUITESOLUTION.
     */

    try {
        // Only run script for issue stages set as script parameter
        var ITEM_FILTER = parseInt(NSOA.context.getParameter(PARAM.FILTER));

        if (!ITEM_FILTER) {
            NSOA.meta.log('debug', 'No project item type filter set. Running for all item types.');
        }

        // Get new and old issue records
        var recIss = NSOA.form.getNewRecord(),
            recIssOld = NSOA.form.getOldRecord();

        // This should should never trigger
        if (!recIss || recIss === undefined) {
            return;
        }

        // Only run for project item types (issue stages) that match
        // the set scripting parameter. Only one item type filter is
        // currently allowed. If no project item type filter is
        // defined, run for all items.
        if (ITEM_FILTER && recIss.issue_stage_id !== ITEM_FILTER) {
            return;
        }

        // Create issue object for modify later
        var objIss = new NSOA.record.oaIssue();
        objIss.id  = recIss.id;

        // Set dirty flag for triggering update
        var needsUpdate = false;

        /*
         * OVERALL RISK
         */

        // Only trigger dirty flag for new issues, or issues with changed values
        if (type === 'new' || recIss[FLD.OVERALL] !== recIssOld[FLD.OVERALL]) {
            // Record is dirty, set flag
            needsUpdate = true;
            if (recIss[FLD.OVERALL]) {
                var overall_risk     = NSOA.record.oaCategory_1(recIss[FLD.OVERALL]);
                var overall_risk_tag = createTag(overall_risk[FLD.FOREGROUND], overall_risk[FLD.BACKGROUND], overall_risk.name);

                if (!overall_risk_tag || overall_risk_tag.error) {
                    NSOA.meta.log('error', 'Error generating OVERALL tag: ' + overall_risk_tag.error.message);
                } else {
                    objIss[FLD.OVERALLCOLOR] = overall_risk_tag.html;
                }
            } else {
                // Null or blank value was found, set blank/empty string
                objIss[FLD.OVERALLCOLOR] = '';
            }
        }

        /*
         * BUDGET RISK
         */

        // Only trigger dirty flag for new issues, or issues with changed values
        if (type === 'new' || recIss[FLD.BUDGET] !== recIssOld[FLD.BUDGET]) {
            // Record is dirty, set flag
            needsUpdate = true;

            if (recIss[FLD.BUDGET]) {
                var budget_risk     = NSOA.record.oaCategory_1(recIss[FLD.BUDGET]);
                var budget_risk_tag = createTag(budget_risk[FLD.FOREGROUND], budget_risk[FLD.BACKGROUND], budget_risk.name);
                if (!budget_risk_tag || budget_risk_tag.error) {
                    NSOA.meta.log('error', 'Error generating BUDGET tag: ' + budget_risk_tag.error.message);
                } else {
                    objIss[FLD.BUDGETCOLOR] = budget_risk_tag.html;
                }
            } else {
                // Null or blank value was found, set blank/empty string
                objIss[FLD.BUDGETCOLOR] = '';
            }
        }

        /*
         * SCHEDULE RISK
         */

        // Only trigger dirty flag for new issues, or issues with changed values
        if (type === 'new' || recIss[FLD.SCHEDULE] !== recIssOld[FLD.SCHEDULE]) {
            // Record is dirty, set flag
            needsUpdate = true;

            if (recIss[FLD.SCHEDULE]) {
                var schedule_risk     = NSOA.record.oaCategory_1(recIss[FLD.SCHEDULE]);
                var schedule_risk_tag = createTag(schedule_risk[FLD.FOREGROUND], schedule_risk[FLD.BACKGROUND], schedule_risk.name);
                if (!schedule_risk_tag || schedule_risk_tag.error) {
                    NSOA.meta.log('error', 'Error generating SCHEDULE tag: ' + schedule_risk_tag.error.message);
                } else {
                    objIss[FLD.SCHEDULECOLOR] = schedule_risk_tag.html;
                }
            } else {
                // Null or blank value was found, set blank/empty string
                objIss[FLD.SCHEDULECOLOR] = '';
            }
        }

        // If issue is dirty, perform update
        if (needsUpdate) {
            NSOA.wsapi.disableFilterSet(true);
            var results = NSOA.wsapi.modify([{name: 'update_custom', value: '1'}], [objIss]);
        }
    } catch (e) {
        NSOA.meta.log('error', 'Try/catch error: ' + e);
    }
}

/**
 * Create an HTML element styled as a Tag.
 *
 * @private
 * @param  {string} foreground   Foreground color string (can be keyword, HEX, RGB, RGBA, HSL).
 * @param  {string} background   Foreground color string (can be keyword, HEX, RGB, RGBA, HSL).
 * @param  {string} text         Text label for HTML tag.
 * @param  {object} options      Override CSS settings for HTML tag (optional).
 * @return {data}                A data object.
 * @return {data.error}          An error string.
 * @return {data.html}           An HTML string.
 */
function createTag(foreground, background, text, options) {
    var fg   = (foreground || '#fff'),     // white
        bg   = (background || '#818a91'),  // gray
        text = (text || ''),
        opt  = (options || {}),

        /**
         * A default styling object for HTML tags.
         *
         * @type {object}
         * @type {object.width}        CSS width attribute (rem or em preferred).
         * @type {object.padding}      CSS padding attribute (rem or em preferred).
         * @type {object.fontSize}     CSS font-size attribute.
         * @type {object.fontWeight}   CSS font-weight attribute.
         * @type {object.lineHeight}   CSS line-height attribute.
         * @type {object.borderRadius} CSS border-radius attribute (rem preferred).
         */
        defaults = {
            width: '3.75rem',
            padding: '.25em .4em',
            fontSize: '75%',
            fontWeight: '700',
            lineHeight: '1',
            borderRadius: '.25rem'
        }
    ;

    // Set defaults with optional overrides
    for (var name in defaults) {
        if (!(name in opt)) {
            opt[name] = defaults[name];
        }
    }

    /**
     * A risk tag return object.
     *
     * @type {object}
     * @type {object.html}  An HTML string.
     * @type {object.error} An error string.
     */
    var data = {
        html: null,
        error: null
    };

    /*
     * Regular expression for HEX color code validation. This will match
     * both 3 and 6 character HEX color codes, with or without a leading
     * hash character.
     *
     * ^                     Match start of string
     * (?:                   Non-capturing group
     *     #                 Hash character
     *     ?                 Optional match of previous character
     * )                     End of non-capturing group
     * [0-9a-f]{3}           Characters 0-9 or a-f appear exactly 3 times
     * (:?                   Non-capturing group
     *     [0-9a-f]{3}       Characters 0-9 or a-f appear exactly 3 times
     * )                     End of non-capturing group
     * ?                     Optional match of previous group
     * $                     Match end of string
     * i                     Flag: Ignore case
     *
     */
    var regex = /^(?:#?)[0-9a-f]{3}(?:[0-9a-f]{3})?$/i;

    // Test string for valid 3-character or 6-character hex color codes
    var isValidHexFg = regex.test(fg);
    if (!isValidHexFg) {data.error = 'Parsing error: Invalid foreground HEX color code ' + fg + ' for ' + text;}

    // Test string for valid 3-character or 6-character hex color codes
    var isValidHexBg = regex.test(bg);
    if (!isValidHexBg) {data.error = 'Parsing error: Invalid background HEX color code ' + bg + ' for ' + text;}

    // Test string for leading hash, otherwise prepend it to create valid HEX color code
    if (fg.charAt(0) !== '#') {fg = '#' + fg;}

    // Test string for leading hash, otherwise prepend it to create valid HEX color code
    if (bg.charAt(0) !== '#') {bg = '#' + bg;}

    try {
        data.html = '<div style="margin:0 auto;">' +
            '<span style="-webkit-box-sizing:inherit;box-sizing:inherit;display:inline-block' +
            ';min-width:' + opt.width +
            ';padding:' + opt.padding +
            ';font-size:' + opt.fontSize +
            ';font-weight:' + opt.fontWeight +
            ';line-height:' + opt.lineHeight +
            ';color:' + fg +
            ';border-radius:' + opt.borderRadius +
            ';background-color:' + bg +
            ';text-align:center;white-space:nowrap;vertical-align:baseline;">' + text +
            '</span>' +
            '</div>'
        ;
    } catch (e) {
        data.error += e;
    } finally {
        return data;
    }
}]]></code>
        </form_script>
        <form_script>
            <custom_fields>
                <custom_field>ss_svcln_risk_foreground</custom_field>
                <custom_field>ss_svcln_risk_background</custom_field>
                <custom_field>ss_iss_overall_risk</custom_field>
                <custom_field>ss_iss_schedule_risk</custom_field>
                <custom_field>ss_iss_budget_risk</custom_field>
                <custom_field>ss_iss_overall_risk_text</custom_field>
                <custom_field>ss_iss_schedule_risk_text</custom_field>
                <custom_field>ss_iss_budget_risk_text</custom_field>
                <custom_field>ss_iss_overall_risk_tag</custom_field>
                <custom_field>ss_iss_schedule_risk_tag</custom_field>
                <custom_field>ss_iss_budget_risk_tag</custom_field>
            </custom_fields>
            <name>SuiteSolution_RiskTags_Iss.nsoa.js</name>
            <event>after_save</event>
            <libraries></libraries>
            <comments></comments>
            <entrance_function>main</entrance_function>
            <parameters>
                <parameter>ss_iss_item_type_filter</parameter>
            </parameters>
            <__is_linked>true</__is_linked>
            <association>issue_edit_form</association>
            <code><![CDATA[/* jshint shadow:true, curly:true, undef:true, quotmark:true, sub:true */
/* globals NSOA */

/**
 * @name SuiteSolution: Risk Tags
 * @copyright Oracle, Inc. 2017. All rights reserved.
 * @version 1.0
 *
 * Create HTML elements of type TAG. These are based on the Bootstrap
 * tag element which can be found here:
 * http://v4-alpha.getbootstrap.com/components/tag/
 *
 * This SuiteSolution requires the use of the extended category 1 feature.
 * Please talk to your NetSuite account manager or PS contact before
 * installing and using this solution.
 *
 * This SuiteSolution requires the use of field whitelisting to allow for
 * the injection of HTML tags into textarea fields. Please consult with your
 * local IT & Security personnel before installing and using this solution.
 * You will need to whitelist FLD.OVERALL, FLD.BUDGET and FLD.SCHEDULE to
 * allow for the injection of HTML content.
 *
 */


/**
 * The main runtime function.
 *
 * @param {string} type OpenAir form script event type (new | edit).
 */
function main(type) {
    // Custom fields used in this solution
    var FLD = {
        OVERALL: 'ss_iss_overall_risk__c',
        OVERALLCOLOR: 'ss_iss_overall_risk_tag__c',
        BUDGET: 'ss_iss_budget_risk__c',
        BUDGETCOLOR: 'ss_iss_budget_risk_tag__c',
        SCHEDULE: 'ss_iss_schedule_risk__c',
        SCHEDULECOLOR: 'ss_iss_schedule_risk_tag__c',
        FOREGROUND: 'ss_svcln_risk_foreground__c',
        BACKGROUND: 'ss_svcln_risk_background__c'
    };
    // Script parameters used in this solution
    var PARAM = {
        FILTER: 'ss_iss_item_type_filter'
    };

    /**
     * DO NOT CHANGE ANYTHING ABOVE THIS LINE BEFORE CONSULTING NETSUITE
     * TECHNICAL SERVICES, AS THEY ARE PRE-BUILT INTO THE SUITESOLUTION.
     */

    try {
        // Only run script for issue stages set as script parameter
        var ITEM_FILTER = parseInt(NSOA.context.getParameter(PARAM.FILTER));

        if (!ITEM_FILTER) {
            NSOA.meta.log('debug', 'No project item type filter set. Running for all item types.');
        }

        // Get new and old issue records
        var recIss = NSOA.form.getNewRecord(),
            recIssOld = NSOA.form.getOldRecord();

        // This should should never trigger
        if (!recIss || recIss === undefined) {
            return;
        }

        // Only run for project item types (issue stages) that match
        // the set scripting parameter. Only one item type filter is
        // currently allowed. If no project item type filter is
        // defined, run for all items.
        if (ITEM_FILTER && recIss.issue_stage_id !== ITEM_FILTER) {
            return;
        }

        // Create issue object for modify later
        var objIss = new NSOA.record.oaIssue();
        objIss.id  = recIss.id;

        // Set dirty flag for triggering update
        var needsUpdate = false;

        /*
         * OVERALL RISK
         */

        // Only trigger dirty flag for new issues, or issues with changed values
        if (type === 'new' || recIss[FLD.OVERALL] !== recIssOld[FLD.OVERALL]) {
            // Record is dirty, set flag
            needsUpdate = true;
            if (recIss[FLD.OVERALL]) {
                var overall_risk     = NSOA.record.oaCategory_1(recIss[FLD.OVERALL]);
                var overall_risk_tag = createTag(overall_risk[FLD.FOREGROUND], overall_risk[FLD.BACKGROUND], overall_risk.name);

                if (!overall_risk_tag || overall_risk_tag.error) {
                    NSOA.meta.log('error', 'Error generating OVERALL tag: ' + overall_risk_tag.error.message);
                } else {
                    objIss[FLD.OVERALLCOLOR] = overall_risk_tag.html;
                }
            } else {
                // Null or blank value was found, set blank/empty string
                objIss[FLD.OVERALLCOLOR] = '';
            }
        }

        /*
         * BUDGET RISK
         */

        // Only trigger dirty flag for new issues, or issues with changed values
        if (type === 'new' || recIss[FLD.BUDGET] !== recIssOld[FLD.BUDGET]) {
            // Record is dirty, set flag
            needsUpdate = true;

            if (recIss[FLD.BUDGET]) {
                var budget_risk     = NSOA.record.oaCategory_1(recIss[FLD.BUDGET]);
                var budget_risk_tag = createTag(budget_risk[FLD.FOREGROUND], budget_risk[FLD.BACKGROUND], budget_risk.name);
                if (!budget_risk_tag || budget_risk_tag.error) {
                    NSOA.meta.log('error', 'Error generating BUDGET tag: ' + budget_risk_tag.error.message);
                } else {
                    objIss[FLD.BUDGETCOLOR] = budget_risk_tag.html;
                }
            } else {
                // Null or blank value was found, set blank/empty string
                objIss[FLD.BUDGETCOLOR] = '';
            }
        }

        /*
         * SCHEDULE RISK
         */

        // Only trigger dirty flag for new issues, or issues with changed values
        if (type === 'new' || recIss[FLD.SCHEDULE] !== recIssOld[FLD.SCHEDULE]) {
            // Record is dirty, set flag
            needsUpdate = true;

            if (recIss[FLD.SCHEDULE]) {
                var schedule_risk     = NSOA.record.oaCategory_1(recIss[FLD.SCHEDULE]);
                var schedule_risk_tag = createTag(schedule_risk[FLD.FOREGROUND], schedule_risk[FLD.BACKGROUND], schedule_risk.name);
                if (!schedule_risk_tag || schedule_risk_tag.error) {
                    NSOA.meta.log('error', 'Error generating SCHEDULE tag: ' + schedule_risk_tag.error.message);
                } else {
                    objIss[FLD.SCHEDULECOLOR] = schedule_risk_tag.html;
                }
            } else {
                // Null or blank value was found, set blank/empty string
                objIss[FLD.SCHEDULECOLOR] = '';
            }
        }

        // If issue is dirty, perform update
        if (needsUpdate) {
            NSOA.wsapi.disableFilterSet(true);
            var results = NSOA.wsapi.modify([{name: 'update_custom', value: '1'}], [objIss]);
        }
    } catch (e) {
        NSOA.meta.log('error', 'Try/catch error: ' + e);
    }
}

/**
 * Create an HTML element styled as a Tag.
 *
 * @private
 * @param  {string} foreground   Foreground color string (can be keyword, HEX, RGB, RGBA, HSL).
 * @param  {string} background   Foreground color string (can be keyword, HEX, RGB, RGBA, HSL).
 * @param  {string} text         Text label for HTML tag.
 * @param  {object} options      Override CSS settings for HTML tag (optional).
 * @return {data}                A data object.
 * @return {data.error}          An error string.
 * @return {data.html}           An HTML string.
 */
function createTag(foreground, background, text, options) {
    var fg   = (foreground || '#fff'),     // white
        bg   = (background || '#818a91'),  // gray
        text = (text || ''),
        opt  = (options || {}),

        /**
         * A default styling object for HTML tags.
         *
         * @type {object}
         * @type {object.width}        CSS width attribute (rem or em preferred).
         * @type {object.padding}      CSS padding attribute (rem or em preferred).
         * @type {object.fontSize}     CSS font-size attribute.
         * @type {object.fontWeight}   CSS font-weight attribute.
         * @type {object.lineHeight}   CSS line-height attribute.
         * @type {object.borderRadius} CSS border-radius attribute (rem preferred).
         */
        defaults = {
            width: '3.75rem',
            padding: '.25em .4em',
            fontSize: '75%',
            fontWeight: '700',
            lineHeight: '1',
            borderRadius: '.25rem'
        }
    ;

    // Set defaults with optional overrides
    for (var name in defaults) {
        if (!(name in opt)) {
            opt[name] = defaults[name];
        }
    }

    /**
     * A risk tag return object.
     *
     * @type {object}
     * @type {object.html}  An HTML string.
     * @type {object.error} An error string.
     */
    var data = {
        html: null,
        error: null
    };

    /*
     * Regular expression for HEX color code validation. This will match
     * both 3 and 6 character HEX color codes, with or without a leading
     * hash character.
     *
     * ^                     Match start of string
     * (?:                   Non-capturing group
     *     #                 Hash character
     *     ?                 Optional match of previous character
     * )                     End of non-capturing group
     * [0-9a-f]{3}           Characters 0-9 or a-f appear exactly 3 times
     * (:?                   Non-capturing group
     *     [0-9a-f]{3}       Characters 0-9 or a-f appear exactly 3 times
     * )                     End of non-capturing group
     * ?                     Optional match of previous group
     * $                     Match end of string
     * i                     Flag: Ignore case
     *
     */
    var regex = /^(?:#?)[0-9a-f]{3}(?:[0-9a-f]{3})?$/i;

    // Test string for valid 3-character or 6-character hex color codes
    var isValidHexFg = regex.test(fg);
    if (!isValidHexFg) {data.error = 'Parsing error: Invalid foreground HEX color code ' + fg + ' for ' + text;}

    // Test string for valid 3-character or 6-character hex color codes
    var isValidHexBg = regex.test(bg);
    if (!isValidHexBg) {data.error = 'Parsing error: Invalid background HEX color code ' + bg + ' for ' + text;}

    // Test string for leading hash, otherwise prepend it to create valid HEX color code
    if (fg.charAt(0) !== '#') {fg = '#' + fg;}

    // Test string for leading hash, otherwise prepend it to create valid HEX color code
    if (bg.charAt(0) !== '#') {bg = '#' + bg;}

    try {
        data.html = '<div style="margin:0 auto;">' +
            '<span style="-webkit-box-sizing:inherit;box-sizing:inherit;display:inline-block' +
            ';min-width:' + opt.width +
            ';padding:' + opt.padding +
            ';font-size:' + opt.fontSize +
            ';font-weight:' + opt.fontWeight +
            ';line-height:' + opt.lineHeight +
            ';color:' + fg +
            ';border-radius:' + opt.borderRadius +
            ';background-color:' + bg +
            ';text-align:center;white-space:nowrap;vertical-align:baseline;">' + text +
            '</span>' +
            '</div>'
        ;
    } catch (e) {
        data.error += e;
    } finally {
        return data;
    }
}]]></code>
        </form_script>
    </objects>
    <version>1.1</version>
    <title>SuiteSolution: Risk Tags</title>
    <description><![CDATA[Easily add 3 risk tracking tags to your project items to easily see which projects need your attention at a glance.

    Features:

    - Overall risk, Budget risk, and Schedule risk are included, along with notes.
    - Unlimited status choices available through the use of category_1 picklist record.
    - Customized color coding available for foreground (text) and background using HTML hex codes.
    - Display tags in list views, reports, and project status summaries.
    - Supports graceful fall back to text values for printing or exporting to PDF.

    Configuration:

    - Set the "SuiteSolution: Project item type filter" to one item type
    - Add/remove your "Project risk value" records (category_1)]]></description>
</platform_solution>

以上是关于xml OA:SuiteSolution - OpenAir风险标签的主要内容,如果未能解决你的问题,请参考以下文章

xml OA:CIOCoE示例API调用

xml OA:演示解决方案 - OpenAir项目风险指标

SSH整合总结(OA项目)

IDEA + SSH OA 第一天(项目收获:Hibernate XML)

OA学习笔记-004-Spring2.5配置

java OA项目源码 flowable activiti流程引擎 Springboot html vue.js 前后分离