2024-02-19 17:48:04 +00:00
|
|
|
package service
|
|
|
|
|
|
|
|
import (
|
|
|
|
"bytes"
|
|
|
|
"github.com/gofiber/fiber/v2"
|
2024-03-13 16:57:12 +00:00
|
|
|
"penahub.gitlab.yandexcloud.net/backend/quiz/common.git/middleware"
|
2024-02-19 17:48:04 +00:00
|
|
|
"penahub.gitlab.yandexcloud.net/backend/quiz/common.git/model"
|
|
|
|
"penahub.gitlab.yandexcloud.net/backend/quiz/common.git/repository/result"
|
2024-03-13 16:57:12 +00:00
|
|
|
"penahub.gitlab.yandexcloud.net/backend/quiz/core.git/tools"
|
2024-02-19 17:48:04 +00:00
|
|
|
"strconv"
|
|
|
|
"time"
|
|
|
|
)
|
|
|
|
|
|
|
|
type ReqExport struct {
|
|
|
|
To, From time.Time
|
|
|
|
New bool
|
|
|
|
Page uint64
|
|
|
|
Limit uint64
|
|
|
|
}
|
|
|
|
|
|
|
|
type ReqExportResponse struct {
|
|
|
|
TotalCount uint64 `json:"total_count"`
|
|
|
|
Results []model.AnswerExport `json:"results"`
|
|
|
|
}
|
|
|
|
|
|
|
|
func (s *Service) GetResultsByQuizID(ctx *fiber.Ctx) error {
|
|
|
|
payment := true // параметр для определения существования текущих привилегий юзера
|
|
|
|
|
|
|
|
accountID, ok := middleware.GetAccountId(ctx)
|
|
|
|
if !ok {
|
|
|
|
return ctx.Status(fiber.StatusUnauthorized).SendString("account id is required")
|
|
|
|
}
|
|
|
|
|
|
|
|
var req ReqExport
|
|
|
|
if err := ctx.BodyParser(&req); err != nil {
|
|
|
|
return ctx.Status(fiber.StatusBadRequest).SendString("Invalid request data")
|
|
|
|
}
|
|
|
|
|
|
|
|
quizIDStr := ctx.Params("quizId")
|
|
|
|
quizID, err := strconv.ParseUint(quizIDStr, 10, 64)
|
|
|
|
if err != nil {
|
|
|
|
return ctx.Status(fiber.StatusBadRequest).SendString("Invalid quiz ID format")
|
|
|
|
}
|
|
|
|
|
|
|
|
account, err := s.dal.AccountRepo.GetAccountByID(ctx.Context(), accountID)
|
|
|
|
if err != nil {
|
|
|
|
return ctx.Status(fiber.StatusInternalServerError).SendString(err.Error())
|
|
|
|
}
|
2024-03-13 16:57:12 +00:00
|
|
|
if _, cnt := account.Privileges["quizCnt"]; !cnt {
|
|
|
|
if _, unlim := account.Privileges["quizUnlimTime"]; !unlim {
|
|
|
|
payment = false
|
|
|
|
}
|
2024-02-19 17:48:04 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
results, totalCount, err := s.dal.ResultRepo.GetQuizResults(ctx.Context(), quizID, result.GetQuizResDeps{
|
|
|
|
To: req.To,
|
|
|
|
From: req.From,
|
|
|
|
New: req.New,
|
|
|
|
Page: req.Page,
|
|
|
|
Limit: req.Limit,
|
|
|
|
}, payment)
|
|
|
|
if err != nil {
|
|
|
|
return ctx.Status(fiber.StatusInternalServerError).SendString(err.Error())
|
|
|
|
}
|
|
|
|
|
|
|
|
resp := &ReqExportResponse{
|
|
|
|
TotalCount: totalCount,
|
|
|
|
Results: results,
|
|
|
|
}
|
|
|
|
|
|
|
|
return ctx.Status(fiber.StatusOK).JSON(resp)
|
|
|
|
}
|
|
|
|
|
|
|
|
func (s *Service) DelResultByID(ctx *fiber.Ctx) error {
|
|
|
|
accountID, ok := middleware.GetAccountId(ctx)
|
|
|
|
if !ok {
|
|
|
|
return ctx.Status(fiber.StatusUnauthorized).SendString("could not get account ID from token")
|
|
|
|
}
|
|
|
|
|
|
|
|
resultIDStr := ctx.Params("resultId")
|
|
|
|
resultID, err := strconv.ParseUint(resultIDStr, 10, 64)
|
|
|
|
if err != nil {
|
|
|
|
return ctx.Status(fiber.StatusBadRequest).SendString("Invalid result ID format")
|
|
|
|
}
|
|
|
|
|
|
|
|
isOwner, err := s.dal.ResultRepo.CheckResultOwner(ctx.Context(), resultID, accountID)
|
|
|
|
if err != nil {
|
|
|
|
return ctx.Status(fiber.StatusInternalServerError).SendString(err.Error())
|
|
|
|
}
|
|
|
|
|
|
|
|
if !isOwner {
|
|
|
|
return ctx.Status(fiber.StatusUnauthorized).SendString("not the owner of the result")
|
|
|
|
}
|
|
|
|
|
|
|
|
if err := s.dal.ResultRepo.SoftDeleteResultByID(ctx.Context(), resultID); err != nil {
|
|
|
|
return ctx.Status(fiber.StatusInternalServerError).SendString(err.Error())
|
|
|
|
}
|
|
|
|
|
|
|
|
ctx.Status(fiber.StatusOK)
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
|
|
|
type ReqSeen struct {
|
|
|
|
Answers []int64
|
|
|
|
}
|
|
|
|
|
|
|
|
func (s *Service) SetStatus(ctx *fiber.Ctx) error {
|
|
|
|
var req ReqSeen
|
|
|
|
if err := ctx.BodyParser(&req); err != nil {
|
|
|
|
return ctx.Status(fiber.StatusBadRequest).SendString("Invalid request data")
|
|
|
|
}
|
|
|
|
|
|
|
|
accountID, ok := middleware.GetAccountId(ctx)
|
|
|
|
if !ok {
|
|
|
|
return ctx.Status(fiber.StatusUnauthorized).SendString("could not get account ID from token")
|
|
|
|
}
|
|
|
|
|
|
|
|
answers, err := s.dal.ResultRepo.CheckResultsOwner(ctx.Context(), req.Answers, accountID)
|
|
|
|
if err != nil {
|
|
|
|
return ctx.Status(fiber.StatusInternalServerError).SendString(err.Error())
|
|
|
|
}
|
|
|
|
|
|
|
|
if len(answers) != len(req.Answers) {
|
|
|
|
return ctx.Status(fiber.StatusNotAcceptable).SendString("could not update some answers because you don't have rights")
|
|
|
|
}
|
|
|
|
|
|
|
|
if err := s.dal.ResultRepo.UpdateAnswersStatus(ctx.Context(), accountID, answers); err != nil {
|
|
|
|
return ctx.Status(fiber.StatusInternalServerError).SendString(err.Error())
|
|
|
|
}
|
|
|
|
|
|
|
|
return ctx.Status(fiber.StatusOK).JSON(nil)
|
|
|
|
}
|
|
|
|
|
|
|
|
func (s *Service) ExportResultsToCSV(ctx *fiber.Ctx) error {
|
|
|
|
accountID, ok := middleware.GetAccountId(ctx)
|
|
|
|
if !ok {
|
|
|
|
return ctx.Status(fiber.StatusUnauthorized).SendString("account id is required")
|
|
|
|
}
|
|
|
|
|
|
|
|
quizIDStr := ctx.Params("quizID")
|
|
|
|
quizID, err := strconv.ParseUint(quizIDStr, 10, 64)
|
|
|
|
if err != nil {
|
|
|
|
return ctx.Status(fiber.StatusBadRequest).SendString("invalid quiz ID")
|
|
|
|
}
|
|
|
|
|
|
|
|
req := ReqExport{}
|
|
|
|
if err := ctx.BodyParser(&req); err != nil {
|
|
|
|
return ctx.Status(fiber.StatusBadRequest).SendString("invalid request body")
|
|
|
|
}
|
|
|
|
|
|
|
|
account, err := s.dal.AccountRepo.GetAccountByID(ctx.Context(), accountID)
|
|
|
|
if err != nil {
|
|
|
|
return ctx.Status(fiber.StatusInternalServerError).SendString(err.Error())
|
|
|
|
}
|
|
|
|
|
2024-03-13 16:57:12 +00:00
|
|
|
if _, cnt := account.Privileges["quizCnt"]; !cnt {
|
|
|
|
if _, unlim := account.Privileges["quizUnlimTime"]; !unlim {
|
|
|
|
return ctx.Status(fiber.StatusPaymentRequired).SendString("payment required")
|
|
|
|
}
|
2024-02-19 17:48:04 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
questions, err := s.dal.ResultRepo.GetQuestions(ctx.Context(), quizID)
|
|
|
|
if err != nil {
|
|
|
|
return ctx.Status(fiber.StatusInternalServerError).SendString("failed to get questions")
|
|
|
|
}
|
|
|
|
|
|
|
|
answers, err := s.dal.ResultRepo.GetQuizResultsCSV(ctx.Context(), quizID, result.GetQuizResDeps{
|
|
|
|
To: req.To,
|
|
|
|
From: req.From,
|
|
|
|
New: req.New,
|
|
|
|
Page: req.Page,
|
|
|
|
Limit: req.Limit,
|
|
|
|
})
|
|
|
|
if err != nil {
|
|
|
|
return ctx.Status(fiber.StatusInternalServerError).SendString("failed to get quiz results")
|
|
|
|
}
|
|
|
|
|
|
|
|
buffer := new(bytes.Buffer)
|
|
|
|
|
2024-03-13 16:57:12 +00:00
|
|
|
if err := tools.WriteDataToExcel(buffer, questions, answers); err != nil {
|
2024-02-19 17:48:04 +00:00
|
|
|
return ctx.Status(fiber.StatusInternalServerError).SendString("failed to write data to Excel")
|
|
|
|
}
|
|
|
|
|
|
|
|
ctx.Set(fiber.HeaderContentType, "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet")
|
|
|
|
ctx.Set(fiber.HeaderContentDisposition, `attachment; filename="results.xlsx"`)
|
|
|
|
|
|
|
|
return ctx.Send(buffer.Bytes())
|
|
|
|
}
|
|
|
|
|
|
|
|
func (s *Service) GetResultAnswers(ctx *fiber.Ctx) error {
|
|
|
|
accountID, ok := middleware.GetAccountId(ctx)
|
|
|
|
if !ok {
|
|
|
|
return ctx.Status(fiber.StatusUnauthorized).SendString("account id is required")
|
|
|
|
}
|
|
|
|
|
|
|
|
resultID, err := strconv.ParseUint(ctx.Params("resultID"), 10, 64)
|
|
|
|
if err != nil {
|
|
|
|
return ctx.Status(fiber.StatusBadRequest).SendString("invalid quiz ID")
|
|
|
|
}
|
|
|
|
|
|
|
|
account, err := s.dal.AccountRepo.GetAccountByID(ctx.Context(), accountID)
|
|
|
|
if err != nil {
|
|
|
|
return ctx.Status(fiber.StatusInternalServerError).SendString(err.Error())
|
|
|
|
}
|
|
|
|
|
2024-03-13 16:57:12 +00:00
|
|
|
if _, cnt := account.Privileges["quizCnt"]; !cnt {
|
|
|
|
if _, unlim := account.Privileges["quizUnlimTime"]; !unlim {
|
|
|
|
return ctx.Status(fiber.StatusPaymentRequired).SendString("payment required")
|
|
|
|
}
|
2024-02-19 17:48:04 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
answers, err := s.dal.ResultRepo.GetResultAnswers(ctx.Context(), resultID)
|
|
|
|
if err != nil {
|
|
|
|
return ctx.Status(fiber.StatusInternalServerError).SendString("failed to get result answers")
|
|
|
|
}
|
|
|
|
|
|
|
|
return ctx.JSON(answers)
|
|
|
|
}
|