I have a growing number of requests to enforce mandatory time entry, but specific to certain groups, certain states, and other attributes of the underlying item.
For example, we currently mandate that time entries exist before we can move on to a "fixed" state. By doing that we ensure that some time is entered, but the approach boldly assumes without proof that the time entered includes the actual fixing. Person "A" might put in a time entry for diagnosis, and then person B might fix and forget to enter time. Mandating that time entries exist generically doesn't help us catch person B's omission.
Additional requests include mandating entry of time by QA team members for verification of fixes. Of course with our "time entries exist" mandate already met by the time of fix, it is too late to use that generic mandate again for a subsequent workflow state.
Before I go and invent a super-cool multi-purpose time-entry-checking trigger script I am sharing this with the community in the fond hope that I am not the first to think of it. All advice and discussion are welcome. I am glad to consider other folks' requirements and share the resulting useful code.
I have not had to code for exactly that scenario, however we do have similar scenarios with complex logic that do not lend themselves to fitting event trigger rules or query filters. You may find the generic approach useful even if it doesn't exactly fit.
In our scenario, the requirement was to send a nightly email whenever the actual hours logged against an item broke a certain threshold of the estimate (e.g. 90% of the estimate).
After experimenting with triggers running through the logic and setting flags on the item, I found that running through the logic in a trigger whenever time was entered against an item was too performance intensive to be practical.
What I ended up doing instead was using multiple static calculated fields to determine the threshold values for each item and to indicate if the item had surpassed the threshold, then querying on those fields as part of a scheduled job to actually send the email.
So in my case there would have been a new field "90 Threshold" = 0.9 * "Estimated Hours" and another field "Broke 90 Threshold" = "90 Threshold" < "Actual Hours"
Then my query found all the items where "Broke 90 Threshold" = true and the email was not yet sent.
For your specific example, you might use some of the time entry calculation functions, such as countTimeEntryByGroup("QA") and sumTimeEntryByState("Diagnosis"), in calculated fields to isolate exactly the conditions you want to enforce in your trigger rules, then run triggers based on those new fields.
So if you had a field TimeEnteredByQA = countTimeEntryByGroup("QA") > 0, then you could run an abort trigger if the state changes from Fixed to Verified and TimeEnteredByQA is false.
One nice point about this approach is that if you find yourself reusing the flags for multiple states and at some point in the future you need to change the flag definition, you just need to change the field calculation in one place rather than update the logic in multiple triggers.
The main caveat with this approach is that I believe the calculated field value is not updated until after the PRE/POST trigger executions are complete, so you cannot use the change of a calculated field value to fire off rule based triggers.
If anyone can confirm when in the PRE/POST event trigger cycle the static calculated field values are updated on the item, I would be grateful.