From 0fa65560c43719cecbf31f6134278a5d246b8082 Mon Sep 17 00:00:00 2001 From: Dombi Attila <83396+dombesz@users.noreply.github.com> Date: Tue, 24 Jan 2023 21:37:23 +0200 Subject: [PATCH] Simplify query for CoveringDatesAndDaysOfWeek --- .../scopes/covering_dates_and_days_of_week.rb | 37 +++++++++---------- .../apply_working_days_change_job.rb | 6 +-- 2 files changed, 21 insertions(+), 22 deletions(-) diff --git a/app/models/work_packages/scopes/covering_dates_and_days_of_week.rb b/app/models/work_packages/scopes/covering_dates_and_days_of_week.rb index 8641c216f0..566c45e0de 100644 --- a/app/models/work_packages/scopes/covering_dates_and_days_of_week.rb +++ b/app/models/work_packages/scopes/covering_dates_and_days_of_week.rb @@ -61,7 +61,6 @@ module WorkPackages::Scopes::CoveringDatesAndDaysOfWeek work_packages.start_date IS NOT NULL OR work_packages.due_date IS NOT NULL ) - ORDER BY work_packages.id ), -- coalesce non-existing dates of work package to get period start/end work_packages_periods AS ( @@ -70,26 +69,26 @@ module WorkPackages::Scopes::CoveringDatesAndDaysOfWeek GREATEST(work_package_start_date, work_package_due_date) AS end_date FROM work_packages_with_dates ), - -- expand period into days. - work_packages_expaned_periods AS ( - SELECT id, generate_series( - work_packages_periods.start_date, - work_packages_periods.end_date, - '1 day') AS dates, - -- limit to 7 days (more would be useless). - extract(isodow from generate_series( - work_packages_periods.start_date, - LEAST( - work_packages_periods.start_date + 6, - work_packages_periods.end_date - ), - '1 day') - ) AS dow - FROM work_packages_periods + -- All days between the start date of a work package and its due date + covered_dates AS ( + SELECT + id, + generate_series(work_packages_periods.start_date, + work_packages_periods.end_date, + '1 day') AS date + FROM work_packages_periods + ), + -- All days between the start date of a work package and its due date including the day of the week for each date + covered_dates_and_wday AS ( + SELECT + id, + date, + EXTRACT(isodow FROM date) dow + FROM covered_dates ) -- select id of work packages covering the given days - SELECT id FROM work_packages_expaned_periods - WHERE dow IN (:days_of_week) OR dates IN (:dates) + SELECT id FROM covered_dates_and_wday + WHERE dow IN (:days_of_week) OR date IN (:dates) SQL sanitize_sql([sql, { days_of_week:, dates: }]) diff --git a/app/workers/work_packages/apply_working_days_change_job.rb b/app/workers/work_packages/apply_working_days_change_job.rb index 1ac855466e..2a262735ec 100644 --- a/app/workers/work_packages/apply_working_days_change_job.rb +++ b/app/workers/work_packages/apply_working_days_change_job.rb @@ -71,7 +71,7 @@ class WorkPackages::ApplyWorkingDaysChangeJob < ApplicationJob def applicable_work_package(previous_working_days, previous_non_working_days) days_of_week = changed_days(previous_working_days).keys - dates = changed_non_working_days(previous_non_working_days).keys + dates = changed_non_working_dates(previous_non_working_days).keys WorkPackage .covering_dates_and_days_of_week(days_of_week:, dates:) .order(WorkPackage.arel_table[:start_date].asc.nulls_first, @@ -87,7 +87,7 @@ class WorkPackages::ApplyWorkingDaysChangeJob < ApplicationJob (previous ^ current).index_with { |day| current.include?(day) } end - def changed_non_working_days(previous_non_working_days) + def changed_non_working_dates(previous_non_working_days) previous = Set.new(previous_non_working_days) current = Set.new(NonWorkingDay.pluck(:date)) @@ -104,7 +104,7 @@ class WorkPackages::ApplyWorkingDaysChangeJob < ApplicationJob def set_journal_notice(updated_work_package_ids, previous_working_days, previous_non_working_days) day_changes = changed_days(previous_working_days) - date_changes = changed_non_working_days(previous_non_working_days) + date_changes = changed_non_working_dates(previous_non_working_days) journal_note = journal_notice_text(day_changes, date_changes) WorkPackage