class Award(BaseAward): class Options: roles = { 'edit': whitelist('status', 'qualified', 'eligible', 'title', 'title_en', 'title_ru', 'description', 'description_en', 'description_ru'), } complaints = ListType(ModelType(Complaint), default=list()) items = ListType(ModelType(Item)) qualified = BooleanType(default=False) eligible = BooleanType(default=False) def validate_qualified(self, data, qualified): if data['status'] == 'active' and not qualified: raise ValidationError(u'This field is required.') def validate_eligible(self, data, eligible): if data['status'] == 'active' and not eligible: raise ValidationError(u'This field is required.')
class Complaint(BaseComplaint): class Options: roles = { 'active.pre-qualification': view_bid_role, 'active.pre-qualification.stand-still': view_bid_role, } documents = ListType(ModelType(Document), default=list()) def serialize(self, role=None, context=None): if role == 'view' and self.type == 'claim' and get_tender(self).status in ['active.tendering', 'active.pre-qualification', 'active.pre-qualification.stand-still', 'active.auction']: role = 'view_claim' return super(Complaint, self).serialize(role=role, context=context)
class Agreement(OpenprocurementSchematicsDocument, Model): """ Base agreement model """ id = MD5Type(required=True, default=lambda: uuid4().hex) agreementID = StringType() # maybe terminated ???? status = StringType(choices=["active", "terminated"], required=True) date = IsoDateTimeType() dateModified = IsoDateTimeType() description = StringType() title = StringType() revisions = ListType(ModelType(Revision, required=True), default=list()) tender_token = StringType(required=True) tender_id = StringType(required=True) owner_token = StringType(default=lambda: uuid4().hex) transfer_token = StringType(default=lambda: uuid4().hex) owner = StringType() mode = StringType(choices=["test"]) def import_data(self, raw_data, **kw): """ Converts and imports the raw data into the instance of the model according to the fields in the model. :param raw_data: The data to be imported. """ data = self.convert(raw_data, **kw) del_keys = [ k for k in data.keys() if data[k] == self.__class__.fields[k].default or data[k] == getattr(self, k) ] for k in del_keys: del data[k] self._data.update(data) return self def __local_roles__(self): return dict( [ ("{}_{}".format(self.owner, self.owner_token), "agreement_owner"), ("{}_{}".format(self.owner, self.tender_token), "tender_owner"), ] ) def __acl__(self): acl = [ (Allow, "{}_{}".format(self.owner, self.owner_token), "edit_agreement"), (Allow, "{}_{}".format(self.owner, self.tender_token), "generate_credentials"), ] return acl def __repr__(self): return "<%s:%r@%r>" % (type(self).__name__, self.id, self.rev)
class Item(Item): """A good, service, or work to be contracted.""" additionalClassifications = ListType( ModelType(Classification), default=list(), validators=[validate_dkpp]) # required=True, min_size=1, def validate_relatedLot(self, data, relatedLot): if relatedLot and isinstance( data['__parent__'], Model) and relatedLot not in [ i.id for i in get_auction(data['__parent__']).lots ]: raise ValidationError(u"relatedLot should be one of lots")
class Contract(BaseContract): documents = ListType(ModelType(Document, required=True), default=list()) def validate_dateSigned(self, data, value): parent = data["__parent__"] if value and isinstance(parent, Model): if value > get_now(): raise ValidationError("Contract signature date can't be in the future") active_award = [award for award in parent.awards if award.status == 'active'] if active_award and value < active_award[0].date: raise ValidationError("Contract signature date should be after award activation date ({})".format( active_award[0].date.isoformat()))
class CompetitiveDialogUA(CompetitiveDialogEU): procurementMethodType = StringType(default=CD_UA_TYPE) title_en = StringType() items = ListType( ModelType(BaseUAItem, required=True), required=True, min_size=1, validators=[validate_cpv_group, validate_items_uniq], ) procuringEntity = ModelType(BaseProcuringEntity, required=True) stage2TenderID = StringType(required=False) mainProcurementCategory = StringType(choices=["services", "works"])
class Bid(BidEU): class Options: roles = { "Administrator": Administrator_bid_role, "embedded": view_bid_role_stage1, "view": view_bid_role_stage1, "create": whitelist( "tenderers", "lotValues", "status", "selfQualified", "selfEligible", "subcontractingDetails", "documents", ), "edit": whitelist("tenderers", "lotValues", "status", "subcontractingDetails"), "active.enquiries": whitelist(), "active.tendering": whitelist(), "active.pre-qualification": whitelist("id", "status", "documents", "tenderers"), "active.pre-qualification.stand-still": whitelist("id", "status", "documents", "tenderers"), "active.auction": whitelist("id", "status", "documents", "tenderers"), "active.stage2.pending": whitelist("id", "status", "documents", "tenderers"), "active.stage2.waiting": whitelist("id", "status", "documents", "tenderers"), "active.qualification": view_bid_role, "complete": view_bid_role_stage1, "unsuccessful": view_bid_role_stage1, "cancelled": view_bid_role_stage1, "invalid": whitelist("id", "status"), "deleted": whitelist("id", "status"), } documents = ListType(ModelType(Document, required=True), default=list()) value = None lotValues = ListType(ModelType(LotValue, required=True), default=list()) def validate_value(self, *args, **kwargs): pass # remove validation on stage 1 def validate_parameters(self, data, parameters): pass # remove validation on stage 1
class Complaint(BaseComplaint): documents = ListType(ModelType(EUDocument, required=True), default=list()) def serialize(self, role=None, context=None): if (role == "view" and self.type == "claim" and get_tender(self).status in [ "active.tendering", "active.pre-qualification", "active.pre-qualification.stand-still", "active.auction", ]): role = "view_claim" return super(Complaint, self).serialize(role=role, context=context)
class Transaction(Model): id = StringType(required=True) documents = ListType(ModelType(TransactionDocument), default=list()) date = IsoDateTimeType(required=True) value = ModelType(Guarantee, required=True) payer = ModelType(OrganizationReference, required=True) payee = ModelType(OrganizationReference, required=True) status = StringType(required=True) class Options: roles = { "view": schematics_default_role, }
class Contract(Model): class Options: roles = { "create": blacklist(), "edit": blacklist("id", "suppliers", "date", "awardID", "bidID"), "embedded": schematics_embedded_role, "view": schematics_default_role, } id = MD5Type(required=True, default=lambda: uuid4().hex) parameters = ListType(ModelType(Parameter, required=True), default=list(), validators=[validate_parameters_uniq]) status = StringType(choices=["active", "unsuccessful"], default="active") suppliers = ListType(ModelType(BusinessOrganization, required=True)) unitPrices = ListType(ModelType(UnitPrice, required=True)) awardID = StringType() bidID = StringType() date = IsoDateTimeType() def validate_awardID(self, data, awardID): parent = data["__parent__"] if awardID and isinstance(parent, Model) and awardID not in [i.id for i in parent["__parent__"].awards]: raise ValidationError(u"awardID should be one of awards")
class Contract(Contract): documents = ListType(ModelType(Document), default=list()) id = MD5Type(required=True, default=lambda: uuid4().hex) awardID = StringType(required=True) contractID = StringType() contractNumber = StringType() title = StringType() # Contract title title_en = StringType() title_ru = StringType() description = StringType() # Contract description description_en = StringType() description_ru = StringType() status = StringType( choices=['pending', 'terminated', 'active', 'cancelled'], default='pending') period = ModelType(Period) value = ModelType(Value) dateSigned = IsoDateTimeType() items = ListType(ModelType(Item)) suppliers = ListType(ModelType(Organization), min_size=1, max_size=1) date = IsoDateTimeType()
class BaseESCOValue(Value): class Options: roles = { 'embedded': view_value_role_esco, 'view': view_value_role_esco, 'create': whitelist('amount', 'amount_escp', 'amountPerformance', 'amountPerformance_npv', 'yearlyPaymentsPercentage', 'annualCostsReduction', 'contractDuration', 'currency', 'valueAddedTaxIncluded'), 'edit': whitelist('amount', 'amount_escp', 'amountPerformance', 'amountPerformance_npv', 'yearlyPaymentsPercentage', 'annualCostsReduction', 'contractDuration', 'currency', 'valueAddedTaxIncluded'), 'auction_view': whitelist('amountPerformance', 'yearlyPaymentsPercentage', 'annualCostsReduction', 'contractDuration', 'currency', 'valueAddedTaxIncluded'), 'auction_post': whitelist('amount_escp', 'amountPerformance_npv', 'yearlyPaymentsPercentage', 'contractDuration'), 'active.qualification': view_value_role_esco, 'active.awarded': view_value_role_esco, 'complete': view_value_role_esco, 'unsuccessful': view_value_role_esco, 'cancelled': view_value_role_esco, } amount = DecimalType( min_value=Decimal('0'), required=False, precision=-2) # Calculated energy service contract value. amountPerformance = DecimalType( required=False, precision=-2 ) # Calculated energy service contract performance indicator yearlyPaymentsPercentage = DecimalType( required=True, precision=-5, min_value=Decimal('0'), max_value=Decimal( '1')) # The percentage of annual payments in favor of Bidder annualCostsReduction = ListType( DecimalType(), required=True) # Buyer's annual costs reduction contractDuration = ModelType(ContractDuration, required=True)
class Qualification(Model): """ Pre-Qualification """ class Options: roles = RolesFromCsv("Qualification.csv", relative_to=__file__) title = StringType() title_en = StringType() title_ru = StringType() description = StringType() description_en = StringType() description_ru = StringType() id = MD5Type(required=True, default=lambda: uuid4().hex) bidID = StringType(required=True) lotID = MD5Type() status = StringType( choices=["pending", "active", "unsuccessful", "cancelled"], default="pending") date = IsoDateTimeType() documents = ListType(ModelType(EUDocument, required=True), default=list()) complaints = ListType(ModelType(Complaint, required=True), default=list()) qualified = BooleanType(default=False) eligible = BooleanType(default=False) def validate_qualified(self, data, qualified): if data["status"] == "active" and not qualified: raise ValidationError(u"This field is required.") def validate_eligible(self, data, eligible): if data["status"] == "active" and not eligible: raise ValidationError(u"This field is required.") def validate_lotID(self, data, lotID): parent = data["__parent__"] if isinstance(parent, Model): if not lotID and parent.lots: raise ValidationError(u"This field is required.") if lotID and lotID not in [lot.id for lot in parent.lots if lot]: raise ValidationError(u"lotID should be one of lots")
class TenderStage2UA(BaseTenderUA): procurementMethodType = StringType(default=STAGE_2_UA_TYPE) dialogue_token = StringType(required=True) dialogueID = StringType() shortlistedFirms = ListType(ModelType(Firms, required=True), min_size=3, required=True) tenderPeriod = ModelType( PeriodStartEndRequired, required=False, default=init_PeriodStartEndRequired(TENDERING_DURATION_UA) ) status = StringType( choices=[ "draft", "active.tendering", "active.pre-qualification", "active.pre-qualification.stand-still", "active.auction", "active.qualification", "active.awarded", "complete", "cancelled", "unsuccessful", STAGE2_STATUS, ], default="active.tendering", ) lots = ListType(ModelType(LotStage2UA, required=True), default=list(), validators=[validate_lots_uniq]) items = ListType( ModelType(ItemStage2UA, required=True), required=True, min_size=1, validators=[validate_cpv_group, validate_items_uniq], ) awards = ListType(ModelType(Award, required=True), default=list()) contracts = ListType(ModelType(Contract, required=True), default=list()) features = ListType(ModelType(Feature, required=True), validators=[validate_features_uniq]) procurementMethod = StringType(choices=["open", "selective", "limited"], default="selective") create_accreditations = (ACCR_COMPETITIVE,) central_accreditations = (ACCR_COMPETITIVE, ACCR_5) transfer_accreditations = (ACCR_3, ACCR_5) class Options(TenderStage2EU.Options): pass def __acl__(self): acl = stage2__acl__(self) self._acl_cancellation_complaint(acl) return acl def validate_features(self, data, features): validate_features_custom_weight(self, data, features, FEATURES_MAX_SUM) # Non-required mainProcurementCategory def validate_mainProcurementCategory(self, data, value): pass # Not required milestones def validate_milestones(self, data, value): pass
class Contract(BaseContract): class Options: roles = RolesFromCsv("Contract.csv", relative_to=__file__) value = ModelType(ContractValue) awardID = StringType(required=True) documents = ListType(ModelType(Document, required=True), default=list()) items = ListType(ModelType(Item)) def __acl__(self): return get_contract_supplier_permissions(self) def get_role(self): root = self.get_root() request = root.request if request.authenticated_role in ("tender_owner", "contract_supplier"): role = "edit_{}".format(request.authenticated_role) else: role = request.authenticated_role return role def __local_roles__(self): roles = {} roles.update(get_contract_supplier_roles(self)) return roles def validate_awardID(self, data, awardID): parent = data["__parent__"] if awardID and isinstance(parent, Model) and awardID not in [ i.id for i in parent.awards ]: raise ValidationError("awardID should be one of awards") def validate_dateSigned(self, data, value): parent = data["__parent__"] if value and isinstance(parent, Model) and value > get_now(): raise ValidationError( "Contract signature date can't be in the future")
class Agreement(Model): class Options: roles = RolesFromCsv("Agreement.csv", relative_to=__file__) id = MD5Type(required=True) agreementID = StringType() agreementNumber = StringType() contracts = ListType(ModelType(Contract, required=True)) changes = ListType( PolyModelType( (ChangeTaxRate, ChangeItemPriceVariation, ChangePartyWithdrawal, ChangeThirdParty), claim_function=get_change_class, ), default=list(), ) date = IsoDateTimeType() dateSigned = IsoDateTimeType() dateModified = IsoDateTimeType() description = StringType() description_en = StringType() description_ru = StringType() documents = ListType(ModelType(Document, required=True), default=list()) items = ListType(ModelType(Item, required=True)) features = ListType(ModelType(Feature, required=True), validators=[validate_features_uniq]) mode = StringType(choices=["test"]) owner = StringType() period = ModelType(Period) procuringEntity = ModelType(ProcuringEntity) status = StringType( choices=["pending", "active", "cancelled", "terminated"]) tender_id = MD5Type() title = StringType() title_en = StringType() title_ru = StringType() terminationDetails = StringType() numberOfContracts = IntType()
class Inspection(BaseModel): class Options: roles = { 'plain': blacklist('_attachments', 'revisions') + schematics_embedded_role, 'revision': whitelist('revisions'), 'create': blacklist('revisions', 'dateModified', 'dateCreated', 'doc_id', '_attachments', 'inspection_id') + schematics_embedded_role, 'edit': whitelist("description", "monitoring_ids"), 'view': blacklist( '_attachments', 'revisions', ) + schematics_embedded_role, 'listing': whitelist('dateModified', 'doc_id'), 'default': schematics_default_role, } monitoring_ids = ListType(MD5Type, required=True, min_size=1) description = StringType(required=True) documents = ListType(ModelType(Document), default=list()) inspection_id = StringType() dateModified = IsoDateTimeType() dateCreated = IsoDateTimeType(default=get_now) revisions = ListType(ModelType(Revision), default=list()) _attachments = DictType(DictType(BaseType), default=dict()) def __repr__(self): return '<%s:%r-%r@%r>' % (type(self).__name__, self.inspection_id, self.id, self.rev)
class Milestone(Model): TYPE_APPROVAL = 'approval' STATUS_SCHEDULED = 'scheduled' STATUS_MET = 'met' STATUS_NOT_MET = 'notMet' STATUS_INVALID = 'invalid' ACTIVE_STATUSES = (STATUS_SCHEDULED, STATUS_MET) class Options: _edit = whitelist("status", "dueDate", "description") _create = _edit + whitelist("title", "description", "type", "author", "documents") _view = _create + whitelist("id", "owner", "dateModified", "dateMet") roles = { "create": _create, "edit": _edit, "embedded": _view, "view": _view, "plain": _view + whitelist("owner_token", "transfer_token"), } def __local_roles__(self): return { "{}_{}".format(self.owner, self.owner_token): "milestone_owner" } def __acl__(self): acl = [ (Allow, "{}_{}".format(self.owner, self.owner_token), "update_milestone"), ] return acl id = MD5Type(required=True, default=lambda: uuid4().hex) title = StringType(required=True, choices=[MILESTONE_APPROVAL_TITLE]) description = StringType(required=True, min_length=3, default=MILESTONE_APPROVAL_DESCRIPTION) type = StringType(required=True, choices=[TYPE_APPROVAL]) dueDate = IsoDateTimeType(required=True) status = StringType( required=True, choices=[STATUS_SCHEDULED, STATUS_MET, STATUS_NOT_MET, STATUS_INVALID], default=STATUS_SCHEDULED) documents = ListType(ModelType(Document, required=True), default=list()) author = ModelType(BaseOrganization, required=True) dateModified = IsoDateTimeType(default=get_now) dateMet = IsoDateTimeType() owner = StringType() owner_token = StringType()
class Tender(ReportingTender): """ Negotiation """ items = ListType(ModelType(Item), required=True, min_size=1, validators=[validate_cpv_group, validate_items_uniq]) awards = ListType(ModelType(Award), default=list()) contracts = ListType(ModelType(Contract), default=list()) cause = StringType(choices=[ 'artContestIP', 'noCompetition', 'twiceUnsuccessful', 'additionalPurchase', 'additionalConstruction', 'stateLegalServices' ], required=True) causeDescription = StringType(required=True, min_length=1) causeDescription_en = StringType(min_length=1) causeDescription_ru = StringType(min_length=1) procurementMethodType = StringType(default="negotiation") create_accreditation = 3 edit_accreditation = 4 procuring_entity_kinds = ['general', 'special', 'defense'] lots = ListType(ModelType(Lot), default=list(), validators=[validate_lots_uniq])
class BaseAward(Model): """ Base award """ id = MD5Type(required=True, default=lambda: uuid4().hex) title = StringType() # Award title title_en = StringType() title_ru = StringType() subcontractingDetails = StringType() qualified = BooleanType() description = StringType() # Award description description_en = StringType() description_ru = StringType() status = StringType( required=True, choices=['pending', 'unsuccessful', 'active', 'cancelled'], default='pending') date = IsoDateTimeType(default=get_now) value = ModelType(Value) suppliers = ListType(ModelType(Organization), required=True, min_size=1, max_size=1) documents = ListType(ModelType(Document), default=list()) items = ListType(ModelType(Item))
class BaseESCOValue(Value): class Options: roles = { "embedded": view_value_role_esco, "view": view_value_role_esco, "create": create_value_role_esco, "edit": edit_value_role_esco, "auction_view": whitelist( "amountPerformance", "yearlyPaymentsPercentage", "annualCostsReduction", "contractDuration", "currency", "valueAddedTaxIncluded", ), "auction_post": whitelist("amount_escp", "amountPerformance_npv", "yearlyPaymentsPercentage", "contractDuration"), "active.qualification": view_value_role_esco, "active.awarded": view_value_role_esco, "complete": view_value_role_esco, "unsuccessful": view_value_role_esco, "cancelled": view_value_role_esco, } amount = DecimalType( min_value=Decimal("0"), required=False, precision=-2) # Calculated energy service contract value. amountPerformance = DecimalType( required=False, precision=-2 ) # Calculated energy service contract performance indicator yearlyPaymentsPercentage = DecimalType( required=True, precision=-5, min_value=Decimal("0"), max_value=Decimal( "1")) # The percentage of annual payments in favor of Bidder annualCostsReduction = ListType( DecimalType(), required=True) # Buyer's annual costs reduction contractDuration = ModelType(ContractDuration, required=True)
class Qualification(Model): """ Pre-Qualification """ class Options: roles = { 'create': blacklist('id', 'status', 'documents', 'date'), 'edit': whitelist('status', 'title', 'title_en', 'title_ru', 'description', 'description_en', 'description_ru'), 'embedded': schematics_embedded_role, 'view': schematics_default_role, } title = StringType() title_en = StringType() title_ru = StringType() description = StringType() description_en = StringType() description_ru = StringType() id = MD5Type(required=True, default=lambda: uuid4().hex) bidID = StringType(required=True) lotID = MD5Type() status = StringType( choices=['pending', 'active', 'unsuccessful', 'cancelled'], default='pending') date = IsoDateTimeType() documents = ListType(ModelType(Document), default=list()) complaints = ListType(ModelType(Complaint), default=list()) def validate_lotID(self, data, lotID): if isinstance(data['__parent__'], Model): if not lotID and data['__parent__'].lots: raise ValidationError(u'This field is required.') if lotID and lotID not in [i.id for i in data['__parent__'].lots]: raise ValidationError(u"lotID should be one of lots")
class Bid(BaseBid): class Options: roles = RolesFromCsv('Bid.csv', relative_to=__file__) documents = ListType(ModelType(BidderEUDocument), default=list()) financialDocuments = ListType(ModelType(BidderEUDocument), default=list()) eligibilityDocuments = ListType(ModelType(BidderEUDocument), default=list()) qualificationDocuments = ListType(ModelType(BidderEUDocument), default=list()) lotValues = ListType(ModelType(LotValue), default=list()) selfQualified = BooleanType(required=True, choices=[True]) selfEligible = BooleanType(required=True, choices=[True]) subcontractingDetails = StringType() parameters = ListType(ModelType(Parameter), default=list(), validators=[validate_parameters_uniq]) status = StringType( choices=['draft', 'pending', 'active', 'invalid', 'invalid.pre-qualification', 'unsuccessful', 'deleted'], default='pending' ) def serialize(self, role=None): if role and role != 'create' and self.status in ['invalid', 'invalid.pre-qualification', 'deleted']: role = self.status elif role and role != 'create' and self.status == 'unsuccessful': role = 'bid.unsuccessful' return super(Bid, self).serialize(role) @serializable(serialized_name="status") def serialize_status(self): if self.status in ['draft', 'invalid', 'invalid.pre-qualification', 'unsuccessful', 'deleted'] or self.__parent__.status in ['active.tendering', 'cancelled']: return self.status if self.__parent__.lots: active_lots = [lot.id for lot in self.__parent__.lots if lot.status in ('active', 'complete',)] if not self.lotValues: return 'invalid' elif [i.relatedLot for i in self.lotValues if i.status == 'pending' and i.relatedLot in active_lots]: return 'pending' elif [i.relatedLot for i in self.lotValues if i.status == 'active' and i.relatedLot in active_lots]: return 'active' else: return 'unsuccessful' return self.status @bids_validation_wrapper def validate_value(self, data, value): BaseBid._validator_functions['value'](self, data, value) @bids_validation_wrapper def validate_lotValues(self, data, lotValues): BaseBid._validator_functions['lotValues'](self, data, lotValues) @bids_validation_wrapper def validate_participationUrl(self, data, participationUrl): BaseBid._validator_functions['participationUrl'](self, data, participationUrl) @bids_validation_wrapper def validate_parameters(self, data, parameters): BaseBid._validator_functions['parameters'](self, data, parameters)
class Award(BaseAward): """ An award for the given procurement. There may be more than one award per contracting process e.g. because the contract is split amongst different providers, or because it is a standing offer. """ class Options: roles = { 'create': award_create_reporting_role, 'edit': award_edit_reporting_role, 'embedded': schematics_embedded_role, 'view': schematics_default_role, 'Administrator': whitelist('complaintPeriod'), } qualified = BooleanType() items = ListType(ModelType(Item)) value = ModelType(Value, required=True) documents = ListType(ModelType(Document), default=list()) complaints = ListType(ModelType(Complaint), default=list()) complaintPeriod = ModelType(Period) def validate_value(self, data, value): if value.valueAddedTaxIncluded is not False: raise ValidationError(u"Currently, only procedures with VAT excluded are supported")
class Cancellation(BaseCancellation): class Options: roles = { "create": whitelist("reason", "status", "reasonType", "cancellationOf", "relatedLot"), "edit": whitelist("status", "reasonType"), "embedded": schematics_embedded_role, "view": schematics_default_role, } documents = ListType(ModelType(EUDocument, required=True), default=list())
class Item(BaseItem): """A good, service, or work to be contracted.""" class Options: roles = { 'create': blacklist('deliveryLocation', 'deliveryAddress', 'deliveryDate'), 'edit_active.tendering': blacklist('deliveryLocation', 'deliveryAddress', 'deliveryDate'), } classification = ModelType(CPVCAVClassification, required=True) additionalClassifications = ListType(ModelType(AdditionalClassification), default=list()) address = ModelType(Address) location = ModelType(Location)
class Qualification(Model): """ Pre-Qualification """ class Options: roles = RolesFromCsv('Qualification.csv', relative_to=__file__) title = StringType() title_en = StringType() title_ru = StringType() description = StringType() description_en = StringType() description_ru = StringType() id = MD5Type(required=True, default=lambda: uuid4().hex) bidID = StringType(required=True) lotID = MD5Type() status = StringType(choices=['pending', 'active', 'unsuccessful', 'cancelled'], default='pending') date = IsoDateTimeType() documents = ListType(ModelType(EUDocument), default=list()) complaints = ListType(ModelType(Complaint), default=list()) qualified = BooleanType(default=False) eligible = BooleanType(default=False) def validate_qualified(self, data, qualified): if data['status'] == 'active' and not qualified: raise ValidationError(u'This field is required.') def validate_eligible(self, data, eligible): if data['status'] == 'active' and not eligible: raise ValidationError(u'This field is required.') def validate_lotID(self, data, lotID): if isinstance(data['__parent__'], Model): if not lotID and data['__parent__'].lots: raise ValidationError(u'This field is required.') if lotID and lotID not in [i.id for i in data['__parent__'].lots]: raise ValidationError(u"lotID should be one of lots")
class Tender(BaseTender): """Data regarding tender process - publicly inviting prospective contractors to submit bids for evaluation and selecting a winner or winners.""" procuringEntity = ModelType( ProcuringEntity, required=True ) # The entity managing the procurement, which may be different from the buyer who is paying / using the items lots = ListType(ModelType(Lot), default=list(), validators=[validate_lots_uniq]) procurementMethodType = StringType(default="aboveThresholdUA.defense") procuring_entity_kinds = ['defense'] @serializable(serialized_name="enquiryPeriod", type=ModelType(EnquiryPeriod)) def tender_enquiryPeriod(self): endDate = calculate_business_date(self.tenderPeriod.endDate, -ENQUIRY_PERIOD_TIME, self, True) return EnquiryPeriod( dict(startDate=self.tenderPeriod.startDate, endDate=endDate, invalidationDate=self.enquiryPeriod and self.enquiryPeriod.invalidationDate, clarificationsUntil=calculate_business_date( endDate, ENQUIRY_STAND_STILL_TIME, self, True))) def validate_tenderPeriod(self, data, period): if period and calculate_business_date(period.startDate, TENDER_PERIOD, data, True) > period.endDate: raise ValidationError( u"tenderPeriod should be greater than {0.days} working days". format(TENDER_PERIOD)) @serializable(type=ModelType(Period)) def complaintPeriod(self): if self.tenderPeriod.startDate < COMPLAINT_OLD_SUBMIT_TIME_BEFORE: return Period( dict(startDate=self.tenderPeriod.startDate, endDate=calculate_business_date( self.tenderPeriod.endDate, -COMPLAINT_OLD_SUBMIT_TIME, self))) else: normalized_end = calculate_normalized_date( self.tenderPeriod.endDate, self) return Period( dict(startDate=self.tenderPeriod.startDate, endDate=calculate_business_date(normalized_end, -COMPLAINT_SUBMIT_TIME, self, True)))
class Contract(BaseContract): items = ListType(ModelType(Item, required=True)) class Options: roles = { "edit": whitelist(), "edit_contract": blacklist("id", "documents", "date", "awardID", "suppliers", "contractID"), } def get_role(self): root = self.get_root() request = root.request role = "edit" if request.authenticated_role == "tender_owner": role = "edit_contract" return role
class Change(Model): class Options: roles = { # 'edit': blacklist('id', 'date'), "create": whitelist("rationale", "rationale_ru", "rationale_en", "rationaleTypes", "contractNumber", "dateSigned"), "edit": whitelist("rationale", "rationale_ru", "rationale_en", "rationaleTypes", "contractNumber", "status", "dateSigned"), "view": schematics_default_role, "embedded": schematics_embedded_role, } id = MD5Type(required=True, default=lambda: uuid4().hex) status = StringType(choices=["pending", "active"], default="pending") date = IsoDateTimeType(default=get_now) rationale = StringType(required=True, min_length=1) rationale_en = StringType() rationale_ru = StringType() rationaleTypes = ListType( StringType( choices=[ "volumeCuts", "itemPriceVariation", "qualityImprovement", "thirdParty", "durationExtension", "priceReduction", "taxRate", "fiscalYearExtension", ], required=True, ), min_size=1, required=True, ) contractNumber = StringType() dateSigned = IsoDateTimeType() def validate_dateSigned(self, data, value): if value and value > get_now(): raise ValidationError( u"Contract signature date can't be in the future")