Skip to content

Commit 14dc571

Browse files
author
Vikas Agarwal
committed
Fixed logic for updating upcoming milestones when actual start date of milestone is changed.
1 parent e2e0d49 commit 14dc571

File tree

1 file changed

+31
-17
lines changed

1 file changed

+31
-17
lines changed

src/routes/milestones/update.js

Lines changed: 31 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -16,42 +16,47 @@ const permissions = tcMiddleware.permissions;
1616

1717
/**
1818
* Cascades endDate/completionDate changes to all milestones with a greater order than the given one.
19-
* @param {Object} originalMilestone the original milestone that was updated
20-
* @param {Object} updatedMilestone the milestone that was updated
19+
* @param {Object} origMilestone the original milestone that was updated
20+
* @param {Object} updMilestone the milestone that was updated
2121
* @returns {Promise<void>} a promise that resolves to the last found milestone. If no milestone exists with an
22-
* order greater than the passed <b>updatedMilestone</b>, the promise will resolve to the passed
23-
* <b>updatedMilestone</b>
22+
* order greater than the passed <b>updMilestone</b>, the promise will resolve to the passed
23+
* <b>updMilestone</b>
2424
*/
25-
function updateComingMilestones(originalMilestone, updatedMilestone) {
25+
function updateComingMilestones(origMilestone, updMilestone) {
2626
// flag to indicate if the milestone in picture, is updated for completionDate field or not
27-
const completionDateChanged = !_.isEqual(originalMilestone.completionDate, updatedMilestone.completionDate);
27+
const completionDateChanged = !_.isEqual(origMilestone.completionDate, updMilestone.completionDate);
2828
const today = moment.utc().hours(0).minutes(0).seconds(0)
2929
.milliseconds(0);
30+
// updated milestone's start date, pefers actual start date over scheduled start date
31+
const updMSStartDate = updMilestone.actualStartDate ? updMilestone.actualStartDate : updMilestone.startDate;
32+
// calculates schedule end date for the milestone based on start date and duration
33+
let updMilestoneEndDate = moment.utc(updMSStartDate).add(updMilestone.duration - 1, 'days').toDate();
34+
// if the milestone, in context, is completed, overrides the end date to the completion date
35+
updMilestoneEndDate = updMilestone.completionDate ? updMilestone.completionDate : updMilestoneEndDate;
3036
return models.Milestone.findAll({
3137
where: {
32-
timelineId: updatedMilestone.timelineId,
33-
order: { $gt: updatedMilestone.order },
38+
timelineId: updMilestone.timelineId,
39+
order: { $gt: updMilestone.order },
3440
},
3541
}).then((affectedMilestones) => {
3642
const comingMilestones = _.sortBy(affectedMilestones, 'order');
37-
let startDate = moment.utc(updatedMilestone.completionDate
38-
? updatedMilestone.completionDate
39-
: updatedMilestone.endDate).add(1, 'days').toDate();
43+
// calculates the schedule start date for the next milestone
44+
let startDate = moment.utc(updMilestoneEndDate).add(1, 'days').toDate();
4045
let firstMilestoneFound = false;
4146
const promises = _.map(comingMilestones, (_milestone) => {
4247
const milestone = _milestone;
4348

4449
// Update the milestone startDate if different than the iterated startDate
4550
if (!_.isEqual(milestone.startDate, startDate)) {
4651
milestone.startDate = startDate;
47-
milestone.updatedBy = updatedMilestone.updatedBy;
52+
milestone.updatedBy = updMilestone.updatedBy;
4853
}
4954

5055
// Calculate the endDate, and update it if different
5156
const endDate = moment.utc(startDate).add(milestone.duration - 1, 'days').toDate();
5257
if (!_.isEqual(milestone.endDate, endDate)) {
5358
milestone.endDate = endDate;
54-
milestone.updatedBy = updatedMilestone.updatedBy;
59+
milestone.updatedBy = updMilestone.updatedBy;
5560
}
5661

5762
// if completionDate is alerted, update status of the first non hidden milestone after the current one
@@ -160,10 +165,7 @@ module.exports = [
160165
// Merge JSON fields
161166
entityToUpdate.details = util.mergeJsonObjects(milestone.details, entityToUpdate.details);
162167

163-
if (durationChanged) {
164-
entityToUpdate.endDate = moment.utc(milestone.startDate).add(entityToUpdate.duration - 1, 'days').toDate();
165-
}
166-
168+
let actualStartDateCanged = false;
167169
// if status has changed
168170
if (statusChanged) {
169171
// if status has changed to be completed, set the compeltionDate if not provided
@@ -176,9 +178,21 @@ module.exports = [
176178
// entityToUpdate.startDate = today;
177179
// should update actual start date
178180
entityToUpdate.actualStartDate = today;
181+
actualStartDateCanged = true;
179182
}
180183
}
181184

185+
// Updates the end date of the milestone if:
186+
// 1. if duration of the milestone is udpated, update its end date
187+
// OR
188+
// 2. if actual start date is updated, updating the end date of the activated milestone because
189+
// early or late start of milestone, we are essentially changing the end schedule of the milestone
190+
if (durationChanged || actualStartDateCanged) {
191+
const updatedStartDate = actualStartDateCanged ? entityToUpdate.actualStartDate : milestone.startDate;
192+
const updatedDuration = _.get(entityToUpdate, 'duration', milestone.duration);
193+
entityToUpdate.endDate = moment.utc(updatedStartDate).add(updatedDuration - 1, 'days').toDate();
194+
}
195+
182196
// if completionDate has changed
183197
if (!statusChanged && completionDateChanged) {
184198
entityToUpdate.status = MILESTONE_STATUS.COMPLETED;

0 commit comments

Comments
 (0)