My question is basically the same as question 289297, if I correctly understand its OP's intent. I am posting my own in the hope of giving the issue more visibility, and also because it is not an answer to that question.
Let me first describe what I am trying to do: My package is planned to be an extension to the built-in Opportunity
to Quote
syncing feature. It contains two custom objects (tables), one for the Opportunity
to Quote
field mappings, the other for the OpportunityLineItem
to QuoteLineItem
field mappings. Both of these tables have two fields where the user can enter the names of the fields he wants synced. The user's entries are validated in a before-trigger that makes sure the two fields are compatible.
to be compatible,
- a field must not be synced by the built-in feature: hard-coded list determined by experiment.
- a field must not be a formula field:
DescribeFieldResult.isCalculated()
.- a field must not be an auto number field:
DescribeFieldResult.isAutoNumber()
.- a field must not be an
ADDRESS
field.- both fields must have the same nillability:
DescribeFieldResult.isNillable()
.- both fields must have the same type:
DescribeFieldResult.getType()
.- if the type is
REFERENCE
, both fields must refer to the same (set of) objects:DescribeFieldResult.getReferenceTo()
.
and, last but not least:
- both fields must be updateable by the code that keeps the mapped fields in sync when the user inserts or updates a row in one of the four entities involved.
This last item is where my problem is. DescribeFieldResult.isUpdateable()
does not help here, because its results are user-dependent, even when called from the method of a class marked without sharing
that executes in a trigger context. Also, the isUpdateable
returns false
in cases where demonstrably the trigger code can successfully update a field to keep it in sync with the corresponding field of the partner row.
tentative and partial answers to my problem, always assuming the the trigger context:
- a custom field, whether in a custom object or in a standard object, is always updateable: hard to verify; easy to implement in code, should this be correct.
- a standard object's standard field is updateable if the Standard Object Reference mentions
Update
in the field'sProperties
: hard to verify, and even, should this be correct, hard to use in code. A hard coded white list does not look like an attractive solution. - a standard object's standard field is not updateable if the field's
Set Field-Level Security
page contains a non-editable checkmark in all rows: if correct, there must be a programmatic way that determines the non-updateability of the field - said page does it. - in a comment to the above mentioned question 289297, @SarcasticSully mentions that "Admin cannot remove update access to any required field": if correct, how does one test for the required field property? is non-nillability the same as being required?
BTW: A possible, though not very clean, way of testing the updateability of a field could be: Start a sub-transaction (is this possible in Apex?), create a row of the object in question and update the field, then roll back the sub-transaction while catching exceptions: now really, lets be serious!
Any ideas or hints will be extremely welcome!
After thinking some more about my question
I have abandoned the idea of deciding in code in a general way whether a given field will be writeable (IsUpdateable()
) in the trigger.
- As far as I can see custom fields (as in
MyCustomField__c
) can always be written to in the trigger, and are therefore usable as synced fields, as long as the conditions enumerated above are met. - Of standard fields there are not many in the context of syncing Quotes and Opportunities that could usefully and meaningfully be synchronized in addition to the fields that the built-in implementation synchronizes.
- In all cases suitable tests should allow one to decide whether a given field can be made to sync with a proposed partner field.