When a Salesforce org tracks prospects across both the Lead and Opportunity objects, a common requirement is a unique prospect number that follows the record through its lifecycle. The number must be generated at whichever stage the record first enters the system, transferred cleanly on conversion, and never duplicated — even when records are created out of sequence.
This pattern was surfaced during a [1] Salesforce review and implemented by the Twistellar development team.
Out-of-the-box Salesforce does not provide a shared auto-number sequence across object types. A naive implementation that generates a number only on the Opportunity object breaks down in two scenarios:
The result is either duplicate numbers, gaps, or manual workarounds.
| Scenario | Where number is generated | What happens on conversion |
|---|---|---|
| Lead created → converted to Opportunity | Lead object | Number is carried over to the Opportunity; no new number is generated |
| Opportunity created directly (no Lead) | Opportunity object | Number is generated at Opportunity creation as a fallback |
This ensures every record in the system has exactly one prospect number, regardless of entry point.
The number must be unique across both objects. This requires a shared counter or sequence mechanism — not separate auto-number fields on each object, which would produce collisions (e.g., Lead #1042 and Opportunity #1042 coexisting).
Implementation options include:
- A custom metadata or custom setting storing the last-used sequence value, incremented atomically via Apex
- A dedicated custom object acting as a sequence table (one record, one counter field, updated with row-level locking)
Salesforce's standard lead conversion does not automatically map custom fields unless a lead field mapping is configured (Setup → Object Manager → Lead → Map Lead Fields). The prospect number field on Lead must be mapped to the corresponding field on Opportunity so the value is copied at conversion time.
The Opportunity-side automation should check: if a prospect number already exists on this record, do not generate a new one. This prevents overwriting a transferred number.
if isBlank(Prospect_Number__c)) must fire on both direct creation and conversion paths.At Quarra Stone, the prospect number is also used as the folder name key when creating project folders on their network drive (iDrive, managed by Veith Consulting). The folder creation automation depends on the prospect number being present and stable at the moment the Opportunity is saved. This makes the transfer-on-conversion logic especially critical — the number must not change after the folder is created.
See [2] for the related pattern.