Skip to content
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

EditResponseの実装 #1268

Merged
merged 3 commits into from
Sep 20, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
66 changes: 66 additions & 0 deletions controller/adapter.go
Original file line number Diff line number Diff line change
Expand Up @@ -276,3 +276,69 @@ func respondentDetail2Response(ctx echo.Context, respondentDetail model.Responde

return res, nil
}

func responseBody2ResponseMetas(body []openapi.ResponseBody, questions []model.Questions) ([]*model.ResponseMeta, error) {
res := []*model.ResponseMeta{}

for i, b := range body {
switch questions[i].Type {
case "Text":
bText, err := b.AsResponseBodyText()
if err != nil {
return nil, err
}
res = append(res, &model.ResponseMeta{
QuestionID: questions[i].ID,
Data: bText.Answer,
})
case "TextLong":
bTextLong, err := b.AsResponseBodyTextLong()
if err != nil {
return nil, err
}
res = append(res, &model.ResponseMeta{
QuestionID: questions[i].ID,
Data: bTextLong.Answer,
})
case "Number":
bNumber, err := b.AsResponseBodyNumber()
if err != nil {
return nil, err
}
res = append(res, &model.ResponseMeta{
QuestionID: questions[i].ID,
Data: strconv.FormatFloat(float64(bNumber.Answer), 'f', -1, 32),
})
case "SingleChoice":
bSingleChoice, err := b.AsResponseBodySingleChoice()
if err != nil {
return nil, err
}
res = append(res, &model.ResponseMeta{
QuestionID: questions[i].ID,
Data: strconv.FormatInt(int64(bSingleChoice.Answer), 10),
})
case "MultipleChoice":
bMultipleChoice, err := b.AsResponseBodyMultipleChoice()
if err != nil {
return nil, err
}
for _, a := range bMultipleChoice.Answer {
res = append(res, &model.ResponseMeta{
QuestionID: questions[i].ID,
Data: strconv.FormatInt(int64(a), 10),
})
}
case "LinearScale":
bScale, err := b.AsResponseBodyScale()
if err != nil {
return nil, err
}
res = append(res, &model.ResponseMeta{
QuestionID: questions[i].ID,
Data: strconv.FormatInt(int64(bScale.Answer), 10),
})
}
}
return res, nil
}
42 changes: 42 additions & 0 deletions controller/response.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ type Response struct {
model.IRespondent
model.IResponse
model.ITarget
model.IQuestion
}

func NewResponse() *Response {
Expand Down Expand Up @@ -132,3 +133,44 @@ func (r Response) DeleteResponse(ctx echo.Context, responseID openapi.ResponseID

return nil
}

func (r Response) EditResponse(ctx echo.Context, responseID openapi.ResponseIDInPath, req openapi.EditResponseJSONRequestBody) error {
limit, err := r.IQuestionnaire.GetQuestionnaireLimitByResponseID(ctx.Request().Context(), responseID)
if err != nil {
if errors.Is(err, model.ErrRecordNotFound) {
ctx.Logger().Infof("failed to find response by response ID: %+v", err)
return echo.NewHTTPError(http.StatusNotFound, fmt.Errorf("failed to find response by response ID: %w", err))
}
ctx.Logger().Errorf("failed to get questionnaire limit by response ID: %+v", err)
return echo.NewHTTPError(http.StatusInternalServerError, fmt.Errorf("failed to get questionnaire limit by response ID: %w", err))
}

if limit.Valid && limit.Time.Before(time.Now()) {
ctx.Logger().Info("unable to edit the expired response")
return echo.NewHTTPError(http.StatusMethodNotAllowed, fmt.Errorf("unable edit the expired response"))
}

err = r.IResponse.DeleteResponse(ctx.Request().Context(), responseID)
if err != nil {
ctx.Logger().Errorf("failed to delete response: %+v", err)
return echo.NewHTTPError(http.StatusInternalServerError, fmt.Errorf("failed to delete response: %w", err))
}

questions, err := r.IQuestion.GetQuestions(ctx.Request().Context(), req.QuestionnaireId)

responseMetas, err := responseBody2ResponseMetas(req.Body, questions)
if err != nil {
ctx.Logger().Errorf("failed to convert response body into response metas: %+v", err)
return echo.NewHTTPError(http.StatusInternalServerError, fmt.Errorf("failed to convert response body into response metas: %w", err))
}

if len(responseMetas) > 0 {
err = r.IResponse.InsertResponses(ctx.Request().Context(), responseID, responseMetas)
if err != nil {
ctx.Logger().Errorf("failed to insert responses: %+v", err)
return echo.NewHTTPError(http.StatusInternalServerError, fmt.Errorf("failed to insert responses: %w", err))
}
}

return nil
}
17 changes: 17 additions & 0 deletions handler/response.go
Original file line number Diff line number Diff line change
Expand Up @@ -60,5 +60,22 @@ func (h Handler) GetResponse(ctx echo.Context, responseID openapi.ResponseIDInPa

// (PATCH /responses/{responseID})
func (h Handler) EditResponse(ctx echo.Context, responseID openapi.ResponseIDInPath) error {
req := openapi.EditResponseJSONRequestBody{}
if err := ctx.Bind(&req); err != nil {
ctx.Logger().Errorf("failed to bind Responses: %+v", err)
return echo.NewHTTPError(http.StatusBadRequest, fmt.Errorf("failed to bind Responses: %w", err))
}

validate, err := getValidator(ctx)
if err != nil {
ctx.Logger().Errorf("failed to get validator: %+v", err)
return echo.NewHTTPError(http.StatusInternalServerError, fmt.Errorf("failed to get validator: %w", err))
}

err = validate.Struct(req)
if err != nil {
ctx.Logger().Errorf("failed to validate request body: %+v", err)
return echo.NewHTTPError(http.StatusBadRequest, fmt.Errorf("failed to validate request body: %w", err))
}
return ctx.NoContent(200)
}
Loading