Skip to content

Commit c283bfa

Browse files
authored
Merge pull request #609 from topcoder-platform/dev
Release
2 parents bb6dff5 + d4b6058 commit c283bfa

File tree

2 files changed

+69
-38
lines changed

2 files changed

+69
-38
lines changed

src/common/phase-helper.js

Lines changed: 21 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -52,9 +52,9 @@ class ChallengePhaseHelper {
5252
);
5353
if (
5454
!_.isUndefined(fixedStartDate) &&
55-
moment(scheduledStartDate).isBefore(moment(fixedStartDate))
55+
moment(scheduledStartDate).isSameOrBefore(moment(fixedStartDate))
5656
) {
57-
scheduledStartDate = fixedStartDate;
57+
scheduledStartDate = moment(fixedStartDate).add(5, "minutes").toDate().toISOString();
5858
}
5959
phase.scheduledStartDate = moment(scheduledStartDate).toDate().toISOString();
6060
phase.scheduledEndDate = moment(phase.scheduledStartDate)
@@ -108,7 +108,7 @@ class ChallengePhaseHelper {
108108
if (updatedPhase.name === "Post-Mortem") {
109109
updatedPhase.predecessor = "a93544bc-c165-4af4-b55e-18f3593b457a";
110110
}
111-
if (_.isUndefined(updatedPhase.actualEndDate) && updatedPhase.name !== "Iterative Review") {
111+
if (_.isUndefined(updatedPhase.actualEndDate)) {
112112
updatedPhase.duration = _.defaultTo(_.get(newPhase, "duration"), updatedPhase.duration);
113113
}
114114
if (_.isUndefined(updatedPhase.predecessor)) {
@@ -118,9 +118,9 @@ class ChallengePhaseHelper {
118118
);
119119
if (
120120
!_.isUndefined(fixedStartDate) &&
121-
moment(scheduledStartDate).isBefore(moment(fixedStartDate))
121+
moment(scheduledStartDate).isSameOrBefore(moment(fixedStartDate))
122122
) {
123-
scheduledStartDate = fixedStartDate;
123+
scheduledStartDate = moment(fixedStartDate).add(5, "minutes").toDate().toISOString();
124124
}
125125
if (isBeingActivated && moment(scheduledStartDate).isSameOrBefore(moment())) {
126126
updatedPhase.isOpen = true;
@@ -134,7 +134,11 @@ class ChallengePhaseHelper {
134134
.toDate()
135135
.toISOString();
136136
}
137-
if (!_.isUndefined(newPhase) && !_.isUndefined(newPhase.constraints)) {
137+
if (
138+
_.isUndefined(phase.actualEndDate) &&
139+
!_.isUndefined(newPhase) &&
140+
!_.isUndefined(newPhase.constraints)
141+
) {
138142
updatedPhase.constraints = newPhase.constraints;
139143
}
140144
if (_.isUndefined(fixedStartDate)) {
@@ -170,6 +174,17 @@ class ChallengePhaseHelper {
170174
return updatedPhases;
171175
}
172176

177+
handlePhasesAfterCancelling(phases) {
178+
return _.map(phases, (phase) => {
179+
const shouldClosePhase = _.includes(["Registration", "Submission", "Checkpoint Submission"], phase.name);
180+
return {
181+
...phase,
182+
isOpen: shouldClosePhase ? false : phase.isOpen,
183+
actualEndDate: shouldClosePhase ? moment().toDate().toISOString() : phase.actualEndDate,
184+
};
185+
});
186+
}
187+
173188
async validatePhases(phases) {
174189
if (!phases || phases.length === 0) {
175190
return;

src/services/ChallengeService.js

Lines changed: 48 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@ const {
4242
convertToISOString,
4343
} = require("../common/challenge-helper");
4444
const deepEqual = require("deep-equal");
45+
const { cloneDeep } = require("lodash");
4546

4647
const challengeDomain = new ChallengeDomain(GRPC_CHALLENGE_SERVER_HOST, GRPC_CHALLENGE_SERVER_PORT);
4748

@@ -1492,23 +1493,8 @@ async function validateWinners(winners, challengeId) {
14921493
async function updateChallenge(currentUser, challengeId, data) {
14931494
const challenge = await challengeDomain.lookup(getLookupCriteria("id", challengeId));
14941495

1495-
// Remove fields from data that are not allowed to be updated and that match the existing challenge
1496-
data = sanitizeData(sanitizeChallenge(data), challenge);
1497-
console.debug("Sanitized Data:", data);
1498-
1499-
if (data.phases != null && data.startDate == null) {
1500-
data.startDate = challenge.startDate;
1501-
}
1502-
1503-
validateChallengeUpdateRequest(currentUser, challenge, data);
1504-
15051496
const projectId = _.get(challenge, "projectId");
15061497

1507-
let sendActivationEmail = false;
1508-
let sendSubmittedEmail = false;
1509-
let sendCompletedEmail = false;
1510-
let sendRejectedEmail = false;
1511-
15121498
const { billingAccountId, markup } = await projectHelper.getProjectBillingInformation(projectId);
15131499

15141500
if (billingAccountId && _.isUndefined(_.get(challenge, "billing.billingAccountId"))) {
@@ -1517,10 +1503,22 @@ async function updateChallenge(currentUser, challengeId, data) {
15171503
}
15181504

15191505
// Make sure the user cannot change the direct project ID
1520-
if (data.legacy && data.legacy.directProjectId) {
1521-
_.unset(data, "legacy.directProjectId");
1506+
if (data.legacy) {
1507+
data.legacy = _.assign({},challenge.legacy, data.legacy)
1508+
_.set(data, "legacy.directProjectId", challenge.legacy.directProjectId);
15221509
}
15231510

1511+
// Remove fields from data that are not allowed to be updated and that match the existing challenge
1512+
data = sanitizeData(sanitizeChallenge(data), challenge);
1513+
console.debug("Sanitized Data:", data);
1514+
1515+
validateChallengeUpdateRequest(currentUser, challenge, data);
1516+
1517+
let sendActivationEmail = false;
1518+
let sendSubmittedEmail = false;
1519+
let sendCompletedEmail = false;
1520+
let sendRejectedEmail = false;
1521+
15241522
/* BEGIN self-service stuffs */
15251523

15261524
// TODO: At some point in the future this should be moved to a Self-Service Challenge Helper
@@ -1589,11 +1587,24 @@ async function updateChallenge(currentUser, challengeId, data) {
15891587
logger.debug(`There was an error trying to update the project: ${e.message}`);
15901588
}
15911589
}
1590+
1591+
if (
1592+
data.status === constants.challengeStatuses.CancelledRequirementsInfeasible ||
1593+
data.status === constants.challengeStatuses.CancelledPaymentFailed
1594+
) {
1595+
try {
1596+
await helper.cancelProject(challenge.projectId, data.cancelReason, currentUser);
1597+
} catch (e) {
1598+
logger.debug(`There was an error trying to cancel the project: ${e.message}`);
1599+
}
1600+
sendRejectedEmail = true;
1601+
}
15921602
}
15931603

15941604
/* END self-service stuffs */
15951605

15961606
let isChallengeBeingActivated = false;
1607+
let isChallengeBeingCancelled = false;
15971608
if (data.status) {
15981609
if (data.status === constants.challengeStatuses.Active) {
15991610
if (
@@ -1619,16 +1630,18 @@ async function updateChallenge(currentUser, challengeId, data) {
16191630
}
16201631
}
16211632

1622-
if (
1623-
data.status === constants.challengeStatuses.CancelledRequirementsInfeasible ||
1624-
data.status === constants.challengeStatuses.CancelledPaymentFailed
1625-
) {
1626-
try {
1627-
await helper.cancelProject(challenge.projectId, cancelReason, currentUser);
1628-
} catch (e) {
1629-
logger.debug(`There was an error trying to cancel the project: ${e.message}`);
1630-
}
1631-
sendRejectedEmail = true;
1633+
if (_.includes([
1634+
constants.challengeStatuses.Cancelled,
1635+
constants.challengeStatuses.CancelledRequirementsInfeasible,
1636+
constants.challengeStatuses.CancelledPaymentFailed,
1637+
constants.challengeStatuses.CancelledFailedReview,
1638+
constants.challengeStatuses.CancelledFailedScreening,
1639+
constants.challengeStatuses.CancelledZeroSubmissions,
1640+
constants.challengeStatuses.CancelledWinnerUnresponsive,
1641+
constants.challengeStatuses.CancelledClientRequest,
1642+
constants.challengeStatuses.CancelledZeroRegistrations,
1643+
], data.status)) {
1644+
isChallengeBeingCancelled = true;
16321645
}
16331646

16341647
if (data.status === constants.challengeStatuses.Completed) {
@@ -1723,9 +1736,9 @@ async function updateChallenge(currentUser, challengeId, data) {
17231736

17241737
let phasesUpdated = false;
17251738
if (
1726-
(data.phases && data.phases.length > 0) ||
1739+
((data.phases && data.phases.length > 0) ||
17271740
isChallengeBeingActivated ||
1728-
timelineTemplateChanged
1741+
timelineTemplateChanged) && !isChallengeBeingCancelled
17291742
) {
17301743
if (
17311744
challenge.status === constants.challengeStatuses.Completed ||
@@ -1754,6 +1767,10 @@ async function updateChallenge(currentUser, challengeId, data) {
17541767
phasesUpdated = true;
17551768
data.phases = newPhases;
17561769
}
1770+
if (isChallengeBeingCancelled && challenge.phases && challenge.phases.length > 0) {
1771+
data.phases = phaseHelper.handlePhasesAfterCancelling(challenge.phases);
1772+
phasesUpdated = true;
1773+
}
17571774
if (phasesUpdated || data.startDate) {
17581775
data.startDate = convertToISOString(_.min(_.map(data.phases, "scheduledStartDate")));
17591776
}
@@ -1855,8 +1872,7 @@ async function updateChallenge(currentUser, challengeId, data) {
18551872
}
18561873

18571874
try {
1858-
const updateInput = sanitizeRepeatedFieldsInUpdateRequest(data);
1859-
1875+
const updateInput = sanitizeRepeatedFieldsInUpdateRequest(_.omit(data, ['cancelReason']));
18601876
if (!_.isEmpty(updateInput)) {
18611877
const grpcMetadata = new GrpcMetadata();
18621878

@@ -1969,7 +1985,7 @@ updateChallenge.schema = {
19691985
.valid(_.values(constants.reviewTypes))
19701986
.insensitive()
19711987
.default(constants.reviewTypes.Internal),
1972-
confidentialityType: Joi.string().default(config.DEFAULT_CONFIDENTIALITY_TYPE),
1988+
confidentialityType: Joi.string().allow(null,'').empty(null,'').default(config.DEFAULT_CONFIDENTIALITY_TYPE),
19731989
directProjectId: Joi.number(),
19741990
forumId: Joi.number().integer(),
19751991
isTask: Joi.boolean(),

0 commit comments

Comments
 (0)