Add TED Scraper Configuration and Cron Scheduler Implementation
- 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.
This commit is contained in:
@@ -0,0 +1,62 @@
|
||||
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
|
||||
}
|
||||
Reference in New Issue
Block a user