How to write automation script trigger for this case

Hi there
I need help with defining a trigger for this use case

I have a module called Customer in the crm namespace
and the module has a field called manager of type string

so I want to have a trigger run after updating the record of that module if and only if the field has changed
could be

  • from null to a value
  • or from a value to another value
  • or from value to null

thanks

here is my failed attempt

  triggers ({ after }) {
    return after('update').for('compose:record')
      .where('namespace', 'crm')
      .where('module.handle', 'Customer')
      .where('record.values.manager', '!=', 'oldRecord.values.manager')
  }

this wouldn’t work because it didn’t recognize the oldRecord field

if anyone concerns why wouldn’t I handle it from the script itself?
the Customer module got updated frequently and my module has around 50K of records
and the change a field manager would change is less than 5%
so if I handle it from the script, I would end 95% of the triggers!!

this cause unfortunate behavior of the server (please relate to this)

Here is a list of things you can use in your triggers Resource constraints :: Corteza Docs

For your case, what I would do is create a new internal/system field (checkbox) called sys_should_run with a value expression in the lines of (not tested; written from the top of my head) old.values.SOMETHING == new.values.SOMETHING (you’ll need to cover the case when it is being created since old doesn’t exist then).
Your trigger would then check if that field is set or not; if it is, that SOMETHING field changed and the script should run.

@tjerman thank you for your suggested approach

so I can’t use record.values.* with dynamic values?
for example oldRecord

would that be improved later? do you have plans for it??

thanks again

You can use the values outlined in that document I’ve linked above.

None of us have thought about adding it so not as of now.
I’ll open up a discussion for it so we can discuss it, but I don’t see why we wouldn’t add it at some point since it makes sense to me.

could you please help regarding this?
here is my failed attempt

old? old.values.manager != new.values.manager: false

hey @tjerman, I think the old object has an issue (I’m using 2022.3.1)

to reproduce the error:
I created a field called test
the field has an expression like this old.values.customer_id
the field customer_id already exists in the record (not empty)
when I edited the record I got this error
Could not update record: check error messages on the form

when I use new object everything is fine

To handle the case where old is not defined, you can do something along the lines of:

(old ?? false) ? old.values.computed +  new.values.base: new.values.base

@tjerman I think I have unexpected behavior (or bug)

to reproduce the issue

  • I created a new module
  • I created a Checkbox field called is_update with the following expression (old ?? false) ? true : false
  • I created a Checkbox field called is_create with the following expression (old ?? false)? false: true

the result:
when I create a new record or update an existing one the is_create field is always true and is_update field is always false

so this expression (old ?? false) always returns false which means the old field is always null even with update operation

@tjerman any luck here?

Hi.
Any news for this case ?
Are you sure ( old ?? false) is evaluated correctly as a boolean expression ?

If old record is missing then it is clear (old ?? false) will return FALSE
but
If old record exists (old ?? false) will return old record. I don’t know if old record means TRUE

hi @CezarRadan thanks for sharing your results

I think yes it will consider old as true
if I tried it in the workflow I would get the right results

Just checked it out and can confirm this is a bug.

1 Like

Hi @tjerman, how can we proceed from here?

Hmm, nothing sane comes to mind (besides checking the value in a workflow/script) so let’s wait for this to get patched up.
You can expect it to get patched out the week after next (that’s when the next batch of patch releases is scheduled for).

Better yet, it might already be available tomorrow (if the patch goes through the QA ok, the fix was fairly trivial).

2 Likes

hey guys, I can confirm the issue has been solved in 2022.3.3 version

and regarding my use-case here the expression
(old??false) ? ((old.values.manager!=new.values.manager)?true:false): ((manager??false)?true:false)

so @tjerman so my original question
and I can define a trigger runs after this expression is evaluated to true … for example

  triggers ({ after }) {
    return after('update').for('compose:record')
      .where('namespace', 'crm')
      .where('module.handle', 'Customer')
      .where('record.values.field_expression', '1')
  }

this will help me register a trigger when a specific field has changed

do you have a better workaround to register automation for a specific event?
do you have a plan to make domain fields registered as constraints in a trigger?

I can give examples for the second question

Refer to here in regards to defining trigger constraints, and here in regards to what constraints you can use based on the resource.

I’m not sure in regards to what this is; being able to check if old value equals the new value? Not as of now but I’ll open up a discussion if we want to add it (I’d imagine we would since it does make sense to me).

Please explain. If you want to use module fields as constant values then that could already be used; see here

We currently don’t have any automation triggering related tasks in our pipeline so I can probably answer that we’re not planning on doing it.

I already checked the docs and I can use the module fields as constraint but it will be static
let me explain more

I can define a constraint on a module field like this
.where('record.values.is_customer', '1')
why this is static? because I hardcoded the value to be 1

  • what if I want an expression instead of hardcoding the value … for example
    if I wanna run the trigger if the record has updated and the field value has changed (no the same as the old value) for example: if a field called is_customer has changed from true to false or from false to true. I would assume I can do something like this
    .where('record.values.is_customer', '!=', 'oldRecord.values.is_customer') (tried this but it didn’t work)
  • what if I want to run a trigger if specific number field is an even number
    .where('record.values.number_of_orders%2', '0')

hope it’s clear

It’s clear but the matching logic doesn’t support expressions so you can’t do this at the moment. This part of the system was defined quite a while ago and we haven’t yet had the need to extend it.
I’ll kick up a discussion around this to see what we want to do here.

In the meantime either check the value inside the script’s code or use the field expression trick.

1 Like