Commit 5bec56da authored by Mark Chao's avatar Mark Chao

Allow persisting start/due dates and milestone ids

parent 93b05616
......@@ -111,15 +111,13 @@ module EE
alias_attribute(:due_date, :end_date)
def update_dates
if !start_date_is_fixed? || !due_date_is_fixed?
milestone_dates = issues
.joins(:milestone)
.pluck('MIN(milestones.start_date)', 'MAX(milestones.due_date)')
.first
end
milestone_data = fetch_milestone_date_data
self.start_date = start_date_is_fixed? ? start_date_fixed : milestone_data[:start_date]
self.start_date_sourcing_milestone_id = milestone_data[:start_date_sourcing_milestone_id]
self.due_date = due_date_is_fixed? ? due_date_fixed : milestone_data[:due_date]
self.due_date_sourcing_milestone_id = milestone_data[:due_date_sourcing_milestone_id]
self.start_date = start_date_is_fixed? ? start_date_fixed : milestone_dates[0]
self.due_date = due_date_is_fixed? ? due_date_fixed : milestone_dates[1]
save if changed?
end
......@@ -179,5 +177,35 @@ module EE
def compute_due_date
due_date_is_fixed? ? due_date_fixed : due_date_from_milestones
end
def fetch_milestone_date_data
sql = <<~SQL
SELECT milestones.id, milestones.start_date, milestones.due_date FROM milestones
INNER JOIN issues ON issues.milestone_id = milestones.id
INNER JOIN epic_issues ON epic_issues.issue_id = issues.id
INNER JOIN (
SELECT MIN(milestones.start_date) AS start_date, MAX(milestones.due_date) AS due_date
FROM milestones
INNER JOIN issues ON issues.milestone_id = milestones.id
INNER JOIN epic_issues ON epic_issues.issue_id = issues.id
WHERE epic_issues.epic_id = #{id}
) inner_results ON (inner_results.start_date = milestones.start_date OR inner_results.due_date = milestones.due_date)
WHERE epic_issues.epic_id = #{id}
ORDER BY milestones.start_date, milestones.due_date;
SQL
db_results = ActiveRecord::Base.connection.select_all(sql).to_a
results = {}
db_results.find { |row| row['start_date'] }&.tap do |row|
results[:start_date] = row['start_date']
results[:start_date_sourcing_milestone_id] = row['id']
end
db_results.reverse.find { |row| row['due_date'] }&.tap do |row|
results[:due_date] = row['due_date']
results[:due_date_sourcing_milestone_id] = row['id']
end
results
end
end
end
......@@ -165,6 +165,7 @@ describe Epic do
context 'fixed date is not set' do
subject { create(:epic, start_date: nil, end_date: nil) }
let(:milestone1) {
create(
:milestone,
......@@ -180,18 +181,135 @@ describe Epic do
)
}
before do
epic_issue1 = create(:epic_issue, epic: subject)
epic_issue1.issue.update(milestone: milestone1)
epic_issue2 = create(:epic_issue, epic: subject)
epic_issue2.issue.update(milestone: milestone2)
context 'multiple milestones' do
before do
epic_issue1 = create(:epic_issue, epic: subject)
epic_issue1.issue.update(milestone: milestone1)
epic_issue2 = create(:epic_issue, epic: subject)
epic_issue2.issue.update(milestone: milestone2)
end
context 'complete start and due dates' do
it 'updates to milestone dates' do
subject.update_dates
expect(subject.start_date).to eq(milestone1.start_date)
expect(subject.due_date).to eq(milestone2.due_date)
end
end
context 'without due date' do
let(:milestone1) {
create(
:milestone,
start_date: Date.new(2000, 1, 1),
due_date: nil
)
}
let(:milestone2) {
create(
:milestone,
start_date: Date.new(2000, 1, 3),
due_date: nil
)
}
it 'updates to milestone dates' do
subject.update_dates
expect(subject.start_date).to eq(milestone1.start_date)
expect(subject.due_date).to eq(nil)
end
end
context 'without any dates' do
let(:milestone1) {
create(
:milestone,
start_date: nil,
due_date: nil
)
}
let(:milestone2) {
create(
:milestone,
start_date: nil,
due_date: nil
)
}
it 'updates to milestone dates' do
subject.update_dates
expect(subject.start_date).to eq(nil)
expect(subject.due_date).to eq(nil)
end
end
end
it 'updates to milestone dates' do
subject.update_dates
context 'without milestone' do
before do
create(:epic_issue, epic: subject)
end
it 'updates to milestone dates' do
subject.update_dates
expect(subject.start_date).to eq(nil)
expect(subject.start_date_sourcing_milestone_id).to eq(nil)
expect(subject.due_date).to eq(nil)
expect(subject.due_date_sourcing_milestone_id).to eq(nil)
end
end
expect(subject.start_date).to eq(milestone1.start_date)
expect(subject.due_date).to eq(milestone2.due_date)
context 'single milestone' do
before do
epic_issue1 = create(:epic_issue, epic: subject)
epic_issue1.issue.update(milestone: milestone1)
end
context 'complete start and due dates' do
it 'updates to milestone dates' do
subject.update_dates
expect(subject.start_date).to eq(milestone1.start_date)
expect(subject.due_date).to eq(milestone1.due_date)
end
end
context 'without due date' do
let(:milestone1) {
create(
:milestone,
start_date: Date.new(2000, 1, 1),
due_date: nil
)
}
it 'updates to milestone dates' do
subject.update_dates
expect(subject.start_date).to eq(milestone1.start_date)
expect(subject.due_date).to eq(nil)
end
end
context 'without any dates' do
let(:milestone1) {
create(
:milestone,
start_date: nil,
due_date: nil
)
}
it 'updates to milestone dates' do
subject.update_dates
expect(subject.start_date).to eq(nil)
expect(subject.due_date).to eq(nil)
end
end
end
end
end
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment