Context & Motivation
Currently, field requirements for usability indicators and red flags are defined as a mix of code logic (e.g. when we choose which set of fields to use as a proxy for buyer or award value), and a dictionary with a set of required fields for each indicator. See component_setup_usability for a reference.
This might be hard to maintain and follow, as conditions for choosing proxy fields are separated from indicator definitions.
What we can do instead is define requirements for indicators using DSL rules.
Proposed Solution
For each indicator (and red flag), define a rule using nested structure where:
{"all": [ ... ]} means all sub-requirements are mandatory (logical AND)
{"any": [ ... ]} means at least one sub-requirement is needed (logical OR)
Combine rules into one and rewrite the 'usability checks' function to take that dictionary as an input.
Example
U066 'Percent of contracts that exceed budget' can be calculated using either planning or tender values.
Currently it is expressed in two parts
Selection of a proxy fields for 'budget':
# U066, U067
if "planning/budget/amount/amount" in fields_list and "planning/budget/amount/currency":
planning = ["planning/budget/amount/amount", "planning/budget/amount/currency"]
elif "tender/value/amount" in fields_list and "tender/value/currency":
planning = ["tender/value/amount", "tender/value/currency"]
else:
planning = ["planning/budget/amount/amount", "planning/budget/amount/currency"]
Construction of an indicator requirements:
{
"Percent of contracts that exceed budget": [
[
"U066"
],
[
"ocid",
"contracts/status",
"contracts/value/amount",
"contracts/value/currency",
"*planning"
]
]
}
Alternatively it can be expressed as a rule:
U066_REQUIREMENT = {
"all": [
"ocid",
"contracts/status",
"contracts/value/amount",
"contracts/value/currency",
{"any": [
{"all": ["planning/budget/amount/amount", "planning/budget/amount/currency"]},
{"all": ["tender/value/amount", "tender/value/currency"]}
]}
]
}
Benefits
Defined this way, rules should be more readable and maintainable. It should be easy to add new requirements and conditions if needed.
Context & Motivation
Currently, field requirements for usability indicators and red flags are defined as a mix of code logic (e.g. when we choose which set of fields to use as a proxy for buyer or award value), and a dictionary with a set of required fields for each indicator. See component_setup_usability for a reference.
This might be hard to maintain and follow, as conditions for choosing proxy fields are separated from indicator definitions.
What we can do instead is define requirements for indicators using DSL rules.
Proposed Solution
For each indicator (and red flag), define a rule using nested structure where:
{"all": [ ... ]}means all sub-requirements are mandatory (logical AND){"any": [ ... ]}means at least one sub-requirement is needed (logical OR)Combine rules into one and rewrite the 'usability checks' function to take that dictionary as an input.
Example
U066 'Percent of contracts that exceed budget' can be calculated using either planning or tender values.
Currently it is expressed in two parts
Selection of a proxy fields for 'budget':
Construction of an indicator requirements:
Alternatively it can be expressed as a rule:
Benefits
Defined this way, rules should be more readable and maintainable. It should be easy to add new requirements and conditions if needed.