Files
tm_back/ted/parser.go
T
n.nakhostin 44f266189c Refactor TED Calendar and EForm Structure for Enhanced Functionality
- Updated the GetOJS function to accept a base URL parameter, improving flexibility in constructing the calendar URL.
- Removed the deprecated eform.go file, streamlining the codebase by eliminating unused components.
- Introduced new eform structures for BusinessRegistrationInformationNotice, ContractNotice, ContractAwardNotice, and PriorInformationNotice, enhancing the handling of TED XML data.
- Implemented mapping functions to convert eform notices to the Tender entity, improving integration with the tender management system.
- Added a service layer to encapsulate business logic related to eform processing, adhering to Clean Architecture principles.
2025-09-30 16:51:40 +03:30

89 lines
3.6 KiB
Go

package ted
import (
"encoding/xml"
"fmt"
"strings"
"tm/pkg/xmlparser"
"tm/ted/eform/business_registration_information"
"tm/ted/eform/contract"
"tm/ted/eform/contract_award"
"tm/ted/eform/prior_information"
)
type ParserType string
const (
ParserTypeContractNotice ParserType = "ContractNotice"
ParserTypeContractAwardNotice ParserType = "ContractAwardNotice"
ParserTypePriorInformationNotice ParserType = "PriorInformationNotice"
ParserTypeBusinessRegistrationInformationNotice ParserType = "BusinessRegistrationInformationNotice"
)
type TEDParser struct {
ContractNotice xmlparser.Parser[contract.ContractNotice]
ContractAwardNotice xmlparser.Parser[contract_award.ContractAwardNotice]
PriorInformationNotice xmlparser.Parser[prior_information.PriorInformationNotice]
BusinessRegistrationInformationNotice xmlparser.Parser[business_registration_information.BusinessRegistrationInformationNotice]
}
// NewTEDParser creates a new TED parser
func NewTEDParser() *TEDParser {
options := xmlparser.DefaultParserOptions()
options.MaxSize = 50 * 1024 * 1024 // 50MB limit for TED XML files
options.IgnoreUnknownElements = true // TED XML has many optional fields
contractNoticeParser := xmlparser.NewParser[contract.ContractNotice](options)
contractAwardNoticeParser := xmlparser.NewParser[contract_award.ContractAwardNotice](options)
priorInformationNoticeParser := xmlparser.NewParser[prior_information.PriorInformationNotice](options)
businessRegistrationInformationNoticeParser := xmlparser.NewParser[business_registration_information.BusinessRegistrationInformationNotice](options)
return &TEDParser{
ContractNotice: contractNoticeParser,
ContractAwardNotice: contractAwardNoticeParser,
PriorInformationNotice: priorInformationNoticeParser,
BusinessRegistrationInformationNotice: businessRegistrationInformationNoticeParser,
}
}
// ParseAnyNotice parses XML content and detects the notice type automatically
func (tp *TEDParser) Parse(content []byte) (interface{}, string, ParserType, error) {
// First, detect the root element type
rootElement, err := detectRootElement(content)
if err != nil {
return nil, "", ParserType(""), fmt.Errorf("failed to detect root element: %w", err)
}
// Parse based on the detected type
switch ParserType(rootElement) {
case ParserTypeContractNotice:
notice, err := tp.ContractNotice.ParseBytes(content)
return notice, notice.GetID(), ParserTypeContractNotice, err
case ParserTypeContractAwardNotice:
notice, err := tp.ContractAwardNotice.ParseBytes(content)
return notice, notice.GetID(), ParserTypeContractAwardNotice, err
case ParserTypePriorInformationNotice:
notice, err := tp.PriorInformationNotice.ParseBytes(content)
return notice, notice.GetID(), ParserTypePriorInformationNotice, err
case ParserTypeBusinessRegistrationInformationNotice:
notice, err := tp.BusinessRegistrationInformationNotice.ParseBytes(content)
return notice, notice.GetID(), ParserTypeBusinessRegistrationInformationNotice, err
default:
return nil, "", ParserType(""), fmt.Errorf("unsupported notice type: %s", rootElement)
}
}
// detectRootElement detects the root XML element name
func detectRootElement(content []byte) (string, error) {
decoder := xml.NewDecoder(strings.NewReader(string(content)))
for {
token, err := decoder.Token()
if err != nil {
return "", err
}
if startElement, ok := token.(xml.StartElement); ok {
return startElement.Name.Local, nil
}
}
}