handlers.computed_field_handler

class ComputedFieldHandler(handlers.eventhandler.EventHandler):

Watch fields for value changes, and when one of the watched fields changes, set another field to a computed value. This allows for lookups and mappings between multiple fields.

Configuration:
fs_types: list of fact sheet types, where this handler should run
depends_on_fields: a list of fields to be monitored for changes; if any of these fields change, the lookup will be performed
field_name: name of the field to be set
update_when_empty: also set the value of field_name when no new value or an empty value was computed
value: list of definitions for the new value lookup

Each entry in value is an object containing two fields:
value: the value to be set if the condition is true
condition: a string of Python code, determining whether this value should be used. The current fact sheet is passed as local variable fs, and you can use any Python code to compute a value of True or False

Example:

{
    "fs_types": ["Application"],
    "depends_on_fields": ["functionalSuitability", "technicalSuitability"],
    "field_name": "lxTimeClassification",
    "update_when_empty": False,
    "value": [
        {
            "condition": "fs['functionalSuitability'] == 'unreasonable' and fs['technicalSuitability'] == 'inappropriate'",
            "value": "Eliminate"
        }
    ]
}

This would set the TIME classification to “Eliminate”, when functional fit and technical fit are set to their lowest values, and would not update in any other case.

name = 'Computed Field'
description = 'Update a field depending on values in other fields, and select on computed conditions'
conditions = {'event_types': ['FactSheetFieldUpdatedEvent']}
supports_initial_sync = True
config_template = {'fs_types': ['Application'], 'depends_on_fields': ['functionalSuitability', 'technicalSuitability'], 'field_name': 'lxTimeClassification', 'update_when_empty': False, 'value': [{'condition': "fs['functionalSuitability'] == 'unreasonable' and fs['technicalSuitability'] == 'inappropriate'", 'value': 'Eliminate'}]}
def data_requirements(self):

Declare the exact fact-sheet data this handler needs, so the webhook event loop (process_event in workspace/views_module.py) can load a single lean FastFactSheet per event instead of the full fact sheet.

Return a dict: { "fields": [], "relations": [], "subscriptions": bool, # True if handle() reads fs["subscriptions"] "tags": bool, # True if handle() reads tags / has_tag() "documents": bool, "acls": bool, "completion": bool, # True if handle() reads fs["completion"] "base_fields": [], # optional; omit/None = full # default base field set. A list restricts the # base scalars to just those (id and type are # always loaded). Advanced opt-in for max speed. } Fields referenced by this handler's trigger are folded in automatically by the event loop (into "fields"), so only declare what handle() itself needs on top of them.

Return None (the default) to signal "requirements cannot be declared statically" - e.g. handlers that exec/eval config-supplied code. The event loop then loads the full fact sheet for that event, so correctness is always preserved. This is a standalone hook (deliberately not tied to the initial_sync_* hooks, which are slated to migrate onto it later).

def handle(self, event, fs, **kwargs):

Called automatically whenever a FactSheetUpdated event comes in via webhook.

def initial_sync_event(self, fs):