Enhance tender estimated value resolution and add unit tests

- Updated the `ResolvedEstimatedValueAndCurrency` method to aggregate procurement lot values when the tender-level estimated value is not set, improving accuracy in value retrieval.
- Introduced the `AggregateProcurementLotEstimatedValue` function to sum estimated values from procurement lots and return the first found currency.
- Modified the `ToResponseWithLanguage` method to utilize the new estimated value resolution logic.
- Added unit tests for the new functionality, ensuring correct behavior for various scenarios in the `entity_test.go` and `budget_test.go` files.

This update improves the handling of estimated values in tenders, enhancing the overall reliability of the tender management system.
This commit is contained in:
Mazyar
2026-06-20 12:29:47 +03:30
parent 6fb57c41c1
commit 4cfca5aa55
7 changed files with 259 additions and 26 deletions
+30 -3
View File
@@ -30,11 +30,11 @@ func mapProcurementLotFromTED(lot *ProcurementProjectLot) notice.ProcurementLot
}
}
if pp.RequestedTenderTotal != nil {
a := pp.RequestedTenderTotal.EstimatedOverallContractAmount
if v, ok := ParseEuropeanAmount(a.Text); ok {
amount, currencyID := pp.RequestedTenderTotal.AmountAndCurrency()
if v, ok := ParseEuropeanAmount(amount); ok {
out.EstimatedValue = v
}
out.Currency = a.CurrencyID
out.Currency = currencyID
}
if pp.PlannedPeriod != nil && pp.PlannedPeriod.DurationMeasure != nil {
dm := pp.PlannedPeriod.DurationMeasure
@@ -167,6 +167,7 @@ func (s *TEDScraper) mapPriorInformationNoticeToTender(pin *PriorInformationNoti
for i := range pin.ProcurementProjectLot {
t.ProcurementLots = append(t.ProcurementLots, mapProcurementLotFromTED(&pin.ProcurementProjectLot[i]))
}
backfillNoticeEstimatedValueFromLots(t)
if duration, unit := pin.GetDuration(); duration != "" {
t.Duration = duration
@@ -351,6 +352,7 @@ func (s *TEDScraper) mapToTender(cn *ContractNotice, sourceFileURL, sourceFileNa
for i := range cn.ProcurementProjectLots {
t.ProcurementLots = append(t.ProcurementLots, mapProcurementLotFromTED(&cn.ProcurementProjectLots[i]))
}
backfillNoticeEstimatedValueFromLots(t)
// Set duration information
if duration, unit := cn.GetDuration(); duration != "" {
@@ -506,6 +508,7 @@ func (s *TEDScraper) mapContractAwardNoticeToTender(can *ContractAwardNotice, so
for i := range can.ProcurementProjectLot {
t.ProcurementLots = append(t.ProcurementLots, mapProcurementLotFromTED(&can.ProcurementProjectLot[i]))
}
backfillNoticeEstimatedValueFromLots(t)
// Set location information from main procurement project or first lot
var realizedAddr *Address
@@ -663,3 +666,27 @@ func (s *TEDScraper) mapOrganization(tedOrg *Organization, role string) *notice.
return org
}
func backfillNoticeEstimatedValueFromLots(t *notice.Notice) {
if t == nil || t.EstimatedValue > 0 {
return
}
var total float64
var currency string
for _, lot := range t.ProcurementLots {
if lot.EstimatedValue <= 0 {
continue
}
total += lot.EstimatedValue
if currency == "" {
currency = strings.TrimSpace(lot.Currency)
}
}
if total <= 0 {
return
}
t.EstimatedValue = total
if strings.TrimSpace(t.Currency) == "" {
t.Currency = currency
}
}