As an existing customer, if you are upgrading to the current release from a release version older than Summer 2018, you must run a post-installation script manually through the developer console to update your existing Cart Views to the new framework.

For customers setting up org on release version later than Summer 2018, the post-install script runs automatically after you install the CPQ package. In such a case, you do not need to execute the migration script manually.

Apex Code: Create a new class in the org with the code given below.

public class APTS_CreateCartViews{

/**
 * Checks if the given string value is null or empty.
 * @param strValue the string to check
 * @return <code>true</code> if the string value is null or empty, <code>false</code> otherwise
 */
public static Boolean nullOrEmpty(String strValue) {
    // check if null or zero length string
    return (strValue == null || strValue.trim().length() == 0);
}
 
/**
 * Checks if the given list of objects is null or empty.
 * @param objList the list of objects to check
 * @return <code>true</code> if the list is null or empty, <code>false</code> otherwise
 */
public static Boolean nullOrEmpty(List<Object> objList) {
    // check if null or empty
    return (objList == null || objList.isEmpty());
}
 
/**
 * returns comma separated value
 */
public static String arrayToCSV(String[] arr){
    String str = '';
    Boolean isFirst = true;
    for(String ele : arr){
        if(isFirst){ isFirst = false; }else{
            str += ', '; //adding space since to display rule action info properly in the layout
        }
        str += ele;
    }
    return str;
}
 
public static void saveFieldList(String dataStore, List<String> fieldNames) {
     
    String names = arrayToCSV(fieldNames);
    Integer len = names.length();
    Integer recordCount = Integer.valueOf(Math.ceil(len * 1.0 / 255));
     
    //delete existing records
    Apttus_Config2__ConfigFieldSet__c dataCache = Apttus_Config2__ConfigFieldSet__c.getInstance(dataStore + '_' + 0 );
    if (dataCache != null) {
        List<Apttus_Config2__ConfigFieldSet__c> queryFieldList = new List<Apttus_Config2__ConfigFieldSet__c>();
        Integer index = 1;
        while(dataCache != null){
            queryFieldList.add(dataCache);
            dataCache = Apttus_Config2__ConfigFieldSet__c.getInstance(dataStore + '_' + index );
            index += 1;
             
        }
        delete queryFieldList;
         
    }
         
    List<Apttus_Config2__ConfigFieldSet__c> queryFieldList = new List<Apttus_Config2__ConfigFieldSet__c>();
         
    for (Integer i = 0; i < recordCount; i++) {
        Integer startIndex = i * 255;
        Integer endIndex = (i + 1) * 255;
        Integer isLast = 0;
        if (endIndex >= len) {
            endIndex = len;
            isLast = 1;
        }
        queryFieldList.add(new Apttus_Config2__ConfigFieldSet__c(Name = dataStore + '_' + i, Apttus_Config2__Data__c = names.substring(startIndex, endIndex), Apttus_Config2__IsLast__c = isLast));
             
    }
 
    insert queryFieldList;
}
 
public class MigrateCartView {
    public String GroupByField;
    public String viewName;
    public List<columnDO> Columns;
    public Boolean isDefault = false;
}
 
//Data structure used to hold the deserialized JSON of cartviewsetting.   
public class columnDO {
    public String FieldName;
    public Integer Sequence;
    public String Pinned;
}
 
//this method deserialize the cartview setting related data stored in JSON format.
private static List<MigrateCartView> parse(String json) {
    return (List<MigrateCartView>) System.JSON.deserialize(json, List<MigrateCartView>.class);
}
 
/**
 * Create the new Cart Views Setting Group for Application Management feature of New Admin
 */
public static void createCartViewsSettingGroup() {
    List<Apttus_Config2__ApplicationFeature__c> cartPageAppFeatures = [SELECT Id,Name,Apttus_Config2__ApplicationName__c
                                                FROM Apttus_Config2__ApplicationFeature__c
                                                WHERE Apttus_Config2__ApplicationName__c = 'CPQ'
                                                AND Name = 'Cart Page'
                                                LIMIT 1];
 
    List<Apttus_Config2__SettingGroup__c> cartViewsSettingGroups = [SELECT Id,Name
                                             FROM Apttus_Config2__SettingGroup__c
                                             WHERE Name = 'Cart Views'
                                             LIMIT 1];
 
    // Create the new Cart Views Setting Group only if the Cart Page Application Feature exists and the Cart View Setting Group DOES NOT exist
    if (cartPageAppFeatures != null
        && cartPageAppFeatures[0] != null
        && nullOrEmpty(cartViewsSettingGroups)
        ) {
             
        Apttus_Config2__SettingGroup__c newCartViewsSettingGroup = new Apttus_Config2__SettingGroup__c();
        newCartViewsSettingGroup.Name = 'Cart Views';
        newCartViewsSettingGroup.Apttus_Config2__ApplicationFeatureId__c = cartPageAppFeatures[0].Id;
        newCartViewsSettingGroup.Apttus_Config2__IsCustom__c = false;
        newCartViewsSettingGroup.Apttus_Config2__Sequence__c = 12;
        newCartViewsSettingGroup.Apttus_Config2__DisplayType__c = 'Custom';
        newCartViewsSettingGroup.Apttus_Config2__ConfigFlow__c = 'Default';
 
        insert newCartViewsSettingGroup;
    }   
}
 
/**
 * Post installation script to migrate cartview setting related data into new object model.
 */
public static void migrateCartViewSetting() {
    String nsPrefix = 'Apttus_Config2__';
    List<Apttus_Config2__UserView__c> newCartViewSettings = new List<Apttus_Config2__UserView__c>();
    Integer isProductIdCount = 0;
    List<String> allColumns;
    List<MigrateCartView> allOldData;
    String pinned;
    String viewName;
     
    //
    List<Apttus_Config2__ConfigSettings__c> configSOs = [SELECT Name,
                                                Apttus_Config2__Scope__c,
                                                Apttus_Config2__ViewSettings__c,
                                                Apttus_Config2__Flow__c
                                        FROM Apttus_Config2__ConfigSettings__c 
                                        WHERE Apttus_Config2__Scope__c = 'User'
                                        LIMIT 100];
    for (Apttus_Config2__ConfigSettings__c configSO : configSOs) {
        isProductIdCount =0;
 
        // Deserialize the JSON text stored in viewSettings__c into MigrateCartView data structure.
        allOldData = parse(configSO.Apttus_Config2__ViewSettings__c);
 
        // One record can hold setting data for more than one view. Loop thru all views.
        for (MigrateCartView oldView : allOldData) {           
            allColumns = new List<String>();
 
            // Current design allows max 36 chars for view name. Remaining chars to be truncated below.
            viewName = oldView.viewName.length() > 36 ? oldView.viewName.left(36) : oldView.viewName; 
            newCartViewSettings.add(new Apttus_Config2__UserView__c (Name = viewName,
                                                    Apttus_Config2__Type__c = 'Public',
                                                    Apttus_Config2__Flow__c = configSO.Apttus_Config2__Flow__c,
                                                    Apttus_Config2__GroupBy__c = oldView.GroupByField,
                                                    Apttus_Config2__IsDefaultView__c = oldView.isDefault,
                                                    Apttus_Config2__IsDefaultRecord__c = oldView.isDefault));
 
                // Loop through every column settings
                for(ColumnDO ColumnD : oldView.Columns) {
 
                    //Column pinned value left null to be changed to middle
                    if (ColumnD.Pinned == 'left') {
                        pinned = 'Left';
                    } else     if (ColumnD.Pinned == 'right') {
                        pinned = 'Right';
                    } else {
                        pinned = 'Middle';
                    }
 
                    allColumns.add(ColumnD.FieldName + '|' + ColumnD.Sequence + '|' + pinned);
 
                    // Check whether the current setup contains ProductID field or not
                    if (ColumnD.FieldName == nsPrefix + 'ProductId__r') {
                        isProductIdCount++;
                    }
 
                }
 
                // Add productID if the view doesn't contain
                if (isProductIdCount == 0) {
                    allColumns.add(nsPrefix + 'ProductId__r|1|Left');
                }
 
                // Create customsetting data for column values.
                saveFieldList(viewName, allColumns);
        }
 
        // Flag the processed data and not to migrate in next run.
        configSO.Apttus_Config2__Scope__c = 'Admin';
    }
    if (!nullOrEmpty(configSOs)) {
        update configSOs;
    }
    if (!nullOrEmpty(newCartViewSettings)) {
        insert newCartViewSettings;
    }
}
 
}
CODE


Run the following script manually using the developer console: 

Run this script only after the abovementioned apex class is created successfully in the org.

Savepoint sp = null;
try {
    sp = Database.setSavepoint();
    // Method to create the new Setting Group in New Admin, since Load Defaults will override existing user customizations
    APTS_CreateCartViews.createCartViewsSettingGroup();
     
    // Method to migrate old Cart Views to the New Cart Views data model
    APTS_CreateCartViews.migrateCartViewSetting();
     
} catch (Exception ex) {
    Database.rollback(sp);
    System.debug(ex.getMessage());
}
CODE

Significance of script

In Summer 2018 Release, Cart Views functionality has been enhanced to include Cart Views Admin setup. For more information, see About Cart Views.

The data model for Cart Views has been updated in order to provide better user experience and enable more features.

You have to migrate to new Cart Views for maintaining data that you created before Summer 2018 Release.

Mechanism of script

The script queries all the Cart Views that were created prior to upgrading to Summer 2018 Release and copies the related data over to the new Data Model.

It checks for Unique Name for the migration to ensure that the same Cart View is not migrated more than once.

It creates the new tab called Cart Views under Cart Page in New Admin UI. For more information, see Application Management Settings

Old Cart Views were created by individual users and were accessible to all users. Hence after migration such old Cart Views will be marked as Public, so that all users can access them. However, due to the nature of the new enhanced Cart Views, only admin users can edit the Public Cart Views.