Enhance tender service to exclude company-rejected tenders from recommendations
- Updated the tender service to include a new dependency for listing rejected tenders by company, allowing for more refined tender recommendations. - Introduced a new field in the SearchForm to specify whether to exclude rejected tenders from the recommendation results. - Enhanced the Recommend method to filter out rejected tenders based on the new exclusion logic, improving the relevance of AI-ranked tender recommendations. - Added unit tests to verify the exclusion logic for rejected tenders, ensuring robust functionality. This update improves the tender recommendation process by ensuring that company-rejected tenders are not included in the results, enhancing user experience and satisfaction.
This commit is contained in:
@@ -176,7 +176,7 @@ func (h *Handler) PublicGetTenderApprovals(c echo.Context) error {
|
||||
submissionMode = &mode
|
||||
}
|
||||
|
||||
// Parse status filter; default to submitted so "Your Tenders" excludes rejected approvals
|
||||
// Parse status filter
|
||||
var status *ApprovalStatus
|
||||
if statusStr != "" {
|
||||
statusVal := ApprovalStatus(statusStr)
|
||||
@@ -184,9 +184,6 @@ func (h *Handler) PublicGetTenderApprovals(c echo.Context) error {
|
||||
return response.BadRequest(c, "Invalid status value", "Must be 'submitted' or 'rejected'")
|
||||
}
|
||||
status = &statusVal
|
||||
} else {
|
||||
defaultStatus := ApprovalStatusSubmitted
|
||||
status = &defaultStatus
|
||||
}
|
||||
|
||||
var from *int64
|
||||
|
||||
@@ -3,11 +3,13 @@ package tender_approval
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"strings"
|
||||
"time"
|
||||
"tm/pkg/logger"
|
||||
"tm/pkg/mongo"
|
||||
|
||||
"go.mongodb.org/mongo-driver/v2/bson"
|
||||
mongodriver "go.mongodb.org/mongo-driver/v2/mongo"
|
||||
)
|
||||
|
||||
// Repository defines the interface for tender approval data operations
|
||||
@@ -30,6 +32,7 @@ type Repository interface {
|
||||
GetTenderApprovalStats(ctx context.Context) (*TenderApprovalStatsResponse, error)
|
||||
GetCompanyTenderApprovalStats(ctx context.Context, companyID string) (*CompanyTenderApprovalStatsResponse, error)
|
||||
SearchByCriteria(ctx context.Context, criteria *TenderApprovalSearchCriteria) ([]*TenderApproval, error)
|
||||
ListRejectedTenderIDsByCompanyID(ctx context.Context, companyID string) ([]string, error)
|
||||
}
|
||||
|
||||
// tenderApprovalRepository implements the Repository interface using the MongoDB ORM
|
||||
@@ -533,6 +536,28 @@ func (r *tenderApprovalRepository) GetCompanyTenderApprovalStats(ctx context.Con
|
||||
return stats, nil
|
||||
}
|
||||
|
||||
// ListRejectedTenderIDsByCompanyID returns distinct tender IDs rejected by a company.
|
||||
func (r *tenderApprovalRepository) ListRejectedTenderIDsByCompanyID(ctx context.Context, companyID string) ([]string, error) {
|
||||
pipeline := mongodriver.Pipeline{
|
||||
{{Key: "$match", Value: bson.M{
|
||||
"company_id": companyID,
|
||||
"status": string(ApprovalStatusRejected),
|
||||
}}},
|
||||
{{Key: "$group", Value: bson.M{"_id": "$tender_id"}}},
|
||||
}
|
||||
|
||||
results, err := r.ormRepo.Aggregate(ctx, pipeline)
|
||||
if err != nil {
|
||||
r.logger.Error("Failed to list rejected tender IDs by company", map[string]interface{}{
|
||||
"company_id": companyID,
|
||||
"error": err.Error(),
|
||||
})
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return aggregateStringIDs(results), nil
|
||||
}
|
||||
|
||||
// SearchByCriteria searches tender approvals using search criteria
|
||||
func (r *tenderApprovalRepository) SearchByCriteria(ctx context.Context, criteria *TenderApprovalSearchCriteria) ([]*TenderApproval, error) {
|
||||
// Convert criteria to search parameters
|
||||
@@ -549,3 +574,16 @@ func (r *tenderApprovalRepository) SearchByCriteria(ctx context.Context, criteri
|
||||
// Use the search method
|
||||
return r.Search(ctx, criteria.TenderID, criteria.CompanyID, status, submissionMode, criteria.CreatedAtFrom, criteria.CreatedAtTo, criteria.Limit, criteria.Offset, "created_at", "desc")
|
||||
}
|
||||
|
||||
func aggregateStringIDs(results []bson.M) []string {
|
||||
ids := make([]string, 0, len(results))
|
||||
for _, result := range results {
|
||||
switch id := result["_id"].(type) {
|
||||
case string:
|
||||
if strings.TrimSpace(id) != "" {
|
||||
ids = append(ids, id)
|
||||
}
|
||||
}
|
||||
}
|
||||
return ids
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user