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
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