Files
tm_back/internal/feedback/service.go
T
n.nakhostin 0e14a11daf Add Company Feedback Statistics Endpoint and Update API Documentation
- Introduced a new endpoint to retrieve comprehensive feedback statistics for the authenticated user's company, including total likes, dislikes, and percentage calculations.
- Implemented the GetCompanyFeedbackStats method in the feedback handler to handle requests, ensuring proper authentication and error handling.
- Updated Swagger JSON, YAML, and Go documentation to accurately reflect the new endpoint, including detailed descriptions, parameters, and response formats for the CompanyFeedbackStatsResponse.
- Enhanced the feedback repository and service layers to support the new statistics functionality, improving the overall data handling capabilities of the tender management system.
- These changes enhance the usability and functionality of the API, providing valuable insights into company feedback statistics.
2025-08-25 13:39:35 +03:30

180 lines
5.2 KiB
Go

package feedback
import (
"context"
"tm/pkg/logger"
"tm/pkg/response"
)
// FeedbackService interface defines feedback business logic methods
type FeedbackService interface {
ToggleFeedback(ctx context.Context, req ToggleFeedbackForm, customerID *string, companyID *string) (*FeedbackResponse, error)
GetFeedback(ctx context.Context, id string) (*FeedbackResponse, error)
ListFeedback(ctx context.Context, criteria FeedbackSearchCriteria, limit, offset int) (*FeedbackListResponse, error)
DeleteFeedback(ctx context.Context, id string) error
GetFeedbackByTenderID(ctx context.Context, tenderID, companyID string) (*FeedbackResponse, error)
CompanyFeedbackStats(ctx context.Context, companyID string) (*CompanyFeedbackStatsResponse, error)
}
// feedbackService implements FeedbackService interface
type feedbackService struct {
feedbackRepo Repository
logger logger.Logger
}
// NewFeedbackService creates a new feedback service
func NewFeedbackService(feedbackRepo Repository, logger logger.Logger) FeedbackService {
return &feedbackService{
feedbackRepo: feedbackRepo,
logger: logger,
}
}
func (s *feedbackService) ToggleFeedback(ctx context.Context, req ToggleFeedbackForm, customerID *string, companyID *string) (*FeedbackResponse, error) {
existing, err := s.feedbackRepo.GetByCompanyID(ctx, *companyID, req.TenderID)
if err != nil {
feedback := &Feedback{
TenderID: req.TenderID,
FeedbackType: req.FeedbackType,
CompanyID: companyID,
CustomerID: customerID,
}
err = s.feedbackRepo.Create(ctx, feedback)
if err != nil {
s.logger.Error("Failed to create new feedback", map[string]interface{}{
"tender_id": req.TenderID,
"company_id": *companyID,
"error": err.Error(),
})
return nil, err
}
return feedback.ToResponse(), nil
}
if existing.FeedbackType == req.FeedbackType {
err = s.feedbackRepo.Delete(ctx, existing.GetID())
if err != nil {
s.logger.Error("Failed to update existing feedback", map[string]interface{}{
"feedback_id": existing.GetID(),
"tender_id": req.TenderID,
"company_id": *companyID,
"error": err.Error(),
})
return nil, err
}
if req.FeedbackType == FeedbackTypeLike {
existing.FeedbackType = "unlike"
} else {
existing.FeedbackType = "undislike"
}
return existing.ToResponse(), nil
}
if existing.FeedbackType == FeedbackTypeLike {
existing.FeedbackType = FeedbackTypeDislike
} else {
existing.FeedbackType = FeedbackTypeLike
}
err = s.feedbackRepo.Update(ctx, existing)
if err != nil {
s.logger.Error("Failed to update existing feedback", map[string]interface{}{
"feedback_id": existing.GetID(),
"tender_id": req.TenderID,
"company_id": *companyID,
"error": err.Error(),
})
return nil, err
}
return existing.ToResponse(), nil
}
func (s *feedbackService) GetFeedback(ctx context.Context, id string) (*FeedbackResponse, error) {
feedback, err := s.feedbackRepo.GetByID(ctx, id)
if err != nil {
s.logger.Error("Failed to get feedback", map[string]interface{}{
"id": id,
"error": err.Error(),
})
return nil, err
}
return feedback.ToResponse(), nil
}
func (s *feedbackService) ListFeedback(ctx context.Context, criteria FeedbackSearchCriteria, limit, offset int) (*FeedbackListResponse, error) {
feedbacks, total, err := s.feedbackRepo.List(ctx, criteria, limit, offset)
if err != nil {
s.logger.Error("Failed to list feedback", map[string]interface{}{
"criteria": criteria,
"limit": limit,
"offset": offset,
"error": err.Error(),
})
return nil, err
}
meta := &response.Meta{
Total: int(total),
Limit: limit,
Offset: offset,
Page: (offset / limit) + 1,
Pages: int((total + int64(limit) - 1) / int64(limit)),
}
result := make([]*FeedbackResponse, len(feedbacks))
for i, feedback := range feedbacks {
result[i] = feedback.ToResponse()
}
return &FeedbackListResponse{
Feedback: result,
Meta: meta,
}, nil
}
func (s *feedbackService) DeleteFeedback(ctx context.Context, id string) error {
return s.feedbackRepo.Delete(ctx, id)
}
func (s *feedbackService) GetFeedbackByTenderID(ctx context.Context, tenderID, companyID string) (*FeedbackResponse, error) {
feedback, err := s.feedbackRepo.GetByTenderID(ctx, tenderID, companyID)
if err != nil {
s.logger.Error("Failed to get feedback by tender ID", map[string]interface{}{
"tender_id": tenderID,
"error": err.Error(),
})
return nil, err
}
return feedback.ToResponse(), nil
}
func (s *feedbackService) CompanyFeedbackStats(ctx context.Context, companyID string) (*CompanyFeedbackStatsResponse, error) {
s.logger.Info("Getting company feedback statistics", map[string]interface{}{
"company_id": companyID,
})
stats, err := s.feedbackRepo.GetCompanyFeedbackStats(ctx, companyID)
if err != nil {
s.logger.Error("Failed to get company feedback statistics", map[string]interface{}{
"company_id": companyID,
"error": err.Error(),
})
return nil, err
}
s.logger.Info("Company feedback statistics retrieved successfully", map[string]interface{}{
"company_id": companyID,
"total_feedback": stats.TotalFeedback,
"total_likes": stats.TotalLikes,
"total_dislikes": stats.TotalDislikes,
})
return stats, nil
}