core/service/result_svc.go

219 lines
6.6 KiB
Go
Raw Normal View History

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)
}