added missing tender data to response

This commit is contained in:
Mazyar
2026-05-13 01:07:43 +03:30
parent c518cd3afb
commit 83c8ece91f
11 changed files with 1383 additions and 315 deletions
+321 -23
View File
@@ -55,6 +55,14 @@ type TEDDocument interface {
Validate() error
}
// ublEformsExtension returns embedded eForms extension data from UBL extensions (shared across notice root types).
func ublEformsExtension(ext *UBLExtensions) *EformsExtension {
if ext == nil || ext.UBLExtension == nil || ext.UBLExtension.ExtensionContent == nil {
return nil
}
return ext.UBLExtension.ExtensionContent.EformsExtension
}
// PriorInformationNotice represents a prior information notice
type PriorInformationNotice struct {
XMLName xml.Name `xml:"PriorInformationNotice"`
@@ -73,7 +81,7 @@ type PriorInformationNotice struct {
IssueTime string `xml:"IssueTime"`
VersionID string `xml:"VersionID"`
RegulatoryDomain string `xml:"RegulatoryDomain"`
NoticeTypeCode string `xml:"NoticeTypeCode"`
NoticeTypeCode NoticeTypeCodeField `xml:"NoticeTypeCode,omitempty"`
NoticeLanguageCode string `xml:"NoticeLanguageCode"`
Extensions *UBLExtensions `xml:"UBLExtensions,omitempty"`
ContractingParty *ContractingParty `xml:"ContractingParty,omitempty"`
@@ -90,7 +98,274 @@ func (pin PriorInformationNotice) GetID() string {
}
func (pin PriorInformationNotice) GetNoticeType() string {
return pin.NoticeTypeCode
return strings.TrimSpace(pin.NoticeTypeCode.Text)
}
// GetNoticeFormType returns the form type from listName on cbc:NoticeTypeCode (BT-03), e.g. "planning".
func (pin PriorInformationNotice) GetNoticeFormType() string {
return strings.TrimSpace(pin.NoticeTypeCode.ListName)
}
func (pin PriorInformationNotice) firstLot() *ProcurementProjectLot {
if len(pin.ProcurementProjectLot) == 0 {
return nil
}
return &pin.ProcurementProjectLot[0]
}
// GetPublicationInfo returns publication information if available.
func (pin PriorInformationNotice) GetPublicationInfo() *Publication {
if ef := ublEformsExtension(pin.Extensions); ef != nil {
return ef.Publication
}
return nil
}
// GetOrganizations returns organizations from extensions.
func (pin PriorInformationNotice) GetOrganizations() *Organizations {
if ef := ublEformsExtension(pin.Extensions); ef != nil {
return ef.Organizations
}
return nil
}
// GetNoticeSubType returns the notice subtype code from extensions.
func (pin PriorInformationNotice) GetNoticeSubType() string {
if ef := ublEformsExtension(pin.Extensions); ef != nil && ef.NoticeSubType != nil {
return ef.NoticeSubType.SubTypeCode
}
return ""
}
// GetNoticePublicationID returns the notice publication ID from extensions.
func (pin PriorInformationNotice) GetNoticePublicationID() string {
pub := pin.GetPublicationInfo()
if pub != nil {
return pub.NoticePublicationID
}
return ""
}
// GetOJSID returns the OJS gazette ID from extensions.
func (pin PriorInformationNotice) GetOJSID() string {
pub := pin.GetPublicationInfo()
if pub != nil {
return pub.GazetteID
}
return ""
}
// GetPublicationDate returns the publication date from extensions.
func (pin PriorInformationNotice) GetPublicationDate() string {
pub := pin.GetPublicationInfo()
if pub != nil {
return pub.PublicationDate
}
return ""
}
// GetOrganizationByID returns an organization by its ID.
func (pin PriorInformationNotice) GetOrganizationByID(orgID string) *Organization {
orgs := pin.GetOrganizations()
if orgs == nil {
return nil
}
for _, org := range orgs.Organization {
if org.Company != nil &&
org.Company.PartyIdentification != nil &&
org.Company.PartyIdentification.ID == orgID {
return &org
}
}
return nil
}
// GetBuyerID returns the buyer organization ID from contracting party.
func (pin PriorInformationNotice) GetBuyerID() string {
if pin.ContractingParty != nil &&
pin.ContractingParty.Party != nil &&
pin.ContractingParty.Party.PartyIdentification != nil {
return pin.ContractingParty.Party.PartyIdentification.ID
}
return ""
}
// GetReviewOrganizationID returns the review organization ID from appeal terms.
func (pin PriorInformationNotice) GetReviewOrganizationID() string {
if pin.firstLot() != nil &&
pin.firstLot().TenderingTerms != nil &&
pin.firstLot().TenderingTerms.AppealTerms != nil &&
pin.firstLot().TenderingTerms.AppealTerms.AppealReceiverParty != nil &&
pin.firstLot().TenderingTerms.AppealTerms.AppealReceiverParty.PartyIdentification != nil {
return pin.firstLot().TenderingTerms.AppealTerms.AppealReceiverParty.PartyIdentification.ID
}
return ""
}
// GetProcedureCode returns the type of procedure.
func (pin PriorInformationNotice) GetProcedureCode() string {
if pin.TenderingProcess != nil {
return pin.TenderingProcess.ProcedureCode
}
return ""
}
// GetProcurementTitle returns the procurement project title.
func (pin PriorInformationNotice) GetProcurementTitle() string {
if pin.ProcurementProject != nil && strings.TrimSpace(pin.ProcurementProject.Name) != "" {
return pin.ProcurementProject.Name
}
if pin.firstLot() != nil && pin.firstLot().ProcurementProject != nil {
return pin.firstLot().ProcurementProject.Name
}
return ""
}
// GetProcurementDescription returns the procurement project description.
func (pin PriorInformationNotice) GetProcurementDescription() string {
if pin.ProcurementProject != nil && strings.TrimSpace(pin.ProcurementProject.Description) != "" {
return pin.ProcurementProject.Description
}
if pin.firstLot() != nil && pin.firstLot().ProcurementProject != nil {
return pin.firstLot().ProcurementProject.Description
}
return ""
}
// GetContractNature returns the main nature of the contract.
func (pin PriorInformationNotice) GetContractNature() string {
if pin.ProcurementProject != nil && strings.TrimSpace(pin.ProcurementProject.ProcurementTypeCode) != "" {
return pin.ProcurementProject.ProcurementTypeCode
}
if pin.firstLot() != nil && pin.firstLot().ProcurementProject != nil {
return pin.firstLot().ProcurementProject.ProcurementTypeCode
}
return ""
}
// GetMainClassification returns the main CPV classification code.
func (pin PriorInformationNotice) GetMainClassification() string {
if pin.ProcurementProject != nil &&
pin.ProcurementProject.MainCommodityClassification != nil {
return pin.ProcurementProject.MainCommodityClassification.ItemClassificationCode
}
if lot := pin.firstLot(); lot != nil && lot.ProcurementProject != nil &&
lot.ProcurementProject.MainCommodityClassification != nil {
return lot.ProcurementProject.MainCommodityClassification.ItemClassificationCode
}
return ""
}
// GetMainClassificationDescription returns the CPV / item classification description when present in the notice XML.
func (pin PriorInformationNotice) GetMainClassificationDescription() string {
if pin.ProcurementProject != nil {
if s := mainCommodityClassificationLabel(pin.ProcurementProject.MainCommodityClassification); s != "" {
return s
}
}
if lot := pin.firstLot(); lot != nil && lot.ProcurementProject != nil {
return mainCommodityClassificationLabel(lot.ProcurementProject.MainCommodityClassification)
}
return ""
}
// GetPlaceOfPerformance returns the place of performance.
func (pin PriorInformationNotice) GetPlaceOfPerformance() string {
if pin.ProcurementProject != nil &&
pin.ProcurementProject.RealizedLocation != nil &&
pin.ProcurementProject.RealizedLocation.Address != nil {
return pin.ProcurementProject.RealizedLocation.Address.Region
}
if lot := pin.firstLot(); lot != nil && lot.ProcurementProject != nil &&
lot.ProcurementProject.RealizedLocation != nil &&
lot.ProcurementProject.RealizedLocation.Address != nil {
return lot.ProcurementProject.RealizedLocation.Address.Region
}
return ""
}
// GetSelectionCriteria returns selection criteria from extensions.
func (pin PriorInformationNotice) GetSelectionCriteria() []SelectionCriteria {
if ef := ublEformsExtension(pin.Extensions); ef != nil {
return ef.SelectionCriteria
}
return nil
}
// GetOfficialLanguages returns official languages from tender terms extensions.
func (pin PriorInformationNotice) GetOfficialLanguages() []string {
if pin.firstLot() != nil &&
pin.firstLot().TenderingTerms != nil &&
len(pin.firstLot().TenderingTerms.CallForTendersDocumentReference) > 0 &&
pin.firstLot().TenderingTerms.CallForTendersDocumentReference[0].UBLExtensions != nil &&
pin.firstLot().TenderingTerms.CallForTendersDocumentReference[0].UBLExtensions.UBLExtension != nil &&
pin.firstLot().TenderingTerms.CallForTendersDocumentReference[0].UBLExtensions.UBLExtension.ExtensionContent != nil &&
pin.firstLot().TenderingTerms.CallForTendersDocumentReference[0].UBLExtensions.UBLExtension.ExtensionContent.EformsExtension != nil &&
pin.firstLot().TenderingTerms.CallForTendersDocumentReference[0].UBLExtensions.UBLExtension.ExtensionContent.EformsExtension.OfficialLanguages != nil {
langs := pin.firstLot().TenderingTerms.CallForTendersDocumentReference[0].UBLExtensions.UBLExtension.ExtensionContent.EformsExtension.OfficialLanguages.Language
languages := make([]string, len(langs))
for i, lang := range langs {
languages[i] = lang.ID
}
return languages
}
return nil
}
// GetDocumentURI returns the document URI from call for tenders document reference.
func (pin PriorInformationNotice) GetDocumentURI() string {
if pin.firstLot() != nil &&
pin.firstLot().TenderingTerms != nil &&
len(pin.firstLot().TenderingTerms.CallForTendersDocumentReference) > 0 &&
pin.firstLot().TenderingTerms.CallForTendersDocumentReference[0].Attachment != nil &&
pin.firstLot().TenderingTerms.CallForTendersDocumentReference[0].Attachment.ExternalReference != nil {
return pin.firstLot().TenderingTerms.CallForTendersDocumentReference[0].Attachment.ExternalReference.URI
}
return ""
}
// GetTenderDeadline returns the tender submission deadline.
func (pin PriorInformationNotice) GetTenderDeadline() string {
if pin.firstLot() != nil &&
pin.firstLot().TenderingProcess != nil &&
pin.firstLot().TenderingProcess.TenderSubmissionDeadlinePeriod != nil {
return pin.firstLot().TenderingProcess.TenderSubmissionDeadlinePeriod.EndDate
}
return ""
}
// GetBudget returns the estimated contract amount and currency.
func (pin PriorInformationNotice) GetBudget() (amount string, currency string) {
if pin.firstLot() != nil &&
pin.firstLot().ProcurementProject != nil &&
pin.firstLot().ProcurementProject.RequestedTenderTotal != nil {
contractAmount := pin.firstLot().ProcurementProject.RequestedTenderTotal.EstimatedOverallContractAmount
return contractAmount.Text, contractAmount.CurrencyID
}
if pin.ProcurementProject != nil && pin.ProcurementProject.RequestedTenderTotal != nil {
a := pin.ProcurementProject.RequestedTenderTotal.EstimatedOverallContractAmount
return a.Text, a.CurrencyID
}
return "", ""
}
// GetDuration returns the contract duration and unit.
func (pin PriorInformationNotice) GetDuration() (duration string, unit string) {
if pin.firstLot() != nil &&
pin.firstLot().ProcurementProject != nil &&
pin.firstLot().ProcurementProject.PlannedPeriod != nil &&
pin.firstLot().ProcurementProject.PlannedPeriod.DurationMeasure != nil {
durationMeasure := pin.firstLot().ProcurementProject.PlannedPeriod.DurationMeasure
return durationMeasure.Text, durationMeasure.UnitCode
}
if pin.ProcurementProject != nil &&
pin.ProcurementProject.PlannedPeriod != nil &&
pin.ProcurementProject.PlannedPeriod.DurationMeasure != nil {
dm := pin.ProcurementProject.PlannedPeriod.DurationMeasure
return dm.Text, dm.UnitCode
}
return "", ""
}
func (pin PriorInformationNotice) GetLanguage() string {
@@ -1288,6 +1563,9 @@ type CurrencyText struct {
type MainCommodityClassification struct {
XMLName xml.Name `xml:"MainCommodityClassification"`
ItemClassificationCode string `xml:"ItemClassificationCode"`
ItemClassificationName string `xml:"ItemClassificationName,omitempty"`
ItemClassificationDesc string `xml:"ItemClassificationDescription,omitempty"`
Name string `xml:"Name,omitempty"`
}
// AdditionalCommodityClassification contains additional commodity classification
@@ -1451,34 +1729,24 @@ func (cn ContractNotice) GetLanguage() string {
// GetPublicationInfo returns publication information if available
func (cn ContractNotice) GetPublicationInfo() *Publication {
if cn.Extensions != nil &&
cn.Extensions.UBLExtension != nil &&
cn.Extensions.UBLExtension.ExtensionContent != nil &&
cn.Extensions.UBLExtension.ExtensionContent.EformsExtension != nil {
return cn.Extensions.UBLExtension.ExtensionContent.EformsExtension.Publication
if ef := ublEformsExtension(cn.Extensions); ef != nil {
return ef.Publication
}
return nil
}
// GetOrganizations returns organizations from extensions
func (cn ContractNotice) GetOrganizations() *Organizations {
if cn.Extensions != nil &&
cn.Extensions.UBLExtension != nil &&
cn.Extensions.UBLExtension.ExtensionContent != nil &&
cn.Extensions.UBLExtension.ExtensionContent.EformsExtension != nil {
return cn.Extensions.UBLExtension.ExtensionContent.EformsExtension.Organizations
if ef := ublEformsExtension(cn.Extensions); ef != nil {
return ef.Organizations
}
return nil
}
// GetNoticeSubType returns the notice subtype code from extensions
func (cn ContractNotice) GetNoticeSubType() string {
if cn.Extensions != nil &&
cn.Extensions.UBLExtension != nil &&
cn.Extensions.UBLExtension.ExtensionContent != nil &&
cn.Extensions.UBLExtension.ExtensionContent.EformsExtension != nil &&
cn.Extensions.UBLExtension.ExtensionContent.EformsExtension.NoticeSubType != nil {
return cn.Extensions.UBLExtension.ExtensionContent.EformsExtension.NoticeSubType.SubTypeCode
if ef := ublEformsExtension(cn.Extensions); ef != nil && ef.NoticeSubType != nil {
return ef.NoticeSubType.SubTypeCode
}
return ""
}
@@ -1592,6 +1860,26 @@ func (cn ContractNotice) GetMainClassification() string {
return ""
}
func mainCommodityClassificationLabel(m *MainCommodityClassification) string {
if m == nil {
return ""
}
for _, s := range []string{m.ItemClassificationName, m.ItemClassificationDesc, m.Name} {
if v := strings.TrimSpace(s); v != "" {
return v
}
}
return ""
}
// GetMainClassificationDescription returns the CPV / item classification description when present in the notice XML.
func (cn ContractNotice) GetMainClassificationDescription() string {
if cn.ProcurementProject == nil {
return ""
}
return mainCommodityClassificationLabel(cn.ProcurementProject.MainCommodityClassification)
}
// GetPlaceOfPerformance returns the place of performance
func (cn ContractNotice) GetPlaceOfPerformance() string {
if cn.ProcurementProject != nil &&
@@ -1612,11 +1900,8 @@ func (cn ContractNotice) GetLotID() string {
// GetSelectionCriteria returns selection criteria from extensions
func (cn ContractNotice) GetSelectionCriteria() []SelectionCriteria {
if cn.Extensions != nil &&
cn.Extensions.UBLExtension != nil &&
cn.Extensions.UBLExtension.ExtensionContent != nil &&
cn.Extensions.UBLExtension.ExtensionContent.EformsExtension != nil {
return cn.Extensions.UBLExtension.ExtensionContent.EformsExtension.SelectionCriteria
if ef := ublEformsExtension(cn.Extensions); ef != nil {
return ef.SelectionCriteria
}
return nil
}
@@ -1913,6 +2198,19 @@ func (can ContractAwardNotice) GetMainClassification() string {
return ""
}
// GetMainClassificationDescription returns the CPV / item classification description when present in the notice XML.
func (can ContractAwardNotice) GetMainClassificationDescription() string {
if can.ProcurementProject != nil {
if s := mainCommodityClassificationLabel(can.ProcurementProject.MainCommodityClassification); s != "" {
return s
}
}
if lot := can.firstAwardLot(); lot != nil && lot.ProcurementProject != nil {
return mainCommodityClassificationLabel(lot.ProcurementProject.MainCommodityClassification)
}
return ""
}
// GetTotalAwardValue returns the total award amount and currency
func (can ContractAwardNotice) GetTotalAwardValue() (amount string, currency string) {
noticeResult := can.GetNoticeResult()