05c7eae8a2
- Introduced a new configuration file for the TED scraper, defining database connection settings, logging preferences, and scraping parameters. - Implemented a CronScheduler to manage scheduled tasks for TED operations, utilizing the robfig/cron library for scheduling. - Added new entities and structures for handling TED XML data, including eForms and tender-related information, enhancing the scraper's functionality. - Updated the main application to initialize the TED scraper with the new configuration and set up graceful shutdown handling. - Removed the deprecated scraping implementation to streamline the codebase and focus on the new architecture.
63 lines
4.5 KiB
Go
63 lines
4.5 KiB
Go
package eform
|
|
|
|
// =====================================================
|
|
// LOT STRUCTURE
|
|
// =====================================================
|
|
|
|
// Lot represents an individual procurement lot
|
|
type Lot struct {
|
|
ID string `json:"id" xml:"id" validate:"required,lotIDFormat"`
|
|
InternalID string `json:"internal_id,omitempty" xml:"internal_id,omitempty" validate:"max=100"`
|
|
Title string `json:"title" xml:"title" validate:"required,max=500"`
|
|
Description string `json:"description" xml:"description" validate:"required,max=10000"`
|
|
MainCPVCode string `json:"main_cpv_code" xml:"main_cpv_code" validate:"required,cpvCode"`
|
|
AdditionalCPVCodes []string `json:"additional_cpv_codes,omitempty" xml:"additional_cpv_codes,omitempty" validate:"dive,cpvCode"`
|
|
ContractNature ContractNature `json:"contract_nature" xml:"contract_nature" validate:"required"`
|
|
EstimatedValue *Money `json:"estimated_value,omitempty" xml:"estimated_value,omitempty"`
|
|
PlacesOfPerformance []Place `json:"places_of_performance" xml:"places_of_performance" validate:"required,min=1,dive"`
|
|
Duration *Duration `json:"duration,omitempty" xml:"duration,omitempty"`
|
|
Renewable bool `json:"renewable" xml:"renewable"`
|
|
RenewalDescription string `json:"renewal_description,omitempty" xml:"renewal_description,omitempty" validate:"required_if=Renewable true"`
|
|
OptionsDescription string `json:"options_description,omitempty" xml:"options_description,omitempty" validate:"max=10000"`
|
|
VariantsAccepted bool `json:"variants_accepted" xml:"variants_accepted"`
|
|
MaxLotsPerTenderer *int `json:"max_lots_per_tenderer,omitempty" xml:"max_lots_per_tenderer,omitempty" validate:"omitempty,min=1"`
|
|
MaxLotsAwarded *int `json:"max_lots_awarded,omitempty" xml:"max_lots_awarded,omitempty" validate:"omitempty,min=1"`
|
|
LotCombinations []string `json:"lot_combinations,omitempty" xml:"lot_combinations,omitempty"`
|
|
SubcontractingObligation SubcontractingObligation `json:"subcontracting_obligation" xml:"subcontracting_obligation"`
|
|
SubcontractingPercentage *float64 `json:"subcontracting_percentage,omitempty" xml:"subcontracting_percentage,omitempty" validate:"omitempty,min=0,max=100"`
|
|
TechnicalSpecifications TechnicalSpecifications `json:"technical_specifications" xml:"technical_specifications" validate:"required"`
|
|
AwardCriteria AwardCriteria `json:"award_criteria" xml:"award_criteria" validate:"required"`
|
|
TenderingTerms TenderingTerms `json:"tendering_terms" xml:"tendering_terms" validate:"required"`
|
|
Result *LotResult `json:"result,omitempty" xml:"result,omitempty"`
|
|
}
|
|
|
|
// SubcontractingObligation represents subcontracting requirements
|
|
type SubcontractingObligation string
|
|
|
|
const (
|
|
SubcontractingNone SubcontractingObligation = "none"
|
|
SubcontractingMinimum SubcontractingObligation = "minimum"
|
|
SubcontractingRequired SubcontractingObligation = "required"
|
|
)
|
|
|
|
// Place represents a place of performance
|
|
type Place struct {
|
|
StreetAddress string `json:"street_address,omitempty" xml:"street_address,omitempty" validate:"max=200"`
|
|
Locality string `json:"locality,omitempty" xml:"locality,omitempty" validate:"max=100"`
|
|
PostalCode string `json:"postal_code,omitempty" xml:"postal_code,omitempty" validate:"max=20"`
|
|
CountrySubdivision string `json:"country_subdivision,omitempty" xml:"country_subdivision,omitempty" validate:"max=100"`
|
|
CountryCode string `json:"country_code" xml:"country_code" validate:"required,iso3166_1_alpha2"`
|
|
NUTSCodes []string `json:"nuts_codes" xml:"nuts_codes" validate:"required,min=1,dive,nutsCode"`
|
|
Description string `json:"description,omitempty" xml:"description,omitempty" validate:"max=1000"`
|
|
}
|
|
|
|
// HasSubcontractingObligation checks if subcontracting is required
|
|
func (l *Lot) HasSubcontractingObligation() bool {
|
|
return l.SubcontractingObligation != SubcontractingNone
|
|
}
|
|
|
|
// IsReservedContract checks if lot is reserved for specific participants
|
|
func (l *Lot) IsReservedContract() bool {
|
|
return l.TechnicalSpecifications.ReservedExecution != ReservedNone
|
|
}
|