LOL. OK, Zendesk did not like my HTML code. Formatting options on this forum suck :-)
For evaluation criteria in a SWR, I need to change the Clarizen logical disjunction (https://en.wikipedia.org/wiki/Truth_table#Logical_disjunction_.28OR.29) so that the clause will return False if just one sub-clause returns false.
Standard Clarizen logic issue for True/False:
Total result for True && True && False: False.
Total result for True || True || False: True .
My rule may have these sub clause results:
Is Current not Archived:True
Is Parent not Archived: True
Is Parent Project not Archived: False
And here I need Clarizen to return False and not True.
((Not($Phase='Archived')) || (Not(IsNull($Parent)) && Not($Parent.Phase='Archived')) || (Not(IsNull($Parent)) && Not($Project.Phase='Archived')))
How can I get False returned if just <em>one</em> sub-clause is false?
Please sign in to leave a comment.
I am not sure if there's a better way (since there is not XOR) to do that but since you have only 3 conditions you can try
(Condition1=FALSE && Condition2=TRUE && Condition3=TRUE) || (Condition1=TRUE && Condition2=FALSE && Condition3=TRUE) || (Condition1=TRUE && Condition2=TRUE && Condition3=FALSE)
In addition PLEASE use <>NULL and not IsNull and as IsNull is very heavy in resource and using this 6 times in the statement can impact performance.
Hi Tamir, thanks for your response - you're a great help.
Maybe I was a bit unclear (or maybe I don't fully grasp your answer :-) ), but any of the conditions could be true or false - I dont know which in advance.
BTW, I was just told by support to use IsNull instead of <>NULL in a different rule (which I have been using so far due to feedback - maybe even you) because <>Null did not work in some instances :-)
Can you please explain again what is the expected result? As far I understood from you the expected result is to get FALSE only if ONE of the three conditions is FALSE - or maybe I'm missing something?
Regarding the difference between isNull and =/<>NULL your statement is indeed correct, since isNull is going to directly to the DB and checks it, therefore it is more reliable. If the frequency of the rule I would consult our chief architect regarding optimization of the the criteria.
When we're "done, done" with WIs we mark them with Phase = 'Archived' (completed WI be be reopened again).
This can ither be done to a single WI: (Not($Phase='Archived')
The parent of the work item so that this branch of the project is done: (Not(IsNull($Parent)) && Not($Parent.Phase='Archived'))
Or at the top level (project): (Not(IsNull($Parent)) && Not($Project.Phase='Archived'))
If any level in the hiearchy above the current WI is 'archived' (since this flag is "Inherited" to children), this rule should not run.
It just to save processing on the server (if I manage to fix the validation rule in another thread).
Please try the following:
$Phase<>'Archived' && Catch(($Parent.Phase,NULL)<>'Archived' && Catch($Project.Phase,NULL)='Archived'
However in terms of the hygiene of the flag I would recommend inheriting that flag with a WR on the WI level.
Your rule should run upon created/edited with eval of isChanged($Phase)
The action should be update field on the phase on the children. In addition check the box of "allow triggering additional workflow rules" on the top of the rule editor.
Please let me know if it makes sense.
I tested your suggestion, but I am sorry to report, it does not work:
To be honest, I am a bit puzzled why the validation rule is hit in all cases, since normally, updating a custom field on an item with a workflow rule does not trigger a validation rule / gives problems with e.g. "completed" state.
Regarding the flag, the reason why I have done done it without propagating the flag is that it should easy to set/unset and to limit the amount of WRs we have (since I already think we have too many!).
Otherwise I need to make 2 WRs to handle this, whereas it has worked so far with 1 validation rule. The SWR should run once a day so there is no need for the "allow triggering".
I would use the CurrentUser as the first criteria as Clarizen reads conditions from left to right. In addition, it is very hard for me to debug it without seeing the instance. I would recommend to implement the WR that populates the Phase down and reach out to your CSM for additional support.
OK, regarding the validation rule (which is actually the other post) and that you do not have any further suggestions for implementing an "XOR" rule.
Just an example of how to perform boolean operation as I think you are trying to do. This depends on bool being cast to int where true = 1 and false = 0.
Not(Not(X) + Not(Y) + Not(Z) = 1)
This will return a boolean False if and only if one of X, Y, or Z are False
If the automatic casting does not work you might try a logical expression like this:
Not((If X then 0 else 1)+(If Y then 0 else 1)+(If Z then 0 else 1)=1)
Hope this helps
Thanks. There can be more than one false - but as long as there is at least 1, it should fire. If I make the falses 1 I could check for >0.
Daniel, you did it!
(If((Not($Phase='Archived')),0,1) + If((Not(IsNull($Parent)) && Not($Parent.Phase='Archived')),0,1) + If((Not(IsNull($Parent)) && Not($Project.Phase='Archived')),0,1))>0
- returns "True" if none of the levels are set as Archived!
If a level is archived, its value is set to 1 and the final check is if the sum is greater than 0, there must be at least one False.
Glad I could help, Peter. Just out of curiosity, did you try it without using the If statements. Wondering if the boolean will actually cast themselves to integers when used in an addition.
No I did not. I just went with what made sense to me. Also I needed to check if at least 1 was false so I needed a value on False.