Skip to content

Commit

Permalink
Merge branch 'develop' into SWAP-4384-experiment-safety-forms-list-page
Browse files Browse the repository at this point in the history
  • Loading branch information
yoganandaness authored Feb 20, 2025
2 parents d4d5e19 + 2bd967b commit 1d1644c
Show file tree
Hide file tree
Showing 4 changed files with 346 additions and 10 deletions.
11 changes: 8 additions & 3 deletions apps/backend/src/models/questionTypes/TechniquePicker.ts
Original file line number Diff line number Diff line change
Expand Up @@ -76,9 +76,14 @@ export const techniquePickerDefinition: Question<DataType.TECHNIQUE_PICKER> = {

return {
...config,
techniques: uniqueTechniques.map(
(technique) => new TechniqueOptionClass(technique.id, technique.name)
),
techniques: uniqueTechniques
.map(
(technique) =>
new TechniqueOptionClass(technique.id, technique.name)
)
.sort((a, b) =>
a.name.toLowerCase() > b.name.toLowerCase() ? 1 : -1
),
};
} catch (err) {
logger.logError('Techniques fetch failed', {
Expand Down
126 changes: 122 additions & 4 deletions apps/backend/src/mutations/QuestionaryMutations.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@ import { container, inject, injectable } from 'tsyringe';

import { QuestionaryAuthorization } from '../auth/QuestionaryAuthorization';
import { Tokens } from '../config/Tokens';
import { GenericTemplateDataSource } from '../datasources/GenericTemplateDataSource';
import { ProposalDataSource } from '../datasources/ProposalDataSource';
import { QuestionaryDataSource } from '../datasources/QuestionaryDataSource';
import { TemplateDataSource } from '../datasources/TemplateDataSource';
import { Authorized, EventBus } from '../decorators';
Expand All @@ -15,10 +17,15 @@ import {
import { AnswerBasic } from '../models/Questionary';
import { getQuestionDefinition } from '../models/questionTypes/QuestionRegistry';
import { rejection } from '../models/Rejection';
import { DataType } from '../models/Template';
import { UserJWT, UserWithRole } from '../models/User';
import { AnswerTopicArgs } from '../resolvers/mutations/AnswerTopicMutation';
import {
AnswerInput,
AnswerTopicArgs,
} from '../resolvers/mutations/AnswerTopicMutation';
import { CreateQuestionaryArgs } from '../resolvers/mutations/CreateQuestionaryMutation';
import { UpdateAnswerArgs } from '../resolvers/mutations/UpdateAnswerMutation';
import { SubTemplateConfig } from '../resolvers/types/FieldConfig';

@injectable()
export default class QuestionaryMutations {
Expand All @@ -28,13 +35,19 @@ export default class QuestionaryMutations {
@inject(Tokens.QuestionaryDataSource)
private dataSource: QuestionaryDataSource,
@inject(Tokens.TemplateDataSource)
private templateDataSource: TemplateDataSource
private templateDataSource: TemplateDataSource,
@inject(Tokens.GenericTemplateDataSource)
private genericTemplateDataSource: GenericTemplateDataSource,
@inject(Tokens.ProposalDataSource)
private proposalDataSource: ProposalDataSource
) {}

async deleteOldAnswers(
templateId: number,
questionaryId: number,
topicId: number
topicId: number,
answers: AnswerInput[],
agent: UserWithRole | null
) {
const templateSteps =
await this.templateDataSource.getTemplateSteps(templateId);
Expand All @@ -53,9 +66,108 @@ export default class QuestionaryMutations {
const questionIds: string[] = stepQuestions.map(
(question) => question.question.id
);

const genericTemplateQuestions = stepQuestions.filter(
(step) => step.question.dataType == DataType.GENERIC_TEMPLATE
);

if (genericTemplateQuestions.length > 0) {
// Confirm dependency with dependency condition
const unsatisfiedDependencyQues = genericTemplateQuestions.filter(
(genericTemplateQues) => {
const notSatisfiedQuestions = genericTemplateQues.dependencies.filter(
(dependency) => {
const answer = answers.find(
(answer) => answer.questionId === dependency.dependencyId
);

if (answer) {
const { value } = JSON.parse(answer.value);
if (value[0] !== dependency.condition.params) {
return true;
}
}
}
);

if (notSatisfiedQuestions.length !== 0) {
return true;
}
}
);

for (const subTemplateQues of unsatisfiedDependencyQues) {
const config = subTemplateQues.config as SubTemplateConfig;
await this.deleteSubTemplatesAnswers(
subTemplateQues.question.id,
config.templateId,
questionaryId,
agent
);
}
}

await this.dataSource.deleteAnswers(questionaryId, questionIds);
}

async deleteSubTemplatesAnswers(
questionId: string,
genericTemplateId: number | null,
questionaryId: number,
agent: UserWithRole | null
): Promise<void> {
if (!genericTemplateId) {
return;
}

const proposal = (
await this.proposalDataSource.getProposals({
questionaryIds: [questionaryId],
})
).proposals[0];

const genericTemplates =
await this.genericTemplateDataSource.getGenericTemplates(
{
filter: {
questionId: questionId,
proposalPk: proposal?.primaryKey,
},
},
agent
);

if (!genericTemplates) {
return;
}

const templateSteps =
await this.templateDataSource.getTemplateSteps(genericTemplateId);
const genericTemplateStepQuestions = templateSteps.flatMap(
(step) => step.fields
);

if (!genericTemplateStepQuestions) {
return;
}

const genericTemplateQuestionIds = genericTemplateStepQuestions.map(
(question) => question.question.id
);

if (!genericTemplateQuestionIds) {
return;
}

for (const genericTemplate of genericTemplates) {
await this.dataSource.deleteAnswers(
genericTemplate.questionaryId,
genericTemplateQuestionIds
);
await this.genericTemplateDataSource.delete(genericTemplate.id);
}
}

@Authorized()
@EventBus(Event.TOPIC_ANSWERED)
async answerTopic(agent: UserWithRole | null, args: AnswerTopicArgs) {
Expand Down Expand Up @@ -89,7 +201,13 @@ export default class QuestionaryMutations {
);
}

await this.deleteOldAnswers(template.templateId, questionaryId, topicId);
await this.deleteOldAnswers(
template.templateId,
questionaryId,
topicId,
answers,
agent
);

const updatedAnswers: AnswerBasic[] = [];
for (const answer of answers) {
Expand Down
5 changes: 4 additions & 1 deletion apps/backend/src/statusActionEngine/statusActionUtils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -192,7 +192,10 @@ export const getEmailReadyArrayOfUsersAndProposals = async (
);
for (const step of await questionarySteps) {
const stepFields = step.fields.map((field) => field);
if (step.topic.title.toUpperCase() === 'SAMPLES') {
if (
step.topic.title.toUpperCase() === 'SAMPLES' ||
step.topic.title.toUpperCase() === 'SAMPLE'
) {
const answers = await stepAnswers(
stepFields,
proposal.primaryKey
Expand Down
Loading

0 comments on commit 1d1644c

Please sign in to comment.