FIX: resets pending automations only if necessary (#26685)

Prior to this fix, any change to an automation would reset `pending_automations`, now we only do it if any value related to recurrence (start_date, interval, frequency, execute_at...) has been changed.

It means that any trigger creating `pending_automations` now needs to manage them in the `on_update` callback.
This commit is contained in:
Joffrey JAFFEUX
2024-04-19 14:23:57 +02:00
committed by GitHub
parent 5021f8a7da
commit bf715c8235
5 changed files with 152 additions and 15 deletions

View File

@ -3,11 +3,17 @@
DiscourseAutomation::Triggerable.add(DiscourseAutomation::Triggers::POINT_IN_TIME) do
field :execute_at, component: :date_time, required: true
on_update do |automation, metadata|
# prevents creating a new pending automation on save when date is expired
execute_at = metadata.dig("execute_at", "value")
if execute_at && execute_at > Time.zone.now
automation.pending_automations.create!(execute_at: execute_at)
on_update do |automation, fields, previous_fields|
execute_at = fields.dig("execute_at", "value")
previous_execute_at = previous_fields&.dig("execute_at", "value")
if execute_at != previous_execute_at
automation.pending_automations.destroy_all
# prevents creating a new pending automation on save when date is expired
if execute_at && execute_at > Time.zone.now
automation.pending_automations.create!(execute_at: execute_at)
end
end
end
end

View File

@ -13,12 +13,27 @@ module DiscourseAutomation
{ id: "year", name: "discourse_automation.triggerables.recurring.frequencies.year" },
]
def self.setup_pending_automation(automation, fields)
automation.pending_automations.destroy_all
def self.setup_pending_automation(automation, fields, previous_fields)
start_date = fields.dig("start_date", "value")
interval = fields.dig("recurrence", "value", "interval")
frequency = fields.dig("recurrence", "value", "frequency")
return unless start_date = fields.dig("start_date", "value")
return unless interval = fields.dig("recurrence", "value", "interval")
return unless frequency = fields.dig("recurrence", "value", "frequency")
# this case is not possible in practice but better be safe
if !start_date || !interval || !frequency
automation.pending_automations.destroy_all
return
end
previous_start_date = previous_fields&.dig("start_date", "value")
previous_interval = previous_fields&.dig("recurrence", "value", "interval")
previous_frequency = previous_fields&.dig("recurrence", "value", "frequency")
if previous_start_date != start_date || previous_interval != interval ||
previous_frequency != frequency
automation.pending_automations.destroy_all
else
return
end
start_date = Time.parse(start_date)
byday = start_date.strftime("%A").upcase[0, 2]
@ -82,11 +97,19 @@ DiscourseAutomation::Triggerable.add(DiscourseAutomation::Triggers::RECURRING) d
required: true
field :start_date, component: :date_time, required: true
on_update do |automation, fields|
DiscourseAutomation::Triggers::Recurring.setup_pending_automation(automation, fields)
on_update do |automation, fields, previous_fields|
DiscourseAutomation::Triggers::Recurring.setup_pending_automation(
automation,
fields,
previous_fields,
)
end
on_call do |automation, fields|
DiscourseAutomation::Triggers::Recurring.setup_pending_automation(automation, fields)
on_call do |automation, fields, previous_fields|
DiscourseAutomation::Triggers::Recurring.setup_pending_automation(
automation,
fields,
previous_fields,
)
end
enable_manual_trigger