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.
- In Setup, find and select Custom Settings.
- On the custom settings, locate the CPQ Configuration Setup and click Manage.
- Find and select ExtendedLineNumberModeEnabled setting.
- Select the checkbox to enable the seven-digit numbering format.
- Save the changes.
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.

