Skip to content

Release #609

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 18 commits into from
Mar 30, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
18 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 21 additions & 6 deletions src/common/phase-helper.js
Original file line number Diff line number Diff line change
Expand Up @@ -52,9 +52,9 @@ class ChallengePhaseHelper {
);
if (
!_.isUndefined(fixedStartDate) &&
moment(scheduledStartDate).isBefore(moment(fixedStartDate))
moment(scheduledStartDate).isSameOrBefore(moment(fixedStartDate))
) {
scheduledStartDate = fixedStartDate;
scheduledStartDate = moment(fixedStartDate).add(5, "minutes").toDate().toISOString();
}
phase.scheduledStartDate = moment(scheduledStartDate).toDate().toISOString();
phase.scheduledEndDate = moment(phase.scheduledStartDate)
Expand Down Expand Up @@ -108,7 +108,7 @@ class ChallengePhaseHelper {
if (updatedPhase.name === "Post-Mortem") {
updatedPhase.predecessor = "a93544bc-c165-4af4-b55e-18f3593b457a";
}
if (_.isUndefined(updatedPhase.actualEndDate) && updatedPhase.name !== "Iterative Review") {
if (_.isUndefined(updatedPhase.actualEndDate)) {
updatedPhase.duration = _.defaultTo(_.get(newPhase, "duration"), updatedPhase.duration);
}
if (_.isUndefined(updatedPhase.predecessor)) {
Expand All @@ -118,9 +118,9 @@ class ChallengePhaseHelper {
);
if (
!_.isUndefined(fixedStartDate) &&
moment(scheduledStartDate).isBefore(moment(fixedStartDate))
moment(scheduledStartDate).isSameOrBefore(moment(fixedStartDate))
) {
scheduledStartDate = fixedStartDate;
scheduledStartDate = moment(fixedStartDate).add(5, "minutes").toDate().toISOString();
}
if (isBeingActivated && moment(scheduledStartDate).isSameOrBefore(moment())) {
updatedPhase.isOpen = true;
Expand All @@ -134,7 +134,11 @@ class ChallengePhaseHelper {
.toDate()
.toISOString();
}
if (!_.isUndefined(newPhase) && !_.isUndefined(newPhase.constraints)) {
if (
_.isUndefined(phase.actualEndDate) &&
!_.isUndefined(newPhase) &&
!_.isUndefined(newPhase.constraints)
) {
updatedPhase.constraints = newPhase.constraints;
}
if (_.isUndefined(fixedStartDate)) {
Expand Down Expand Up @@ -170,6 +174,17 @@ class ChallengePhaseHelper {
return updatedPhases;
}

handlePhasesAfterCancelling(phases) {
return _.map(phases, (phase) => {
const shouldClosePhase = _.includes(["Registration", "Submission", "Checkpoint Submission"], phase.name);
return {
...phase,
isOpen: shouldClosePhase ? false : phase.isOpen,
actualEndDate: shouldClosePhase ? moment().toDate().toISOString() : phase.actualEndDate,
};
});
}

async validatePhases(phases) {
if (!phases || phases.length === 0) {
return;
Expand Down
80 changes: 48 additions & 32 deletions src/services/ChallengeService.js
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ const {
convertToISOString,
} = require("../common/challenge-helper");
const deepEqual = require("deep-equal");
const { cloneDeep } = require("lodash");

const challengeDomain = new ChallengeDomain(GRPC_CHALLENGE_SERVER_HOST, GRPC_CHALLENGE_SERVER_PORT);

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

// Remove fields from data that are not allowed to be updated and that match the existing challenge
data = sanitizeData(sanitizeChallenge(data), challenge);
console.debug("Sanitized Data:", data);

if (data.phases != null && data.startDate == null) {
data.startDate = challenge.startDate;
}

validateChallengeUpdateRequest(currentUser, challenge, data);

const projectId = _.get(challenge, "projectId");

let sendActivationEmail = false;
let sendSubmittedEmail = false;
let sendCompletedEmail = false;
let sendRejectedEmail = false;

const { billingAccountId, markup } = await projectHelper.getProjectBillingInformation(projectId);

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

// Make sure the user cannot change the direct project ID
if (data.legacy && data.legacy.directProjectId) {
_.unset(data, "legacy.directProjectId");
if (data.legacy) {
data.legacy = _.assign({},challenge.legacy, data.legacy)
_.set(data, "legacy.directProjectId", challenge.legacy.directProjectId);
}

// Remove fields from data that are not allowed to be updated and that match the existing challenge
data = sanitizeData(sanitizeChallenge(data), challenge);
console.debug("Sanitized Data:", data);

validateChallengeUpdateRequest(currentUser, challenge, data);

let sendActivationEmail = false;
let sendSubmittedEmail = false;
let sendCompletedEmail = false;
let sendRejectedEmail = false;

/* BEGIN self-service stuffs */

// TODO: At some point in the future this should be moved to a Self-Service Challenge Helper
Expand Down Expand Up @@ -1589,11 +1587,24 @@ async function updateChallenge(currentUser, challengeId, data) {
logger.debug(`There was an error trying to update the project: ${e.message}`);
}
}

if (
data.status === constants.challengeStatuses.CancelledRequirementsInfeasible ||
data.status === constants.challengeStatuses.CancelledPaymentFailed
) {
try {
await helper.cancelProject(challenge.projectId, data.cancelReason, currentUser);
} catch (e) {
logger.debug(`There was an error trying to cancel the project: ${e.message}`);
}
sendRejectedEmail = true;
}
}

/* END self-service stuffs */

let isChallengeBeingActivated = false;
let isChallengeBeingCancelled = false;
if (data.status) {
if (data.status === constants.challengeStatuses.Active) {
if (
Expand All @@ -1619,16 +1630,18 @@ async function updateChallenge(currentUser, challengeId, data) {
}
}

if (
data.status === constants.challengeStatuses.CancelledRequirementsInfeasible ||
data.status === constants.challengeStatuses.CancelledPaymentFailed
) {
try {
await helper.cancelProject(challenge.projectId, cancelReason, currentUser);
} catch (e) {
logger.debug(`There was an error trying to cancel the project: ${e.message}`);
}
sendRejectedEmail = true;
if (_.includes([
constants.challengeStatuses.Cancelled,
constants.challengeStatuses.CancelledRequirementsInfeasible,
constants.challengeStatuses.CancelledPaymentFailed,
constants.challengeStatuses.CancelledFailedReview,
constants.challengeStatuses.CancelledFailedScreening,
constants.challengeStatuses.CancelledZeroSubmissions,
constants.challengeStatuses.CancelledWinnerUnresponsive,
constants.challengeStatuses.CancelledClientRequest,
constants.challengeStatuses.CancelledZeroRegistrations,
], data.status)) {
isChallengeBeingCancelled = true;
}

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

let phasesUpdated = false;
if (
(data.phases && data.phases.length > 0) ||
((data.phases && data.phases.length > 0) ||
isChallengeBeingActivated ||
timelineTemplateChanged
timelineTemplateChanged) && !isChallengeBeingCancelled
) {
if (
challenge.status === constants.challengeStatuses.Completed ||
Expand Down Expand Up @@ -1754,6 +1767,10 @@ async function updateChallenge(currentUser, challengeId, data) {
phasesUpdated = true;
data.phases = newPhases;
}
if (isChallengeBeingCancelled && challenge.phases && challenge.phases.length > 0) {
data.phases = phaseHelper.handlePhasesAfterCancelling(challenge.phases);
phasesUpdated = true;
}
if (phasesUpdated || data.startDate) {
data.startDate = convertToISOString(_.min(_.map(data.phases, "scheduledStartDate")));
}
Expand Down Expand Up @@ -1855,8 +1872,7 @@ async function updateChallenge(currentUser, challengeId, data) {
}

try {
const updateInput = sanitizeRepeatedFieldsInUpdateRequest(data);

const updateInput = sanitizeRepeatedFieldsInUpdateRequest(_.omit(data, ['cancelReason']));
if (!_.isEmpty(updateInput)) {
const grpcMetadata = new GrpcMetadata();

Expand Down Expand Up @@ -1969,7 +1985,7 @@ updateChallenge.schema = {
.valid(_.values(constants.reviewTypes))
.insensitive()
.default(constants.reviewTypes.Internal),
confidentialityType: Joi.string().default(config.DEFAULT_CONFIDENTIALITY_TYPE),
confidentialityType: Joi.string().allow(null,'').empty(null,'').default(config.DEFAULT_CONFIDENTIALITY_TYPE),
directProjectId: Joi.number(),
forumId: Joi.number().integer(),
isTask: Joi.boolean(),
Expand Down