Refactor Feedback Service to Include Tender Information in Responses
- Updated the FeedbackService to include a new dependency on TenderService, allowing feedback responses to include associated tender details. - Modified the ListFeedback method to return a new FeedbackListWithTenderResponse type, which includes feedback along with tender information. - Enhanced the feedback entity and form structures to support the new response format, improving the API's capability to provide comprehensive feedback data. - Adjusted the main application initialization to reflect the changes in the feedback service dependencies.
This commit is contained in:
+1
-1
@@ -127,7 +127,7 @@ func main() {
|
|||||||
companyService := company.NewCompanyService(companyRepository, logger)
|
companyService := company.NewCompanyService(companyRepository, logger)
|
||||||
customerService := customer.NewCustomerService(customerRepository, logger, customerAuthService, companyService)
|
customerService := customer.NewCustomerService(customerRepository, logger, customerAuthService, companyService)
|
||||||
tenderService := tender.NewTenderService(tenderRepository, companyService, logger)
|
tenderService := tender.NewTenderService(tenderRepository, companyService, logger)
|
||||||
feedbackService := feedback.NewFeedbackService(feedbackRepo, logger)
|
feedbackService := feedback.NewFeedbackService(feedbackRepo, tenderService, logger)
|
||||||
tenderApprovalService := tender_approval.NewTenderApprovalService(tenderApprovalRepository, tenderService, logger)
|
tenderApprovalService := tender_approval.NewTenderApprovalService(tenderApprovalRepository, tenderService, logger)
|
||||||
logger.Info("Services initialized successfully", map[string]interface{}{
|
logger.Info("Services initialized successfully", map[string]interface{}{
|
||||||
"services": []string{"customer", "user", "company", "tender", "feedback", "tender_approval"},
|
"services": []string{"customer", "user", "company", "tender", "feedback", "tender_approval"},
|
||||||
|
|||||||
@@ -3,7 +3,6 @@ package feedback
|
|||||||
import (
|
import (
|
||||||
"time"
|
"time"
|
||||||
"tm/pkg/mongo"
|
"tm/pkg/mongo"
|
||||||
"tm/pkg/response"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// FeedbackType represents the type of feedback
|
// FeedbackType represents the type of feedback
|
||||||
@@ -43,12 +42,6 @@ type FeedbackSearchCriteria struct {
|
|||||||
Offset int `json:"offset,omitempty"`
|
Offset int `json:"offset,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// FeedbackListResponse represents a paginated list of feedback
|
|
||||||
type FeedbackListResponse struct {
|
|
||||||
Feedback []*FeedbackResponse `json:"feedback"`
|
|
||||||
Meta *response.Meta `json:"meta"`
|
|
||||||
}
|
|
||||||
|
|
||||||
// GetID returns the feedback ID
|
// GetID returns the feedback ID
|
||||||
func (f *Feedback) GetID() string {
|
func (f *Feedback) GetID() string {
|
||||||
return f.ID.Hex()
|
return f.ID.Hex()
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ package feedback
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"time"
|
"time"
|
||||||
|
"tm/pkg/response"
|
||||||
)
|
)
|
||||||
|
|
||||||
// ListFeedbackForm represents the form for listing feedback
|
// ListFeedbackForm represents the form for listing feedback
|
||||||
@@ -30,6 +31,53 @@ type FeedbackResponse struct {
|
|||||||
CompanyId *string `json:"company_id"`
|
CompanyId *string `json:"company_id"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// FeedbackListResponse represents a paginated list of feedback
|
||||||
|
type FeedbackListResponse struct {
|
||||||
|
Feedback []*FeedbackResponse `json:"feedback"`
|
||||||
|
Meta *response.Meta `json:"meta"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// FeedbackListResponse represents a paginated list of feedback
|
||||||
|
type FeedbackListWithTenderResponse struct {
|
||||||
|
Feedback []*FeedbackWithTenderResponse `json:"feedback"`
|
||||||
|
Meta *response.Meta `json:"meta"`
|
||||||
|
}
|
||||||
|
type FeedbackWithTenderResponse struct {
|
||||||
|
ID string `json:"id"`
|
||||||
|
FeedbackType FeedbackType `json:"feedback_type"`
|
||||||
|
UpdatedAt int64 `json:"updated_at"`
|
||||||
|
CreatedAt int64 `json:"created_at"`
|
||||||
|
TenderID string `json:"tender_id"`
|
||||||
|
CustomerID *string `json:"customer_id"`
|
||||||
|
CompanyId *string `json:"company_id"`
|
||||||
|
Tender *tenderDetails `json:"tender"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// tenderDetails represents essential tender information for the response
|
||||||
|
type (
|
||||||
|
tenderDetails struct {
|
||||||
|
ID string `json:"id"`
|
||||||
|
NoticePublicationID string `json:"notice_publication_id"`
|
||||||
|
PublicationDate int64 `json:"publication_date"`
|
||||||
|
Title string `json:"title"`
|
||||||
|
Description string `json:"description"`
|
||||||
|
ProcurementTypeCode string `json:"procurement_type_code"`
|
||||||
|
ProcedureCode string `json:"procedure_code"`
|
||||||
|
EstimatedValue float64 `json:"estimated_value"`
|
||||||
|
Currency string `json:"currency"`
|
||||||
|
Duration string `json:"duration"`
|
||||||
|
DurationUnit string `json:"duration_unit"`
|
||||||
|
TenderDeadline int64 `json:"tender_deadline"`
|
||||||
|
SubmissionDeadline int64 `json:"submission_deadline"`
|
||||||
|
CountryCode string `json:"country_code"`
|
||||||
|
BuyerOrganization *organizationResponse `json:"buyer_organization"`
|
||||||
|
Status string `json:"status"`
|
||||||
|
}
|
||||||
|
organizationResponse struct {
|
||||||
|
Name string `json:"name"`
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
// CompanyFeedbackStatsResponse represents the response for company feedback statistics
|
// CompanyFeedbackStatsResponse represents the response for company feedback statistics
|
||||||
type CompanyFeedbackStatsResponse struct {
|
type CompanyFeedbackStatsResponse struct {
|
||||||
CompanyID string `json:"company_id"`
|
CompanyID string `json:"company_id"`
|
||||||
@@ -68,3 +116,16 @@ func (f *Feedback) ToResponse() *FeedbackResponse {
|
|||||||
CreatedAt: f.CreatedAt,
|
CreatedAt: f.CreatedAt,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (f *Feedback) ToResponseWithTender(tender *tenderDetails) *FeedbackWithTenderResponse {
|
||||||
|
return &FeedbackWithTenderResponse{
|
||||||
|
ID: f.ID.Hex(),
|
||||||
|
FeedbackType: f.FeedbackType,
|
||||||
|
TenderID: f.TenderID,
|
||||||
|
CustomerID: f.CustomerID,
|
||||||
|
CompanyId: f.CompanyID,
|
||||||
|
UpdatedAt: f.UpdatedAt,
|
||||||
|
CreatedAt: f.CreatedAt,
|
||||||
|
Tender: tender,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ package feedback
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
"tm/internal/tender"
|
||||||
"tm/pkg/logger"
|
"tm/pkg/logger"
|
||||||
"tm/pkg/response"
|
"tm/pkg/response"
|
||||||
)
|
)
|
||||||
@@ -10,7 +11,7 @@ import (
|
|||||||
type FeedbackService interface {
|
type FeedbackService interface {
|
||||||
ToggleFeedback(ctx context.Context, req ToggleFeedbackForm, customerID *string, companyID *string) (*FeedbackResponse, error)
|
ToggleFeedback(ctx context.Context, req ToggleFeedbackForm, customerID *string, companyID *string) (*FeedbackResponse, error)
|
||||||
GetFeedback(ctx context.Context, id string) (*FeedbackResponse, error)
|
GetFeedback(ctx context.Context, id string) (*FeedbackResponse, error)
|
||||||
ListFeedback(ctx context.Context, criteria FeedbackSearchCriteria, limit, offset int) (*FeedbackListResponse, error)
|
ListFeedback(ctx context.Context, criteria FeedbackSearchCriteria, limit, offset int) (*FeedbackListWithTenderResponse, error)
|
||||||
DeleteFeedback(ctx context.Context, id string) error
|
DeleteFeedback(ctx context.Context, id string) error
|
||||||
GetFeedbackByTenderID(ctx context.Context, tenderID, companyID string) (*FeedbackResponse, error)
|
GetFeedbackByTenderID(ctx context.Context, tenderID, companyID string) (*FeedbackResponse, error)
|
||||||
CompanyFeedbackStats(ctx context.Context, companyID string) (*CompanyFeedbackStatsResponse, error)
|
CompanyFeedbackStats(ctx context.Context, companyID string) (*CompanyFeedbackStatsResponse, error)
|
||||||
@@ -18,15 +19,17 @@ type FeedbackService interface {
|
|||||||
|
|
||||||
// feedbackService implements FeedbackService interface
|
// feedbackService implements FeedbackService interface
|
||||||
type feedbackService struct {
|
type feedbackService struct {
|
||||||
feedbackRepo Repository
|
feedbackRepo Repository
|
||||||
logger logger.Logger
|
tenderService tender.TenderService
|
||||||
|
logger logger.Logger
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewFeedbackService creates a new feedback service
|
// NewFeedbackService creates a new feedback service
|
||||||
func NewFeedbackService(feedbackRepo Repository, logger logger.Logger) FeedbackService {
|
func NewFeedbackService(feedbackRepo Repository, tenderService tender.TenderService, logger logger.Logger) FeedbackService {
|
||||||
return &feedbackService{
|
return &feedbackService{
|
||||||
feedbackRepo: feedbackRepo,
|
feedbackRepo: feedbackRepo,
|
||||||
logger: logger,
|
tenderService: tenderService,
|
||||||
|
logger: logger,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -108,7 +111,7 @@ func (s *feedbackService) GetFeedback(ctx context.Context, id string) (*Feedback
|
|||||||
return feedback.ToResponse(), nil
|
return feedback.ToResponse(), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *feedbackService) ListFeedback(ctx context.Context, criteria FeedbackSearchCriteria, limit, offset int) (*FeedbackListResponse, error) {
|
func (s *feedbackService) ListFeedback(ctx context.Context, criteria FeedbackSearchCriteria, limit, offset int) (*FeedbackListWithTenderResponse, error) {
|
||||||
feedbacks, total, err := s.feedbackRepo.List(ctx, criteria, limit, offset)
|
feedbacks, total, err := s.feedbackRepo.List(ctx, criteria, limit, offset)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
s.logger.Error("Failed to list feedback", map[string]interface{}{
|
s.logger.Error("Failed to list feedback", map[string]interface{}{
|
||||||
@@ -128,11 +131,37 @@ func (s *feedbackService) ListFeedback(ctx context.Context, criteria FeedbackSea
|
|||||||
Pages: int((total + int64(limit) - 1) / int64(limit)),
|
Pages: int((total + int64(limit) - 1) / int64(limit)),
|
||||||
}
|
}
|
||||||
|
|
||||||
result := make([]*FeedbackResponse, len(feedbacks))
|
result := make([]*FeedbackWithTenderResponse, len(feedbacks))
|
||||||
for i, feedback := range feedbacks {
|
for i, feedback := range feedbacks {
|
||||||
result[i] = feedback.ToResponse()
|
tender, err := s.tenderService.GetTenderByID(ctx, feedback.TenderID)
|
||||||
|
if err != nil {
|
||||||
|
s.logger.Error("Failed to get tender", map[string]interface{}{
|
||||||
|
"tender_id": feedback.TenderID,
|
||||||
|
"error": err.Error(),
|
||||||
|
})
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
resp := feedback.ToResponseWithTender(&tenderDetails{
|
||||||
|
ID: tender.ID,
|
||||||
|
NoticePublicationID: tender.NoticePublicationID,
|
||||||
|
PublicationDate: tender.PublicationDate,
|
||||||
|
Title: tender.Title,
|
||||||
|
Description: tender.Description,
|
||||||
|
ProcurementTypeCode: tender.ProcurementTypeCode,
|
||||||
|
ProcedureCode: tender.ProcedureCode,
|
||||||
|
EstimatedValue: tender.EstimatedValue,
|
||||||
|
Currency: tender.Currency,
|
||||||
|
Duration: tender.Duration,
|
||||||
|
DurationUnit: tender.DurationUnit,
|
||||||
|
TenderDeadline: tender.TenderDeadline,
|
||||||
|
SubmissionDeadline: tender.SubmissionDeadline,
|
||||||
|
CountryCode: tender.CountryCode,
|
||||||
|
BuyerOrganization: &organizationResponse{Name: tender.BuyerOrganization.Name},
|
||||||
|
Status: string(tender.Status),
|
||||||
|
})
|
||||||
|
result[i] = resp
|
||||||
}
|
}
|
||||||
return &FeedbackListResponse{
|
return &FeedbackListWithTenderResponse{
|
||||||
Feedback: result,
|
Feedback: result,
|
||||||
Meta: meta,
|
Meta: meta,
|
||||||
}, nil
|
}, nil
|
||||||
|
|||||||
@@ -347,21 +347,21 @@ func (h *TenderHandler) RecommendTenders(c echo.Context) error {
|
|||||||
companyID = &customerCompanyID
|
companyID = &customerCompanyID
|
||||||
}
|
}
|
||||||
|
|
||||||
from := int64(0)
|
var from *int64
|
||||||
if fromParam := c.QueryParam("publication_from"); fromParam != "" {
|
if fromParam := c.QueryParam("publication_from"); fromParam != "" {
|
||||||
if parsed, err := strconv.ParseInt(fromParam, 10, 64); err == nil {
|
if parsed, err := strconv.ParseInt(fromParam, 10, 64); err == nil {
|
||||||
from = parsed
|
from = &parsed
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
to := int64(0)
|
var to *int64
|
||||||
if toParam := c.QueryParam("publication_to"); toParam != "" {
|
if toParam := c.QueryParam("publication_to"); toParam != "" {
|
||||||
if parsed, err := strconv.ParseInt(toParam, 10, 64); err == nil {
|
if parsed, err := strconv.ParseInt(toParam, 10, 64); err == nil {
|
||||||
to = parsed
|
to = &parsed
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
result, err := h.service.RecommendTenders(c.Request().Context(), companyID, &from, &to, limit, offset)
|
result, err := h.service.RecommendTenders(c.Request().Context(), companyID, from, to, limit, offset)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return response.InternalServerError(c, "Failed to retrieve tenders")
|
return response.InternalServerError(c, "Failed to retrieve tenders")
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user