Loading
Salesforce now sends email only from verified domains. Read More
Get Started with Communications, Media, and Energy & Utilities (CME)...
Table of Contents
Select Filters

          No results
          No results
          Here are some search tips

          Check the spelling of your keywords.
          Use more general search terms.
          Select fewer filters to broaden your search.

          Search all of Salesforce Help
          Configure Extended Asset Line Numbering for Large Accounts

          Configure Extended Asset Line Numbering for Large Accounts

          Enable the extended line numbering feature to support large-scale asset management. This enhancement increases ‌root asset capacity from 9,999 to 9,999,999, ensuring unique identifiers for high-volume accounts and preventing duplicate numbering during assetization.

          Required Editions

          Available in: Lightning Experience
          Available in: Enterprise, Unlimited, Performance, and Developer Edition.
          User Permissions Needed
          Set of permissions required Configuring Extended Asset Line Numbering: CME Managed Package

          Before you begin, create the provided batch class and include the appropriate namespace where required. After the code is final, run the batch class to begin the process.

          Ensure to fulfill these conditions while you execute the script:

          • Set UseAssetReferenceIdForParentAndRoot to True.
          • Set ExtendedLineNumberModeEnabled to True.
          • The value of AssetReferenceId__c is unique for each account.
          • Run the script within the context of a single account.
          public with sharing class DedupAssetLineNumberBatchJob implements Database.Batchable<SObject>, Database.Stateful {
              private Set<String> usedRootLineNumbers = new Set<String>();
              private Integer highestNumericRootLineNumber = null;
              private Id accountId;
              public DedupAssetLineNumberBatchJob(Id accountId) {
                  this.accountId = accountId;
              }
              public Database.QueryLocator start(Database.BatchableContext BC) {
                  return Database.getQueryLocator([SELECT Id, AssetReferenceId__c,NumericRootLineNumber__c, LineNumber__c FROM Asset WHERE AccountId = :accountId AND LineNumber__c != null AND (NOT LineNumber__c LIKE '%.%') ORDER BY NumericRootLineNumber__c desc nulls last]);
              }
          
              public void execute(Database.BatchableContext BC, List<SObject> scope) {
                  dedupAssetLineNumber(scope);
              }
          
              public void finish(Database.BatchableContext BC) {
              }
          
              private void dedupAssetLineNumber(List<SObject> scope) {
                  List<Asset> rootAssetsWithDupilcateLineNumbers = new List<Asset>();
                  for(SObject assetSO : scope) {
                      Asset asset = (Asset)assetSO;
                      String rootLineNumber = asset.LineNumber__c;
                      Integer numericRootLineNumber = Integer.valueOf(asset.NumericRootLineNumber__c);
                      
                      //initialize the highestNumericRootLineNumber
                      if(this.highestNumericRootLineNumber == null) {
                          this.highestNumericRootLineNumber = numericRootLineNumber;
                      }
                      //collect the root assets with duplicate line numbers
                      if(usedRootLineNumbers.contains(rootLineNumber)) {
                          rootAssetsWithDupilcateLineNumbers.add(asset);
                      }
                      usedRootLineNumbers.add(rootLineNumber);
          
                  }
                  this.highestNumericRootLineNumber = renumberAssetsAndChildren(rootAssetsWithDupilcateLineNumbers, this.highestNumericRootLineNumber, usedRootLineNumbers);
              }
            
              private Integer renumberAssetsAndChildren(List<Asset> rootAssetsWithDupilcateLineNumbers, Integer highestNumericRootLineNumber, Set<String> usedRootLineNumbers) {
                  
                  Set<String> assetReferenceIds = new Set<String>();
                  Map<String, String> rootAssetReferenceIdToNewRootLineNumber = new Map<String, String>();
                  for(Asset asset : rootAssetsWithDupilcateLineNumbers) {
                      assetReferenceIds.add(asset.AssetReferenceId__c);
                      highestNumericRootLineNumber ++;
                      String newRootLineNumber = padLeft(highestNumericRootLineNumber);
                      usedRootLineNumbers.add(newRootLineNumber);
                      rootAssetReferenceIdToNewRootLineNumber.put(asset.AssetReferenceId__c, newRootLineNumber);
                  }
                  List<Asset> assetsToRenumber = [SELECT AssetReferenceId__c, RootItemId__c , LineNumber__c FROM Asset WHERE RootItemId__c IN :assetReferenceIds ORDER BY LineNumber__c ASC];
                  
                  for(Asset assetToRenumber : assetsToRenumber) {
                      String newRootLineNumber = rootAssetReferenceIdToNewRootLineNumber.get(assetToRenumber.RootItemId__c);
                      if(assetToRenumber.LineNumber__c.contains('.')) {
                          List<String> rootLineNumberSections = assetToRenumber.LineNumber__c.split('\\.');
                          rootLineNumberSections[0] = newRootLineNumber;
                          assetToRenumber.LineNumber__c = String.join(rootLineNumberSections, '.');
                      }
                      else {
                          assetToRenumber.LineNumber__c = newRootLineNumber;
                      }
                  }
                  update assetsToRenumber;
                  return highestNumericRootLineNumber;
              }
          
              private String padLeft(Integer i) {
                  String str = String.valueOf(i);
          		while (str.length() < 7) {
          			str = '0' + str;
          		}
          		return str;
              }  
          }
          

          Also find the Batch Invocation sample for reference:

          //replace with account Id
          Id accountID = 'someAcountId';
          DedupAssetLineNumberBatchJob dedup = new DedupAssetLineNumberBatchJob(accountId);
          //lower batchSize if governor limits are reached
          Integer batchSize = 200;
          Database.executeBAtch(dedup,batchSize);
          

          The steps to enable the extended line numbering feature.

          1. In Setup, find and select Custom Settings.
          2. On the custom settings, locate the CPQ Configuration Setup and click Manage.
          3. Find and select ExtendedLineNumberModeEnabled setting.
          4. Select the checkbox to enable the seven-digit numbering format.
          5. Save the changes.
          Note
          Note The system renumbers duplicates that use the highest line number for the specific account. It converts only the root portion to a seven-digit format to support extended line numbering such as 10000.0001 becomes 0010001.0001.

          After you enable this setting, you can’t turn it off. This restriction ensures continuous data integrity for your asset records.

          Post-Activation Steps

          Verify API Integration: Check any external systems that parse line numbers. Make sure that they can process the new seven-digit format.

          Test MACD Flows: Perform a "Change" or "Move" operation to verify that the system correctly converts extended asset numbers back to the four-digit format within the cart.

           
          Loading
          Salesforce Help | Article