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 }