Skip to content

Commit fd9ae86

Browse files
authored
Merge pull request #2264 from jadmsaadaot/TRACK-task#2105
Prevent issue start date being after earliest update
2 parents 7c3a9f0 + 0552c22 commit fd9ae86

File tree

2 files changed

+33
-3
lines changed

2 files changed

+33
-3
lines changed

epictrack-api/src/api/services/work_issues.py

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -118,15 +118,26 @@ def approve_work_issues(cls, issue_id, update_id):
118118

119119
return work_issue_update
120120

121+
@classmethod
122+
def _check_valid_issue_edit_data(cls, new_data, work_issue_db):
123+
"""Check if the issue data is valid for editing"""
124+
if new_data.get('expected_resolution_date'):
125+
if new_data.get('start_date').timestamp() > new_data.get('expected_resolution_date').timestamp():
126+
raise BadRequestError('expected resolution date cannot be before the start date')
127+
128+
earliest_issue_update_date = min(update.posted_date for update in work_issue_db.updates)
129+
if new_data.get('start_date').timestamp() > earliest_issue_update_date.timestamp():
130+
raise BadRequestError('issue start date cannot be after an update date')
131+
121132
@classmethod
122133
def edit_issue(cls, work_id, issue_id, issue_data):
123134
"""Edit an existing work issue, and save it only if there are changes."""
124135
work_issue = WorkIssuesService.find_work_issue_by_id(work_id, issue_id)
125136

126137
if not work_issue:
127138
raise ResourceNotFoundError("Work issue doesnt exist")
128-
129139
cls._check_edit_auth(work_id)
140+
cls._check_valid_issue_edit_data(issue_data, work_issue)
130141

131142
# Create a flag to track changes on work_issues
132143
has_changes_to_work_issue = False

epictrack-web/src/components/workPlan/issues/Forms/EditIssue.tsx

Lines changed: 21 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import React, { useEffect } from "react";
1+
import React, { useEffect, useMemo } from "react";
22
import { FormProvider, useForm } from "react-hook-form";
33
import * as yup from "yup";
44
import { yupResolver } from "@hookform/resolvers/yup";
@@ -13,6 +13,7 @@ import { EditIssueForm } from "../types";
1313
import moment from "moment";
1414
import ControlledDatePicker from "../../../shared/controlledInputComponents/ControlledDatePicker";
1515
import { ETFormLabel } from "../../../shared";
16+
import dayjs from "dayjs";
1617

1718
const InfoIcon: React.FC<IconProps> = Icons["InfoIcon"];
1819

@@ -40,6 +41,19 @@ const EditIssue = () => {
4041
mode: "onSubmit",
4142
});
4243

44+
const maxStartDate = useMemo(() => {
45+
if (!issueToEdit) {
46+
return undefined;
47+
}
48+
49+
// find the min date of updates
50+
const updatesPostedDates = issueToEdit.updates.map((update) =>
51+
moment(update.posted_date)
52+
);
53+
const minPostedDate = moment.min(updatesPostedDates).toDate();
54+
return dayjs(minPostedDate);
55+
}, [issueToEdit]);
56+
4357
const { handleSubmit, watch } = methods;
4458

4559
const watchedTitle = watch("title");
@@ -131,7 +145,12 @@ const EditIssue = () => {
131145
</Grid>
132146
<Grid item xs={6}>
133147
<ETFormLabel required>Start Date</ETFormLabel>
134-
<ControlledDatePicker name="start_date" />
148+
<ControlledDatePicker
149+
name="start_date"
150+
datePickerProps={{
151+
maxDate: maxStartDate,
152+
}}
153+
/>
135154
</Grid>
136155
<Grid item xs={6}>
137156
<ETFormLabel required>Expected Resolution Date</ETFormLabel>

0 commit comments

Comments
 (0)