1
+ package com .wora .state_of_dev .survey .application .service .impl ;
2
+
3
+ import com .wora .state_of_dev .common .domain .exception .EntityNotFoundException ;
4
+ import com .wora .state_of_dev .survey .application .dto .request .*;
5
+ import com .wora .state_of_dev .survey .application .service .SurveySubmissionService ;
6
+ import com .wora .state_of_dev .survey .domain .entities .Answer ;
7
+ import com .wora .state_of_dev .survey .domain .entities .Question ;
8
+ import com .wora .state_of_dev .survey .domain .exception .GivenAnswerNotBelongToQuestion ;
9
+ import com .wora .state_of_dev .survey .domain .exception .QuestionNotBelongToSurveyEdition ;
10
+ import com .wora .state_of_dev .survey .domain .repository .AnswerRepository ;
11
+ import com .wora .state_of_dev .survey .domain .repository .QuestionRepository ;
12
+ import com .wora .state_of_dev .survey .domain .valueObject .AnswerId ;
13
+ import com .wora .state_of_dev .survey .domain .valueObject .AnswerType ;
14
+ import com .wora .state_of_dev .survey .domain .valueObject .QuestionId ;
15
+ import com .wora .state_of_dev .survey .domain .valueObject .SurveyEditionId ;
16
+ import jakarta .transaction .Transactional ;
17
+ import lombok .RequiredArgsConstructor ;
18
+ import org .springframework .stereotype .Service ;
19
+
20
+ import java .util .List ;
21
+ import java .util .Objects ;
22
+
23
+ @ Service
24
+ @ Transactional
25
+ @ RequiredArgsConstructor
26
+ public class DefaultSurveySubmissionService implements SurveySubmissionService {
27
+ private final QuestionRepository questionRepository ;
28
+ private final AnswerRepository answerRepository ;
29
+
30
+ private SurveyEditionId surveyEditionId ;
31
+
32
+ @ Override
33
+ public void submit (SurveyEditionId surveyEditionId , SingleQuestionSubmissionRequestDto dto ) {
34
+ this .surveyEditionId = surveyEditionId ;
35
+ handleSubmission (dto );
36
+ }
37
+
38
+ @ Override
39
+ public void submit (SurveyEditionId surveyEditionId , ListOfQuestionSubmissionRequestDto dto ) {
40
+ this .surveyEditionId = surveyEditionId ;
41
+ dto .submissions ()
42
+ .forEach (this ::handleSubmission );
43
+ }
44
+
45
+ private void handleSubmission (SingleQuestionSubmissionRequestDto dto ) {
46
+ Question question = findQuestionById (dto .questionId ());
47
+ if (!Objects .equals (surveyEditionId .value (), question .getChapter ().getSurveyEdition ().getId ().value ()))
48
+ throw new QuestionNotBelongToSurveyEdition ("the question with ID: " + question .getId ().value () + " does not belong to survey of id " + surveyEditionId .value ());
49
+
50
+ question .incrementAnswerCount ();
51
+ processAnswer (dto .answer (), question );
52
+ }
53
+
54
+ private Question findQuestionById (Long questionId ) {
55
+ return questionRepository .findById (new QuestionId (questionId ))
56
+ .orElseThrow (() -> new EntityNotFoundException ("question" , questionId ));
57
+ }
58
+
59
+ private void processAnswer (AnswerSubmissionRequestDto <?> answerDto , Question question ) {
60
+ if (answerDto instanceof SingleChoiceSubmissionRequestDto singleChoiceAnswer
61
+ && question .getAnswerType ().equals (AnswerType .SINGLE_CHOICE )) {
62
+ processSingleChoiceAnswer (singleChoiceAnswer , question );
63
+ } else if (answerDto instanceof MultiChoiceSubmissionRequestDto multiChoiceAnswer
64
+ && question .getAnswerType ().equals (AnswerType .MULTI_CHOICE )) {
65
+ processMultiChoiceAnswer (multiChoiceAnswer , question );
66
+ } else {
67
+ throw new IllegalArgumentException ("Unsupported answer type" );
68
+ }
69
+ }
70
+
71
+ private void processSingleChoiceAnswer (SingleChoiceSubmissionRequestDto answerDto , Question question ) {
72
+ Long answerId = answerDto .answer ();
73
+ Answer answer = answerRepository .findById (new AnswerId (answerId ))
74
+ .orElseThrow (() -> new EntityNotFoundException ("answer" , answerId ));
75
+ incrementSelectionCount (question , answer );
76
+ }
77
+
78
+ private void processMultiChoiceAnswer (MultiChoiceSubmissionRequestDto answerDto , Question question ) {
79
+ List <AnswerId > answerIds = answerDto .answer ().stream ()
80
+ .map (AnswerId ::new )
81
+ .toList ();
82
+ answerRepository .findAllById (answerIds )
83
+ .forEach (answer -> incrementSelectionCount (question , answer ));
84
+ }
85
+
86
+ private void incrementSelectionCount (Question question , Answer answer ) {
87
+ if (answer .getQuestion ().getId () != question .getId ())
88
+ throw new GivenAnswerNotBelongToQuestion ("answer with id " + answer .getId ().value () + " does not related to question " + question .getId ().value ());
89
+ answer .incrementSelectCount ();
90
+ }
91
+ }
0 commit comments