Simplify query for CoveringDatesAndDaysOfWeek

pull/11854/head
Dombi Attila 2 years ago
parent 8a167b97d1
commit 0fa65560c4
  1. 37
      app/models/work_packages/scopes/covering_dates_and_days_of_week.rb
  2. 6
      app/workers/work_packages/apply_working_days_change_job.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: }])

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

Loading…
Cancel
Save