adaae4c4bc
continuous-integration/drone/push Build is passing
- Replaced the direct fetching of tender details within the `GetTenderApprovalsByCompanyIDWithTender`, `GetTenderApprovalsByStatusWithTender`, and `GetTenderApprovalsBySubmissionModeWithTender` methods with a new approach that loads tender details in bulk using `loadTendersByIDs`. - Introduced helper functions `fullTenderDetailsFromResponse` and `listTenderDetailsFromResponse` to streamline the mapping of tender responses to `TenderDetails`. - Added a new file `tender_details.go` to encapsulate tender detail mapping logic, improving code organization and readability. This update enhances the performance of the tender approval service by reducing redundant calls to fetch tender details, leading to more efficient data handling.
111 lines
3.1 KiB
Go
111 lines
3.1 KiB
Go
package tender_approval
|
|
|
|
import (
|
|
"context"
|
|
|
|
"tm/internal/tender"
|
|
)
|
|
|
|
func fullTenderDetailsFromResponse(resp *tender.TenderResponse) *TenderDetails {
|
|
if resp == nil {
|
|
return nil
|
|
}
|
|
|
|
details := &TenderDetails{
|
|
ID: resp.ID,
|
|
NoticePublicationID: resp.NoticePublicationID,
|
|
PublicationDate: resp.PublicationDate,
|
|
Title: resp.Title,
|
|
Description: resp.Description,
|
|
ProcurementTypeCode: resp.ProcurementTypeCode,
|
|
ProcedureCode: resp.ProcedureCode,
|
|
EstimatedValue: resp.EstimatedValue,
|
|
Currency: resp.Currency,
|
|
Duration: resp.Duration,
|
|
DurationUnit: resp.DurationUnit,
|
|
TenderDeadline: resp.TenderDeadline,
|
|
SubmissionDeadline: resp.SubmissionDeadline,
|
|
CountryCode: resp.CountryCode,
|
|
Status: string(resp.Status),
|
|
}
|
|
if resp.BuyerOrganization != nil && resp.BuyerOrganization.Name != "" {
|
|
details.BuyerOrganization = &OrganizationResponse{Name: resp.BuyerOrganization.Name}
|
|
}
|
|
return details
|
|
}
|
|
|
|
func listTenderDetailsFromResponse(resp *tender.TenderResponse) *TenderDetails {
|
|
if resp == nil {
|
|
return nil
|
|
}
|
|
|
|
details := &TenderDetails{
|
|
ID: resp.ID,
|
|
Title: resp.Title,
|
|
Description: resp.Description,
|
|
EstimatedValue: resp.EstimatedValue,
|
|
Currency: resp.Currency,
|
|
TenderDeadline: resp.TenderDeadline,
|
|
SubmissionDeadline: resp.SubmissionDeadline,
|
|
CountryCode: resp.CountryCode,
|
|
Status: string(resp.Status),
|
|
}
|
|
if resp.BuyerOrganization != nil && resp.BuyerOrganization.Name != "" {
|
|
details.BuyerOrganization = &OrganizationResponse{Name: resp.BuyerOrganization.Name}
|
|
}
|
|
return details
|
|
}
|
|
|
|
func uniqueTenderIDs(approvals []*TenderApproval) []string {
|
|
if len(approvals) == 0 {
|
|
return nil
|
|
}
|
|
|
|
seen := make(map[string]struct{}, len(approvals))
|
|
ids := make([]string, 0, len(approvals))
|
|
for _, approval := range approvals {
|
|
if approval == nil || approval.TenderID == "" {
|
|
continue
|
|
}
|
|
if _, ok := seen[approval.TenderID]; ok {
|
|
continue
|
|
}
|
|
seen[approval.TenderID] = struct{}{}
|
|
ids = append(ids, approval.TenderID)
|
|
}
|
|
return ids
|
|
}
|
|
|
|
func (s *tenderApprovalService) loadTendersByIDs(ctx context.Context, tenderIDs []string) map[string]*tender.TenderResponse {
|
|
if len(tenderIDs) == 0 {
|
|
return map[string]*tender.TenderResponse{}
|
|
}
|
|
|
|
tenders, err := s.tenderService.GetByIDs(ctx, tenderIDs)
|
|
if err != nil {
|
|
s.logger.Warn("Failed to load tenders by IDs", map[string]interface{}{
|
|
"count": len(tenderIDs),
|
|
"error": err.Error(),
|
|
})
|
|
return map[string]*tender.TenderResponse{}
|
|
}
|
|
|
|
return tenders
|
|
}
|
|
|
|
func mapApprovalsWithTender(
|
|
approvals []*TenderApproval,
|
|
tenders map[string]*tender.TenderResponse,
|
|
toDetails func(*tender.TenderResponse) *TenderDetails,
|
|
) []*TenderApprovalWithTenderResponse {
|
|
responses := make([]*TenderApprovalWithTenderResponse, 0, len(approvals))
|
|
for _, approval := range approvals {
|
|
var details *TenderDetails
|
|
if tenderResp, ok := tenders[approval.TenderID]; ok {
|
|
details = toDetails(tenderResp)
|
|
}
|
|
responses = append(responses, approval.ToResponseWithTender(details))
|
|
}
|
|
return responses
|
|
}
|