Disabling "Standard Change Properties - Two step" the Change Management REST API fails to copy attachments from std_change_record_producer


Description

With "Standard Change Properties - Two step" disabled, the Change Management REST API fails to copy attachments related to the Standard Change template.

Steps to Reproduce

1. Go to Standard Change Properties
2. Uncheck Two step
3. Go to a std_change_record_producer record and attach a file
4. Go to the REST API Explorer
i. Namespace = sn_chg_request
ii. API Name = Change Management
iii. API Version = Latest
iv. Standard (POST)
v. standard_change_template_id put in the sys_id of the std_change_record_producer in #3
vi. Send

A new Standard change gets created missing the file attachment from the std_change_record_producer.

Workaround

This problem has been fixed. If you are able to upgrade, review the Fixed In section to determine the latest version with a permanent fix your instance can be upgraded to.

The pre-Orlando workaround was to modify the script includes listed below.

- StandardChangeTemplate -

Add the following two functions:

    applyToChange: function(changeRequestGr) {
        if (!changeRequestGr)
            return false;

        changeRequestGr.std_change_producer_version = this.getGlideRecord().current_version + "";

        if (this._log.atLevel(GSLog.DEBUG))
            this._log.debug("[applyToChange] std_change_producer_version sysId: " + changeRequestGr.std_change_producer_version);

        var isTableExtOfStdChgRecProd = GlideDBObjectManager.getTables(this.getGlideRecord().getTableName()).contains(StandardChangeTemplateSNC.CHANGE_RECORD_PRODUCER)

        if (this._log.atLevel(GSLog.DEBUG))
            this._log.debug("[applyToChange] isTableExtOfStdChgRecProd: " + isTableExtOfStdChgRecProd);

        if (isTableExtOfStdChgRecProd)
            return new GlideTemplate.getFromRecord(this.getGlideRecord().template.getRefRecord()).apply(changeRequestGr) === 0 ? true : false;

        return false;
    },

    copyAttachments: function(changeRequestGr) {
        // if two step enabled, Business Rule will copy the attachments
        if (new global.StdChangeUtils().isChangeStandardAndTwoStepEnabled(changeRequestGr))
            return true;

        var sourceTable = StandardChangeTemplateSNC.CHANGE_RECORD_PRODUCER;
        var sourceId = changeRequestGr.std_change_producer_version.std_change_producer + "";
        var targetTable = changeRequestGr.getTableName();
        var targetId = changeRequestGr.sys_id + "";

        if (this._log.atLevel(GSLog.DEBUG))
            this._log.debug("[copyAttachments] sourceTable: " + sourceTable + " sourceId: " + sourceId + " targetTable:" + targetTable + " targetId: " + targetId);

        var attachmentsGr = new GlideSysAttachment().getAttachments(sourceTable, sourceId);
        var attachmentCount = attachmentsGr.getRowCount();

        if (this._log.atLevel(GSLog.DEBUG))
            this._log.debug("[copyAttachments] attachmentCount: " + attachmentCount);

        if (attachmentCount < 1)
            return true;

        var attachments = GlideSysAttachment.copy(sourceTable, sourceId, targetTable, targetId);

        if (this._log.atLevel(GSLog.DEBUG))
            this._log.debug("[copyAttachments] copied attachments size: " + attachments.size());

        if (attachments.size() !== attachmentCount) {
            if (this._log.atLevel(GSLog.ERROR))
                this._log.error("[copyAttachments] failed to copy attachments to: " + changeRequestGr.getDisplayValue());

            return false;
        }

        return true;
    },


- StandardChangeProcess -

    applyTemplate: function(standardChangeTemplate) {
        if (!this._standardChangeActive)
            return true;

        standardChangeTemplate = this._validateStandardChangeTemplate(standardChangeTemplate);
        if (standardChangeTemplate === null)
            return false;

        if (this._log.atLevel(GSLog.DEBUG))
            this._log.debug("[apply] template: " + standardChangeTemplate.getGlideRecord().name);

        return standardChangeTemplate.applyToChange(this._gr);
    },

    copyAttachments: function(standardChangeTemplate) {
        standardChangeTemplate = this._validateStandardChangeTemplate(standardChangeTemplate);
        if (standardChangeTemplate === null)
            return false;

        return standardChangeTemplate.copyAttachments(this._gr);
    },

    _validateStandardChangeTemplate: function(standardChangeTemplate) {
        if (typeof standardChangeTemplate === "string")
            standardChangeTemplate = StandardChangeTemplate.findById(standardChangeTemplate);

        if (typeof standardChangeTemplate !== "object" || standardChangeTemplate.type !== "StandardChangeTemplate")
            return null;

        return standardChangeTemplate;
    },


- StandardChangeProcess - outside the object definition, add the following static like function declaration:

StandardChangeProcess.newChange = function(standardChangeTemplate, nameValuePairs) {
    var changeProcess = new StandardChangeProcess(ChangeRequest.newStandard().getGlideRecord());

    if (pm.isActive("com.snc.change_management.standard_change_catalog")) {
        standardChangeTemplate = typeof standardChangeTemplate === "string" ? StandardChangeTemplate.findById(standardChangeTemplate) : standardChangeTemplate;
        if (!standardChangeTemplate || standardChangeTemplate.type !== "StandardChangeTemplate")
            return null;

        var standardChangeTemplateApplied = changeProcess.applyTemplate(standardChangeTemplate);
        if (!standardChangeTemplateApplied)
            return null;
    }

    var fields = changeProcess.setValues(nameValuePairs);
    if (fields.ignored && fields.ignored.length > 0)
        changeProcess.__ignoredfields = fields.ignored;

    if (!changeProcess.insert())
        return null;

    changeProcess.copyAttachments(standardChangeTemplate);
    return changeProcess;
};



Related Problem: PRB1365831