Change Behaviour when Updating Install Status and Operational Status on Business Applications

nameisnani
Mega Sage

Hi Team ,

 

I have identified some incorrect behaviour when updating the statuses of Business Applications today.

When the Install status is updated to Retired, then it automatically changes the Operational Status to Retired.

When the Operational Status is changed to Decommissioned, then it automatically changes the Install Status to In Production.

This behaviour needs to be changed so that these 2 fields can be updated independently without impacting the other.

For example, if I change the value in the Install Status field, then it should have no impact on the Operational Status value.

Similarly, if I change the value in the Operational Status field, then it should have no impact on the Install Status value.

 

nameisnani_0-1752218277173.png

 

 

I am thinking is that because of this BR 

nameisnani_1-1752218326206.png

 

 

@Ankur Bawiskar  - Can you please - help me on this request . 

 

If the issue with the BR -  could you please me on the updation 

var OpsStatusSynchronizer = Class.create();
OpsStatusSynchronizer.prototype = {
    initialize: function(currentCIRecord) {
        if (!currentCIRecord)
            return;

        this.current = currentCIRecord;
        if (currentCIRecord.getElement('hardware_status')) {
            this.statusField = 'hardware_status';
            this.baseTable = 'cmdb_ci_hardware';
        } else {
            this.statusField = 'install_status';
            this.baseTable = 'cmdb_ci';
        }
    },

    shouldSync: function() {
        if (!this.current)
            return false;

        var current = this.current;
        var opsChoice = current.getElement('operational_status').getChoiceValueLang('en');
        var statusChoice = current.getElement(this.statusField).getChoiceValueLang('en');

        var retired = gs.getMessageLang('Retired', 'en');
        return opsChoice == retired && statusChoice != retired ||
            opsChoice != retired && statusChoice == retired;
    },

    syncStatus: function() {
        if (!this.current)
            return;

        var current = this.current;
        var statusField = this.statusField;
        var baseTable = this.baseTable;

        var retired = gs.getMessageLang('Retired', 'en');
        var fromOps = {};
        fromOps[retired] = retired;

        var toOps = {};
        toOps[retired] = retired;

        var ops = current.getElement('operational_status');
        var status = current.getElement(statusField);
        if (ops.changes()) { // higher priority for checking Operational Status
            var opsChoice = ops.getChoiceValueLang('en');
            var statusChoice = fromOps[opsChoice];
            var subStatusChoice = ''; // necessary to set Hardware Asset retired
            if (!statusChoice) {
                statusChoice = gs.getMessageLang('Installed', 'en');
                subStatusChoice = gs.getMessageLang('In Use', 'en');
            }
            current.setValue(statusField,
                new SNC.CMDBUtil().getChoiceListByLanguage(baseTable, statusField, 'en').getValueOf(statusChoice));
            if (baseTable == 'cmdb_ci_hardware') {
                var subStatusField = 'hardware_substatus';
                current.setValue(subStatusField, !subStatusChoice ? '' :
                    new SNC.CMDBUtil().getChoiceListByLanguage(baseTable, subStatusField, 'en').getValueOf(subStatusChoice));
            }

        } else {
            statusChoice = status.getChoiceValueLang('en');
            opsChoice = toOps[statusChoice];
            if (!opsChoice)
                opsChoice = gs.getMessageLang('Non-Operational', 'en');
            current.setValue('operational_status',
                new SNC.CMDBUtil().getChoiceListByLanguage(baseTable, 'operational_status', 'en').getValueOf(opsChoice));

        }
    },

    type: 'OpsStatusSynchronizer'
};

var synchronizer = new OpsStatusSynchronizer(current);
if (synchronizer.shouldSync())
    synchronizer.syncStatus();

 

8 REPLIES 8

nameisnani
Mega Sage

@Dr Atul G- LNG

 @Zack Hilacan1 

@Ankur Bawiskar 

 

My client is asking for quick resolution - could you please help me on this - 

Hi @nameisnani 

I doubt there’s a quick solution here. You’ll need to go through these links and understand the backend logic, mate.

*************************************************************************************************************
If my response proves useful, please indicate its helpfulness by selecting " Accept as Solution" and " Helpful." This action benefits both the community and me.

Regards
Dr. Atul G. - Learn N Grow Together
ServiceNow Techno - Functional Trainer
LinkedIn: https://www.linkedin.com/in/dratulgrover
YouTube: https://www.youtube.com/@LearnNGrowTogetherwithAtulG
Topmate: https://topmate.io/atul_grover_lng [ Connect for 1-1 Session]

****************************************************************************************************************

nameisnani
Mega Sage

@Dr Atul G- LNG 

 

I have created a system property 

 

 

Field Value

Namecmdb.sync_ops_status.disabled
Type`true
Valuetrue
Description"Disables status sync between install_status and operational_status in CMDB CI"

 

 

updated my BR 

var OpsStatusSynchronizer = Class.create();
OpsStatusSynchronizer.prototype = {
    initialize: function(currentCIRecord) {
        if (!currentCIRecord)
            return;

        this.current = currentCIRecord;

        // Detect if it's a hardware CI
        if (currentCIRecord.getElement('hardware_status')) {
            this.statusField = 'hardware_status';
            this.baseTable = 'cmdb_ci_hardware';
        } else {
            this.statusField = 'install_status';
            this.baseTable = 'cmdb_ci';
        }

        // System property to disable sync logic
        this.syncDisabled = gs.getProperty('cmdb.sync_ops_status.disabled') == 'true';
    },

    shouldSync: function() {
        if (this.syncDisabled || !this.current)
            return false;

        var current = this.current;
        var opsChoice = current.getElement('operational_status').getChoiceValueLang('en');
        var statusChoice = current.getElement(this.statusField).getChoiceValueLang('en');

        var retired = gs.getMessageLang('Retired', 'en');
        return opsChoice == retired && statusChoice != retired ||
               opsChoice != retired && statusChoice == retired;
    },

    syncStatus: function() {
        if (this.syncDisabled || !this.current)
            return;

        var current = this.current;
        var statusField = this.statusField;
        var baseTable = this.baseTable;

        var retired = gs.getMessageLang('Retired', 'en');
        var fromOps = {};
        fromOps[retired] = retired;

        var toOps = {};
        toOps[retired] = retired;

        var ops = current.getElement('operational_status');
        var status = current.getElement(statusField);

        if (ops.changes()) { // Give priority to Operational Status
            var opsChoice = ops.getChoiceValueLang('en');
            var statusChoice = fromOps[opsChoice];
            var subStatusChoice = ''; // Set Hardware Substatus if needed

            if (!statusChoice) {
                statusChoice = gs.getMessageLang('Installed', 'en');
                subStatusChoice = gs.getMessageLang('In Use', 'en');
            }

            current.setValue(
                statusField,
                new SNC.CMDBUtil()
                    .getChoiceListByLanguage(baseTable, statusField, 'en')
                    .getValueOf(statusChoice)
            );

            if (baseTable === 'cmdb_ci_hardware') {
                var subStatusField = 'hardware_substatus';
                current.setValue(
                    subStatusField,
                    !subStatusChoice ? '' :
                    new SNC.CMDBUtil()
                        .getChoiceListByLanguage(baseTable, subStatusField, 'en')
                        .getValueOf(subStatusChoice)
                );
            }

        } else {
            var statusChoice = status.getChoiceValueLang('en');
            var opsChoice = toOps[statusChoice];
            if (!opsChoice)
                opsChoice = gs.getMessageLang('Non-Operational', 'en');

            current.setValue(
                'operational_status',
                new SNC.CMDBUtil()
                    .getChoiceListByLanguage(baseTable, 'operational_status', 'en')
                    .getValueOf(opsChoice)
            );
        }
    },

    type: 'OpsStatusSynchronizer'
};

// Main execution
var synchronizer = new OpsStatusSynchronizer(current);
if (synchronizer.shouldSync())
    synchronizer.syncStatus();

 

 

i have tested - it is worked for me 

 

could you please tell , is there is any mistake in my process . 

Hi @nameisnani 

Process-wise, it looks good, but my only concern is that it might cause issues during upgrades. If it works well in your testing, then go ahead.

*************************************************************************************************************
If my response proves useful, please indicate its helpfulness by selecting " Accept as Solution" and " Helpful." This action benefits both the community and me.

Regards
Dr. Atul G. - Learn N Grow Together
ServiceNow Techno - Functional Trainer
LinkedIn: https://www.linkedin.com/in/dratulgrover
YouTube: https://www.youtube.com/@LearnNGrowTogetherwithAtulG
Topmate: https://topmate.io/atul_grover_lng [ Connect for 1-1 Session]

****************************************************************************************************************