We have Opportunity with a custom checkbox property "Locked__c". While this value is set to true (never mind how), it should be impossible to change any value on the Opportunity.
The Opportunity has a detail record "Requirement__c" with a checkbox property "Is_Completed__c".
The Opportunity has two roll-up summary fields "Requirement_Count__c" and "Open_Requirement_Count__c", and as you might expect, adding or modifying these cascades into an update of the Opportunity, which therefore executes the Opportunity validation rules.
It must be possible to add and modify "Requirement__c" records even when the Opportunity is locked and we've gotten very close to the requirement with a validation rule that checks:
( (NOT( Locked__c )&&NOT(PRIORVALUE(Locked__c)))&&( && NOT(OR( ISCHANGED(Requirement_Count__c), ISCHANGED(Open_Requirement_Count__c) )) )
But there is a corner case where this rule blocks changes when we don't want it to.
If the user simultaneously (re)opens and closes the same number of Requirement__c, the validation rule will reject the changes.
The validation has no way to distinguish between which Requirement__c are opening and closing.
I thought about trying to make this into a trigger, but as a trigger on Opportunity, at the time this executes, there would (so far as I know) also be know way of knowing the historic states of the Requirement__c, so we still can't make the distinction.
I also thought about adding a "Was_Completed__c" property to the "Requirement__c", but it seems to me that we'd need to simultaneously update this every time each "Requirement__c" related to the same Opportunity was updated, and we'd need to do this in a bulkified way, and somehow without recursion causing SFDC to throw a tantrum. I'm not sure whether that is possible, but it seems a lot of work to deal with the corner case....
Is there a more elegant/practical way to accomplish this?