Extending QuoteX Cloning Logic

Published on May 8, 2026 QuoteX


Extending QuoteX Cloning Logic

Technical Design Guide

Objective

Goal: Enable cloning of custom (out-of-namespace) fields during the QuoteX cloning process for both Parent Quotes and Timeline (Child) records.


Scope: This approach applies only to custom fields you have added to the PSC Quote object. Native managed-package fields are handled internally by QuoteX and are outside scope.

Problem Statement

The QuoteX managed package cloning functionality only recognizes fields within its own namespace. Custom fields added to the PSC Quote object are ignored during the native clone operation. The native process also provides no direct hook to map these fields, so a workaround is required to identify the Source Record ID during the before insert execution context.

Logic & Workaround Strategy

To map custom fields, capture the Source Record ID, retrieve its custom field values, and inject them into the new record. Two existing fields act as temporary pass-through containers for the Source ID:

  1. Parent Quotes: the deprecated Version Notes field.
  2. Timelines (Child Quotes): the standard Name field (pre-populated by the package as "Only for Timeline").

Record Identification Criteria

Record Typepsce__Is_Specific_To_Timeline__cpsce__Parent_Estimate__cIdentity Container
Parent QuoteFalsenullVersion_Notes__c
Timeline (Child)TrueNOT nullName

Execution Logic (Apex Trigger / Flow)

Phase A: Before Insert (Data Mapping)

  1. Parent Quotes:
  2. Check if Version_Notes__c contains a valid Salesforce 18-digit ID.
  3. If valid, query the Source Quote record for all relevant custom field values.
  4. Map these values to the current record instance (Trigger.new).
  5. Timeline Records:
  6. Check if the Name field contains a valid Salesforce 18-digit ID.
  7. If valid, query the Source Timeline record for all relevant custom field values.
  8. Map these values to the current record instance (Trigger.new).

Phase B: After Insert (Field Cleanup)

To ensure data integrity and prevent the pass-through IDs from remaining in the system:

  1. Parent Quotes: Update Version_Notes__c with the ID of the newly created record (or nullify if preferred).
  2. Timeline Records: Update the Name field with the ID of the newly created record to overwrite the source ID reference.

Trigger Summary

Trigger EventConditionAction
Before InsertVersion_Notes__c contains valid record IDFetch source Quote, copy custom field values to new record
Before InsertName = valid record ID and Timeline condition metFetch source Timeline, copy custom field values to new record
After Insertpsce__Is_Specific_To_Timeline__c = falseSet Version_Notes__c = new record ID (via DML update)
After Insertpsce__Is_Specific_To_Timeline__c = trueSet Name = new record ID (via DML update)

Implementation Notes & Constraints

  1. Namespace Awareness: Ensure the query for custom fields dynamically handles fields outside the psce__ namespace.
  2. SOQL Optimization: When bulk cloning, ensure the Source Record queries are bulkified (collection-based) to avoid governor limits.
  3. Field Deprecation: Version_Notes__c is deprecated as of v1.85 and is safe for re-purposing as a temporary ID container for Parent Quotes.
  4. Timeline Hard-coding: The native package hard-codes the Name field for Timelines; our logic must override this in the After Insert phase to maintain record naming conventions.

Potential Risks & Enhancements

Consider these technical nuances to keep the solution robust:

Recursion Trap: Since you perform an After Insert update on the same object, use static variable recursion control. Do not update Trigger.new directly; create a new instance of the object and update that.


Governor Limits (Bulkification):In Before Insert, collect all IDs from the Version Notes / Name fields first.Run one single SOQL query to get all custom field values for those Source IDs.Map them using a Map<Id, PSC_Quote__c>.Never query inside the loop.


Name Field Sensitivity: Since the standard Name field is used for Timelines, ensure no other automation (auto-numbering, Flows) overwrites the Source ID before your Before Insert logic reads it. Apply this only to Timelines, never to Parent Quotes, because the Parent Quote Name is populated by users.

Knowledge Article Number: KA-00240

View more articles in the knowledge base