package history_admin import ( "fmt" "github.com/gofiber/fiber/v2" "go.uber.org/zap" "gitea.pena/PenaSide/customer/internal/interface/client" "gitea.pena/PenaSide/customer/internal/interface/controller/http" "gitea.pena/PenaSide/customer/internal/interface/repository" codeword_rpc "gitea.pena/PenaSide/customer/internal/proto/codeword" ) type Deps struct { MiddleWare *http.MiddleWare HistoryRepo *repository.HistoryRepository AccountRepo *repository.AccountRepository VerifyClient *client.VerificationClient AuthClient *client.AuthClient TemplateClient *client.TemplateClient CodewordClient *client.CodewordClient Logger *zap.Logger } type HistoryController struct { middleWare *http.MiddleWare historyRepo *repository.HistoryRepository accountRepo *repository.AccountRepository verifyClient *client.VerificationClient authClient *client.AuthClient templateClient *client.TemplateClient codewordClient *client.CodewordClient logger *zap.Logger } func NewHistoryController(deps Deps) *HistoryController { return &HistoryController{ middleWare: deps.MiddleWare, historyRepo: deps.HistoryRepo, authClient: deps.AuthClient, accountRepo: deps.AccountRepo, verifyClient: deps.VerifyClient, templateClient: deps.TemplateClient, codewordClient: deps.CodewordClient, logger: deps.Logger, } } func (receiver *HistoryController) CalculateLTV(ctx *fiber.Ctx) error { var req struct { From int64 `json:"from"` To int64 `json:"to"` } if err := ctx.BodyParser(&req); err != nil { receiver.logger.Error("failed to bind request", zap.Error(err)) return receiver.middleWare.Error(ctx, fiber.StatusBadRequest, "failed to bind request") } if req.From > req.To && req.To != 0 { receiver.logger.Error("From timestamp must be less than To timestamp unless To is 0") return receiver.middleWare.Error(ctx, fiber.StatusBadRequest, "From timestamp must be less than To timestamp unless To is 0") } ltv, err := receiver.historyRepo.CalculateCustomerLTV(ctx.Context(), req.From, req.To) if err != nil { receiver.logger.Error("failed to calculate LTV", zap.Error(err)) return receiver.middleWare.ErrorOld(ctx, err) } response := struct { LTV int64 `json:"LTV"` }{ LTV: ltv, } return ctx.Status(fiber.StatusOK).JSON(response) } func (receiver *HistoryController) QuizLogoStat(ctx *fiber.Ctx) error { var req struct { From *int `json:"from,omitempty"` Limit *int `json:"limit,omitempty"` Page *int `json:"page,omitempty"` To *int `json:"to,omitempty"` } if err := ctx.BodyParser(&req); err != nil { receiver.logger.Error("failed to bind request", zap.Error(err)) return receiver.middleWare.Error(ctx, fiber.StatusBadRequest, "failed to bind request") } result, err := receiver.accountRepo.QuizLogoStat(ctx.Context(), repository.QuizLogoStatDeps{ Page: req.Page, Limit: req.Limit, From: req.From, To: req.To, }) if err != nil { return receiver.middleWare.Error(ctx, fiber.StatusInternalServerError, fmt.Sprint("failed getting quiz logo stat", err.Error())) } return ctx.Status(fiber.StatusOK).JSON(result) } func (receiver *HistoryController) PromocodeLTV(ctx *fiber.Ctx) error { var req struct { From int `json:"from"` To int `json:"to"` } if err := ctx.BodyParser(&req); err != nil { receiver.logger.Error("failed to bind request", zap.Error(err)) return receiver.middleWare.Error(ctx, fiber.StatusBadRequest, "failed to bind request") } // получаем мапу вида [promoID] = []{userid,timeActivate} // отдаются только первые использованые на аккаунте промокоды, соответсвенно подсчет идет сугубо по ним // если в запросе время различается с временем активации - если меньше, то учитывается только после применения // если больше, то учитывается только с начала переданного from codewordData, err := receiver.codewordClient.GetAllPromoActivations(ctx.Context(), &codeword_rpc.Time{ To: int64(req.To), From: int64(req.From), }) if err != nil { return receiver.middleWare.Error(ctx, fiber.StatusInternalServerError, fmt.Sprint("failed getting codeword data", err.Error())) } userSumMap, er := receiver.historyRepo.GetPayUsersPromoHistory(ctx.Context(), codewordData, int64(req.From), int64(req.To)) if er != nil { return receiver.middleWare.Error(ctx, fiber.StatusInternalServerError, fmt.Sprint("failed calculate promo users paid sum", er.Error())) } resp := make(map[string]struct { Regs int Money int64 }) for promoID, data := range codewordData { fmt.Println("PROTOMOTO", promoID, data) for _, value := range data { paids, ok := userSumMap[value.UserID] if !ok { paids = 0 } fmt.Println("PROTOMOTO1", paids, value) if value.Time >= int64(req.From) && value.Time <= int64(req.To) { if _, ok := resp[promoID]; !ok { resp[promoID] = struct { Regs int Money int64 }{Regs: 1, Money: paids} continue } current := resp[promoID] current.Regs += 1 current.Money += paids resp[promoID] = current } } } return ctx.Status(fiber.StatusOK).JSON(resp) }