added AI auto-generated keywords to customer profile
This commit is contained in:
+86
-24
@@ -3,8 +3,10 @@ package tender
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"strings"
|
||||
"time"
|
||||
"tm/internal/company"
|
||||
"tm/internal/customer"
|
||||
"tm/pkg/logger"
|
||||
"tm/pkg/response"
|
||||
)
|
||||
@@ -26,17 +28,19 @@ type Service interface {
|
||||
|
||||
// tenderService implements TenderService interface
|
||||
type tenderService struct {
|
||||
repository TenderRepository
|
||||
companyService company.Service
|
||||
logger logger.Logger
|
||||
repository TenderRepository
|
||||
companyService company.Service
|
||||
customerService customer.Service
|
||||
logger logger.Logger
|
||||
}
|
||||
|
||||
// NewService creates a new tender service
|
||||
func NewService(repository TenderRepository, companyService company.Service, logger logger.Logger) Service {
|
||||
func NewService(repository TenderRepository, companyService company.Service, customerService customer.Service, logger logger.Logger) Service {
|
||||
return &tenderService{
|
||||
repository: repository,
|
||||
companyService: companyService,
|
||||
logger: logger,
|
||||
repository: repository,
|
||||
companyService: companyService,
|
||||
customerService: customerService,
|
||||
logger: logger,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -156,8 +160,8 @@ func (s *tenderService) GetDocumentSummaries(ctx context.Context, id string) ([]
|
||||
}
|
||||
|
||||
s.logger.Info("Retrieved document summaries for tender", map[string]interface{}{
|
||||
"tender_id": id,
|
||||
"summaries_count": len(tender.DocumentSummaries),
|
||||
"tender_id": id,
|
||||
"summaries_count": len(tender.DocumentSummaries),
|
||||
})
|
||||
|
||||
return tender.DocumentSummaries, nil
|
||||
@@ -166,13 +170,41 @@ func (s *tenderService) GetDocumentSummaries(ctx context.Context, id string) ([]
|
||||
// ListTenders retrieves tenders with pagination and filtering
|
||||
func (s *tenderService) Search(ctx context.Context, form *SearchForm, pagination *response.Pagination) (*SearchResponse, error) {
|
||||
s.logger.Info("Listing tenders", map[string]interface{}{
|
||||
"limit": pagination.Limit,
|
||||
"offset": pagination.Offset,
|
||||
"company_id": form.CompanyID,
|
||||
"from": form.DeadlineFrom,
|
||||
"to": form.DeadlineTo,
|
||||
"limit": pagination.Limit,
|
||||
"offset": pagination.Offset,
|
||||
"company_id": form.CompanyID,
|
||||
"customer_id": form.CustomerID,
|
||||
"from": form.DeadlineFrom,
|
||||
"to": form.DeadlineTo,
|
||||
})
|
||||
|
||||
// If customer ID is provided, get customer keywords and add to search
|
||||
if form.CustomerID != nil && *form.CustomerID != "" {
|
||||
customerResp, err := s.customerService.GetByID(ctx, *form.CustomerID)
|
||||
if err == nil && customerResp != nil {
|
||||
// Only use keywords if status is ready
|
||||
if customerResp.KeywordsStatus == "ready" && len(customerResp.Keywords) > 0 {
|
||||
// Combine customer keywords with existing search query
|
||||
keywordsQuery := strings.Join(customerResp.Keywords, " ")
|
||||
if form.Search != nil && *form.Search != "" {
|
||||
combinedSearch := *form.Search + " " + keywordsQuery
|
||||
form.Search = &combinedSearch
|
||||
} else {
|
||||
form.Search = &keywordsQuery
|
||||
}
|
||||
s.logger.Info("Using customer keywords for search", map[string]interface{}{
|
||||
"customer_id": *form.CustomerID,
|
||||
"keywords": customerResp.Keywords,
|
||||
})
|
||||
} else {
|
||||
s.logger.Info("Customer keywords not ready, skipping keyword-based search", map[string]interface{}{
|
||||
"customer_id": *form.CustomerID,
|
||||
"keywords_status": customerResp.KeywordsStatus,
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
tenders, total, err := s.repository.Search(ctx, form, pagination)
|
||||
if err != nil {
|
||||
s.logger.Error("Failed to list tenders", map[string]interface{}{
|
||||
@@ -240,20 +272,50 @@ func (s *tenderService) Search(ctx context.Context, form *SearchForm, pagination
|
||||
// Recommend retrieves tenders with pagination and filtering
|
||||
func (s *tenderService) Recommend(ctx context.Context, form *SearchForm, pagination *response.Pagination) (*SearchResponse, error) {
|
||||
s.logger.Info("Recommend tenders", map[string]interface{}{
|
||||
"company_id": form.CompanyID,
|
||||
"company_id": form.CompanyID,
|
||||
"customer_id": form.CustomerID,
|
||||
})
|
||||
|
||||
company, err := s.companyService.GetByID(ctx, *form.CompanyID)
|
||||
if err != nil {
|
||||
s.logger.Error("Failed to get company", map[string]interface{}{
|
||||
"company_id": form.CompanyID,
|
||||
"error": err.Error(),
|
||||
})
|
||||
return nil, fmt.Errorf("failed to get company: %w", err)
|
||||
form.Status = []string{string(TenderStatusActive)}
|
||||
|
||||
// Priority: Use customer keywords if available, otherwise use company CPV codes
|
||||
if form.CustomerID != nil && *form.CustomerID != "" {
|
||||
customerResp, err := s.customerService.GetByID(ctx, *form.CustomerID)
|
||||
if err == nil && customerResp != nil {
|
||||
// Only use keywords if status is ready
|
||||
if customerResp.KeywordsStatus == "ready" && len(customerResp.Keywords) > 0 {
|
||||
// Use customer keywords for recommendation
|
||||
keywordsQuery := strings.Join(customerResp.Keywords, " ")
|
||||
form.Search = &keywordsQuery
|
||||
s.logger.Info("Using customer keywords for recommendation", map[string]interface{}{
|
||||
"customer_id": *form.CustomerID,
|
||||
"keywords": customerResp.Keywords,
|
||||
})
|
||||
} else {
|
||||
s.logger.Info("Customer keywords not ready, falling back to company CPV codes", map[string]interface{}{
|
||||
"customer_id": *form.CustomerID,
|
||||
"keywords_status": customerResp.KeywordsStatus,
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
form.Status = []string{string(TenderStatusActive)}
|
||||
form.Classifications = company.Tags.CPVCodes
|
||||
// Fallback to company CPV codes if no customer keywords
|
||||
if form.Search == nil || *form.Search == "" {
|
||||
if form.CompanyID != nil && *form.CompanyID != "" {
|
||||
company, err := s.companyService.GetByID(ctx, *form.CompanyID)
|
||||
if err != nil {
|
||||
s.logger.Error("Failed to get company", map[string]interface{}{
|
||||
"company_id": form.CompanyID,
|
||||
"error": err.Error(),
|
||||
})
|
||||
return nil, fmt.Errorf("failed to get company: %w", err)
|
||||
}
|
||||
if company.Tags != nil && len(company.Tags.CPVCodes) > 0 {
|
||||
form.Classifications = company.Tags.CPVCodes
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
tenders, total, err := s.repository.Search(ctx, form, pagination)
|
||||
if err != nil {
|
||||
|
||||
Reference in New Issue
Block a user