2020-03-04 11:07:12 +00:00
package main
import (
"encoding/json"
2021-11-19 20:41:01 +00:00
"fmt"
2020-03-04 11:07:12 +00:00
"strconv"
2020-09-13 14:37:30 +00:00
"time"
2020-03-04 11:07:12 +00:00
"github.com/julienschmidt/httprouter"
)
func init ( ) {
router . POST ( "/api/surveys/:sid" , apiAuthHandler ( surveyAuthHandler ( func ( s Survey , u * User , body [ ] byte ) HTTPResponse {
var responses [ ] Response
if err := json . Unmarshal ( body , & responses ) ; err != nil {
2020-09-13 14:37:30 +00:00
return APIErrorResponse { err : err }
2020-03-04 11:07:12 +00:00
}
2021-11-19 20:41:01 +00:00
// Check the survey is open
now := time . Now ( )
if now . Before ( s . StartAvailability ) {
return APIErrorResponse { err : fmt . Errorf ( "Le questionnaire n'a pas encore commencé" ) }
} else if now . After ( s . EndAvailability ) {
return APIErrorResponse { err : fmt . Errorf ( "Le questionnaire n'est plus ouvert" ) }
}
2020-03-04 11:07:12 +00:00
for _ , response := range responses {
2020-03-08 00:06:44 +00:00
if len ( response . Answer ) > 0 {
if _ , err := s . NewResponse ( response . IdQuestion , u . Id , response . Answer ) ; err != nil {
2020-09-13 14:37:30 +00:00
return APIErrorResponse { err : err }
2020-03-08 00:06:44 +00:00
}
2020-03-04 11:07:12 +00:00
}
}
return APIResponse { true }
2020-03-08 00:06:44 +00:00
} ) , loggedUser ) )
2020-11-28 17:59:14 +00:00
router . POST ( "/api/users/:uid/surveys/:sid" , apiAuthHandler ( func ( u * User , ps httprouter . Params , body [ ] byte ) HTTPResponse {
return surveyAuthHandler ( func ( s Survey , u * User , _ [ ] byte ) HTTPResponse {
return userHandler ( func ( u User , _ [ ] byte ) HTTPResponse {
var responses [ ] Response
if err := json . Unmarshal ( body , & responses ) ; err != nil {
return APIErrorResponse { err : err }
}
for _ , response := range responses {
if len ( response . Answer ) > 0 {
if _ , err := s . NewResponse ( response . IdQuestion , u . Id , response . Answer ) ; err != nil {
return APIErrorResponse { err : err }
}
}
}
return APIResponse { true }
} ) ( ps , body )
} ) ( u , ps , body )
} , adminRestricted ) )
2020-03-04 11:07:12 +00:00
router . GET ( "/api/surveys/:sid/responses" , apiAuthHandler ( surveyAuthHandler (
func ( s Survey , u * User , _ [ ] byte ) HTTPResponse {
2020-03-08 00:06:44 +00:00
return formatApiResponse ( s . GetMyResponses ( u , s . Corrected ) )
} ) , loggedUser ) )
2020-11-28 17:59:14 +00:00
router . GET ( "/api/users/:uid/surveys/:sid/responses" , apiAuthHandler ( func ( u * User , ps httprouter . Params , body [ ] byte ) HTTPResponse {
return surveyAuthHandler ( func ( s Survey , u * User , _ [ ] byte ) HTTPResponse {
return userHandler ( func ( u User , _ [ ] byte ) HTTPResponse {
return formatApiResponse ( s . GetMyResponses ( & u , s . Corrected ) )
} ) ( ps , body )
} ) ( u , ps , body )
} , adminRestricted ) )
2020-03-04 11:07:12 +00:00
router . GET ( "/api/surveys/:sid/responses/:rid" , apiAuthHandler ( responseAuthHandler (
func ( r Response , _ * User , _ [ ] byte ) HTTPResponse {
return APIResponse { r }
2020-03-08 00:06:44 +00:00
} ) , adminRestricted ) )
router . GET ( "/api/surveys/:sid/questions/:qid/responses" , apiAuthHandler ( questionAuthHandler (
func ( q Question , u * User , _ [ ] byte ) HTTPResponse {
return formatApiResponse ( q . GetResponses ( ) )
} ) , adminRestricted ) )
router . PUT ( "/api/surveys/:sid/questions/:qid/responses/:rid" , apiAuthHandler ( responseAuthHandler ( func ( current Response , u * User , body [ ] byte ) HTTPResponse {
2020-03-04 11:07:12 +00:00
var new Response
if err := json . Unmarshal ( body , & new ) ; err != nil {
2020-09-13 14:37:30 +00:00
return APIErrorResponse { err : err }
2020-03-04 11:07:12 +00:00
}
2020-09-13 14:37:30 +00:00
if new . Score != nil && ( current . Score == nil || * new . Score != * current . Score ) {
2020-03-08 00:06:44 +00:00
now := time . Now ( )
new . IdCorrector = & u . Id
new . TimeScored = & now
}
2020-03-04 11:07:12 +00:00
new . Id = current . Id
new . IdUser = current . IdUser
return formatApiResponse ( new . Update ( ) )
2020-03-08 00:06:44 +00:00
} ) , adminRestricted ) )
2020-03-04 11:07:12 +00:00
}
func responseHandler ( f func ( Response , [ ] byte ) HTTPResponse ) func ( httprouter . Params , [ ] byte ) HTTPResponse {
return func ( ps httprouter . Params , body [ ] byte ) HTTPResponse {
var survey * Survey = nil
if sid , err := strconv . Atoi ( string ( ps . ByName ( "sid" ) ) ) ; err == nil {
if s , err := getSurvey ( sid ) ; err == nil {
survey = & s
}
}
if rid , err := strconv . Atoi ( string ( ps . ByName ( "rid" ) ) ) ; err != nil {
2020-09-13 14:37:30 +00:00
return APIErrorResponse { err : err }
2020-03-04 11:07:12 +00:00
} else if survey == nil {
if response , err := getResponse ( rid ) ; err != nil {
2020-09-13 14:37:30 +00:00
return APIErrorResponse { err : err }
2020-03-04 11:07:12 +00:00
} else {
return f ( response , body )
}
} else {
if response , err := survey . GetResponse ( rid ) ; err != nil {
2020-09-13 14:37:30 +00:00
return APIErrorResponse { err : err }
2020-03-04 11:07:12 +00:00
} else {
return f ( response , body )
}
}
}
}
func responseAuthHandler ( f func ( Response , * User , [ ] byte ) HTTPResponse ) func ( * User , httprouter . Params , [ ] byte ) HTTPResponse {
return func ( u * User , ps httprouter . Params , body [ ] byte ) HTTPResponse {
return responseHandler ( func ( r Response , body [ ] byte ) HTTPResponse {
return f ( r , u , body )
} ) ( ps , body )
}
}
type Response struct {
2020-03-08 00:06:44 +00:00
Id int64 ` json:"id" `
IdQuestion int64 ` json:"id_question" `
IdUser int64 ` json:"id_user" `
Answer string ` json:"value" `
TimeSubmit time . Time ` json:"time_submit" `
Score * int64 ` json:"score,omitempty" `
ScoreExplaination * string ` json:"score_explaination,omitempty" `
IdCorrector * int64 ` json:"id_corrector,omitempty" `
TimeScored * time . Time ` json:"time_scored,omitempty" `
2020-03-04 11:07:12 +00:00
}
func ( s * Survey ) GetResponses ( ) ( responses [ ] Response , err error ) {
if rows , errr := DBQuery ( "SELECT R.id_response, R.id_question, R.id_user, R.answer, R.time_submit, R.score, R.score_explanation, R.id_corrector, R.time_scored FROM survey_responses R INNER JOIN survey_quests Q ON Q.id_question = R.id_question WHERE Q.id_survey=?" , s . Id ) ; errr != nil {
return nil , errr
} else {
defer rows . Close ( )
for rows . Next ( ) {
var r Response
2020-03-08 00:06:44 +00:00
if err = rows . Scan ( & r . Id , & r . IdQuestion , & r . IdUser , & r . Answer , & r . TimeSubmit , & r . Score , & r . ScoreExplaination , & r . IdCorrector , & r . TimeScored ) ; err != nil {
2020-03-04 11:07:12 +00:00
return
}
responses = append ( responses , r )
}
if err = rows . Err ( ) ; err != nil {
return
}
return
}
}
2020-03-08 00:06:44 +00:00
func ( s * Survey ) GetMyResponses ( u * User , showScore bool ) ( responses [ ] Response , err error ) {
2020-03-04 11:07:12 +00:00
if rows , errr := DBQuery ( "SELECT R.id_response, R.id_question, R.id_user, R.answer, R.time_submit, R.score, R.score_explanation, R.id_corrector, R.time_scored FROM survey_responses R INNER JOIN survey_quests Q ON Q.id_question = R.id_question WHERE Q.id_survey=? AND R.id_user=? ORDER BY time_submit DESC" , s . Id , u . Id ) ; errr != nil {
return nil , errr
} else {
defer rows . Close ( )
for rows . Next ( ) {
var r Response
2020-03-08 00:06:44 +00:00
if err = rows . Scan ( & r . Id , & r . IdQuestion , & r . IdUser , & r . Answer , & r . TimeSubmit , & r . Score , & r . ScoreExplaination , & r . IdCorrector , & r . TimeScored ) ; err != nil {
return
}
if ! showScore {
r . Score = nil
r . ScoreExplaination = nil
}
responses = append ( responses , r )
}
if err = rows . Err ( ) ; err != nil {
return
}
return
}
}
func ( q * Question ) GetResponses ( ) ( responses [ ] Response , err error ) {
if rows , errr := DBQuery ( "SELECT id_response, id_question, S.id_user, answer, S.time_submit, score, score_explanation, id_corrector, time_scored FROM (SELECT id_user, MAX(time_submit) AS time_submit FROM survey_responses WHERE id_question=? GROUP BY id_user) R INNER JOIN survey_responses S ON S.id_user = R.id_user AND S.time_submit = R.time_submit AND S.id_question=?" , q . Id , q . Id ) ; errr != nil {
return nil , errr
} else {
defer rows . Close ( )
for rows . Next ( ) {
var r Response
if err = rows . Scan ( & r . Id , & r . IdQuestion , & r . IdUser , & r . Answer , & r . TimeSubmit , & r . Score , & r . ScoreExplaination , & r . IdCorrector , & r . TimeScored ) ; err != nil {
2020-03-04 11:07:12 +00:00
return
}
responses = append ( responses , r )
}
if err = rows . Err ( ) ; err != nil {
return
}
return
}
}
func getResponse ( id int ) ( r Response , err error ) {
2020-03-08 00:06:44 +00:00
err = DBQueryRow ( "SELECT id_response, id_question, id_user, answer, time_submit, score, score_explanation, id_corrector, time_scored FROM survey_responses WHERE id_response=?" , id ) . Scan ( & r . Id , & r . IdQuestion , & r . IdUser , & r . Answer , & r . TimeSubmit , & r . Score , & r . ScoreExplaination , & r . IdCorrector , & r . TimeScored )
2020-03-04 11:07:12 +00:00
return
}
func ( s * Survey ) GetResponse ( id int ) ( r Response , err error ) {
2020-03-08 00:06:44 +00:00
err = DBQueryRow ( "SELECT R.id_response, R.id_question, R.id_user, R.answer, R.time_submit, R.score, R.score_explanation, R.id_corrector, R.time_scored FROM survey_responses R INNER JOIN survey_quests Q ON Q.id_question = R.id_question WHERE R.id_response=? AND Q.id_survey=?" , id , s . Id ) . Scan ( & r . Id , & r . IdQuestion , & r . IdUser , & r . Answer , & r . TimeSubmit , & r . Score , & r . ScoreExplaination , & r . IdCorrector , & r . TimeScored )
2020-03-04 11:07:12 +00:00
return
}
func ( s * Survey ) NewResponse ( id_question int64 , id_user int64 , response string ) ( Response , error ) {
if res , err := DBExec ( "INSERT INTO survey_responses (id_question, id_user, answer, time_submit) VALUES (?, ?, ?, ?)" , id_question , id_user , response , time . Now ( ) ) ; err != nil {
return Response { } , err
} else if rid , err := res . LastInsertId ( ) ; err != nil {
return Response { } , err
} else {
return Response { rid , id_question , id_user , response , time . Now ( ) , nil , nil , nil , nil } , nil
}
}
func ( r Response ) Update ( ) ( Response , error ) {
2020-03-08 00:06:44 +00:00
_ , err := DBExec ( "UPDATE survey_responses SET id_question = ?, id_user = ?, answer = ?, time_submit = ?, score = ?, score_explanation = ?, id_corrector = ?, time_scored = ? WHERE id_response = ?" , r . IdQuestion , r . IdUser , r . Answer , r . TimeSubmit , r . Score , r . ScoreExplaination , r . IdCorrector , r . TimeScored , r . Id )
2020-03-04 11:07:12 +00:00
return r , err
}
func ( r Response ) Delete ( ) ( int64 , error ) {
if res , err := DBExec ( "DELETE FROM survey_responses WHERE id_response = ?" , r . Id ) ; err != nil {
return 0 , err
} else if nb , err := res . RowsAffected ( ) ; err != nil {
return 0 , err
} else {
return nb , err
}
}
func ClearResponses ( ) ( int64 , error ) {
if res , err := DBExec ( "DELETE FROM survey_responses" ) ; err != nil {
return 0 , err
} else if nb , err := res . RowsAffected ( ) ; err != nil {
return 0 , err
} else {
return nb , err
}
}