def test_iso_duration_type(self): type_duration = IsoDurationType() period_str = "P3Y6M4DT12H30M5S" duration_period = Duration(years=3, months=6, days=4, hours=12, minutes=30, seconds=5) res_to_native = type_duration.to_native(period_str) self.assertEqual(res_to_native.years, 3) self.assertEqual(res_to_native.months, 6) self.assertEqual(res_to_native.days, 4) self.assertEqual(res_to_native.seconds, 45005) self.assertEqual(res_to_native, duration_period) self.assertEqual(duration_isoformat(res_to_native), period_str) res_to_primitive = type_duration.to_primitive(duration_period) self.assertEqual(res_to_primitive, period_str) # Parse with errors result = type_duration.to_native(duration_period) self.assertEqual(result, duration_period) with self.assertRaises(Exception) as context: result = type_duration.to_native("Ptest") self.assertEqual(context.exception.messages, [ "ISO 8601 time designator 'T' missing. Unable to parse datetime string 'test'" ]) with self.assertRaises(Exception) as context: result = type_duration.to_native("P3Y6MW4DT12H30M5S") self.assertEqual(context.exception.messages, ["Unrecognised ISO 8601 date format: '3Y6MW4D'"]) with self.assertRaises(Exception) as context: result = type_duration.to_native(123123) self.assertEqual( context.exception.messages, ["Could not parse 123123. Should be ISO8601 Durations."]) res_native1 = type_duration.to_native("P3Y6M4DT12H30M5S") res_native2 = type_duration.to_native("P2Y18M4DT12H30M5S") self.assertEqual(res_native1, res_native2) res_dur1 = type_duration.to_primitive(res_native1) res_dur2 = type_duration.to_primitive(res_native2) self.assertEqual("P3Y6M4DT12H30M5S", res_dur1) self.assertEqual("P2Y18M4DT12H30M5S", res_dur2)
class CloseFrameworkAgreementUA(Tender): """ OpenEU tender model """ class Options: namespace = "Tender" _core_roles = Tender.Options.roles _procurement_method_details = whitelist("procurementMethodDetails") _edit_fields = _core_roles["edit"] + whitelist( "tenderPeriod", "features", "complaintPeriod", "agreementDuration", "next_check", "procuringEntity", "guarantee", "serializable_enquiryPeriod", "minimalStep", "items", "qualificationPeriod", "value", "maxAwardsCount", "agreements", "numberOfBidders", "hasEnquiries", "serializable_guarantee", "serializable_value", "serializable_minimalStep", ) _edit_role = _edit_fields + whitelist("numberOfBids") _edit_qualification = whitelist("status") + _procurement_method_details _tendering_view_role = ( _core_roles["view"] + _edit_fields + whitelist( "auctionPeriod", "lots", "enquiryPeriod", "complaints", "auctionUrl", "awardPeriod", "qualifications", "questions", "cancellations", "awards", ) ) _view_role = _tendering_view_role + whitelist("numberOfBids", "bids") _complete_view_role = _view_role + whitelist("contractPeriod") roles = { "create": _edit_role + whitelist("mode", "procurementMethodType", "lots"), "edit_draft": _edit_role, "edit": _edit_role, "edit_active.tendering": _edit_role, "edit_active.pre-qualification": _edit_qualification, "edit_active.qualification": _edit_qualification, "edit_cancelled": _procurement_method_details, "edit_complete": _procurement_method_details, "edit_unsuccessful": _procurement_method_details, "edit_active.awarded": _procurement_method_details, "edit_active.auction": _procurement_method_details, "edit_active.pre-qualification.stand-still": _procurement_method_details, "draft": _tendering_view_role + whitelist("contractPeriod"), "active.tendering": _tendering_view_role, "cancelled": _view_role, "active.auction": _view_role, "active.pre-qualification.stand-still": _view_role, "active.qualification.stand-still": _view_role, "view": _complete_view_role, "active.qualification": _complete_view_role, "active.pre-qualification": _complete_view_role, "complete": _complete_view_role, "active.awarded": _complete_view_role, "unsuccessful": _complete_view_role, "contracting": _core_roles["contracting"] + _procurement_method_details, "chronograph": _core_roles["chronograph"] + _procurement_method_details, "chronograph_view": _core_roles["chronograph_view"] + _procurement_method_details, "auction_view": _core_roles["auction_view"] + _procurement_method_details + whitelist("milestones", "mainProcurementCategory"), "Administrator": _core_roles["Administrator"] + _procurement_method_details, "auction_post": _core_roles["auction_post"] + _procurement_method_details, "auction_patch": _core_roles["auction_patch"] + _procurement_method_details, "listing": _core_roles["listing"] + _procurement_method_details, "embedded": _core_roles["embedded"], "plain": _core_roles["plain"], "default": _core_roles["default"], } create_accreditations = (ACCR_3, ACCR_5) central_accreditations = (ACCR_5,) edit_accreditations = (ACCR_4,) procuring_entity_kinds = ["authority", "central", "defense", "general", "social", "special"] block_tender_complaint_status = ["claim", "pending", "accepted", "satisfied", "stopping"] block_complaint_status = ["pending", "accepted", "satisfied", "stopping"] auctionPeriod = ModelType(TenderAuctionPeriod, default={}) auctionUrl = URLType() awards = ListType(ModelType(Award, required=True), default=list()) awardPeriod = ModelType(Period) # The dat e or period on which an award is anticipated to be made. bids = SifterListType( BidModelType(Bid), default=list(), filter_by="status", filter_in_values=["invalid", "invalid.pre-qualification", "deleted"], ) # A list of all the companies who entered submissions for the tender. cancellations = ListType(ModelType(Cancellation, required=True), default=list()) complaints = ListType(ComplaintModelType(Complaint, required=True), default=list()) contractPeriod = ModelType(ContractPeriod, required=False) agreements = ListType(ModelType(Agreement, required=True), default=list()) documents = ListType( ModelType(EUDocument, required=True), default=list() ) # All documents and attachments related to the tender. enquiryPeriod = ModelType(EnquiryPeriod, required=False) guarantee = ModelType(Guarantee) hasEnquiries = BooleanType() # A Yes/No field as to whether enquiries were part of tender process. items = ListType( ModelType(Item, required=True), required=True, min_size=1, validators=[validate_cpv_group, validate_items_uniq, validate_classification_id], ) # The goods and services to be purchased, broken into line items wherever possible. Items should not be duplicated, but a quantity of 2 specified instead. features = ListType(ModelType(Feature, required=True), validators=[validate_features_uniq]) minimalStep = ModelType(Value, required=True) numberOfBidders = IntType() # The number of unique tenderers who participated in the tender maxAwardsCount = IntType(required=True, validators=[validate_max_awards_number]) lots = ListType( ModelType(Lot, required=True), min_size=1, max_size=1, default=list(), validators=[validate_lots_uniq] ) procurementMethodType = StringType(default="closeFrameworkAgreementUA") procuringEntity = ModelType( ProcuringEntity, required=True ) # The entity managing the procurement, which may be different from the buyer who is paying / using the items being procured. qualificationPeriod = ModelType(Period) qualifications = ListType(ModelType(Qualification, required=True), default=list()) questions = ListType(ModelType(Question, required=True), default=list()) status = StringType( choices=[ "draft", "active.tendering", "active.pre-qualification", "active.pre-qualification.stand-still", "active.auction", "active.qualification", "active.qualification.stand-still", "active.awarded", "complete", "cancelled", "unsuccessful", ], default="active.tendering", ) tenderPeriod = ModelType(PeriodStartEndRequired, required=True) title_en = StringType(required=True, min_length=1) value = ModelType(Value, required=True) # The total estimated value of the procurement. agreementDuration = IsoDurationType(required=True, validators=[validate_max_agreement_duration_period]) mainProcurementCategory = StringType(choices=["goods", "services"]) def __local_roles__(self): roles = dict([("{}_{}".format(self.owner, self.owner_token), "tender_owner")]) for i in self.bids: roles["{}_{}".format(i.owner, i.owner_token)] = "bid_owner" return roles def __acl__(self): acl = [ (Allow, "{}_{}".format(i.owner, i.owner_token), "create_qualification_complaint") for i in self.bids if i.status in ["active", "unsuccessful", "invalid.pre-qualification"] ] acl.extend( [ (Allow, "{}_{}".format(i.owner, i.owner_token), "create_award_complaint") for i in self.bids if i.status == "active" ] ) acl.extend( [ (Allow, "{}_{}".format(self.owner, self.owner_token), "edit_complaint"), ] ) self._acl_cancellation_complaint(acl) return acl def check_auction_time(self): if ( self.auctionPeriod and self.auctionPeriod.startDate and self.auctionPeriod.shouldStartAfter and self.auctionPeriod.startDate > calculate_tender_business_date( parse_date(self.auctionPeriod.shouldStartAfter), AUCTION_PERIOD_TIME, self, True ) ): self.auctionPeriod.startDate = None for lot in self.lots: if ( lot.auctionPeriod and lot.auctionPeriod.startDate and lot.auctionPeriod.shouldStartAfter and lot.auctionPeriod.startDate > calculate_tender_business_date( parse_date(lot.auctionPeriod.shouldStartAfter), AUCTION_PERIOD_TIME, self, True ) ): lot.auctionPeriod.startDate = None def invalidate_bids_data(self): self.check_auction_time() self.enquiryPeriod.invalidationDate = get_now() for bid in self.bids: if bid.status not in ["deleted", "draft"]: bid.status = "invalid"
def test_iso_duration_type_from_timedelta(self): duration_instance = IsoDurationType() duration = timedelta(days=1) self.assertEqual(duration_instance(duration), duration)
def test_iso_duration_type_from_Duration(self): duration_instance = IsoDurationType() duration = Duration(months=1, days=1) self.assertEqual(duration_instance(duration), duration)
class CloseFrameworkAgreementUA(Tender): """ OpenEU tender model """ class Options: namespace = 'Tender' roles = RolesFromCsv('CloseFrameworkAgreementUA.csv', relative_to=__file__) create_accreditation = 3 edit_accreditation = 4 procuring_entity_kinds = ['general', 'special', 'defense'] block_tender_complaint_status = [ 'claim', 'pending', 'accepted', 'satisfied', 'stopping' ] block_complaint_status = ['pending', 'accepted', 'satisfied', 'stopping'] auctionPeriod = ModelType(TenderAuctionPeriod, default={}) auctionUrl = URLType() awards = ListType(ModelType(Award), default=list()) awardPeriod = ModelType( Period ) # The dat e or period on which an award is anticipated to be made. bids = SifterListType( BidModelType(Bid), default=list(), filter_by='status', filter_in_values=['invalid', 'invalid.pre-qualification', 'deleted'] ) # A list of all the companies who entered submissions for the tender. cancellations = ListType(ModelType(Cancellation), default=list()) complaints = ListType(ComplaintModelType(Complaint), default=list()) contractPeriod = ModelType(ContractPeriod, required=False) agreements = ListType(ModelType(Agreement), default=list()) documents = ListType( ModelType(EUDocument), default=list()) # All documents and attachments related to the tender. enquiryPeriod = ModelType(EnquiryPeriod, required=False) guarantee = ModelType(Guarantee) hasEnquiries = BooleanType( ) # A Yes/No field as to whether enquiries were part of tender process. items = ListType( ModelType(Item), required=True, min_size=1, validators=[validate_cpv_group, validate_items_uniq] ) # The goods and services to be purchased, broken into line items wherever possible. Items should not be duplicated, but a quantity of 2 specified instead. features = ListType(ModelType(Feature), validators=[validate_features_uniq]) minimalStep = ModelType(Value, required=True) numberOfBidders = IntType( ) # The number of unique tenderers who participated in the tender maxAwardsCount = IntType(required=True, validators=[validate_max_awards_number]) lots = ListType(ModelType(Lot), min_size=1, max_size=1, default=list(), validators=[validate_lots_uniq]) procurementMethodType = StringType(default="closeFrameworkAgreementUA") procuringEntity = ModelType( ProcuringEntity, required=True ) # The entity managing the procurement, which may be different from the buyer who is paying / using the items being procured. qualificationPeriod = ModelType(Period) qualifications = ListType(ModelType(Qualification), default=list()) questions = ListType(ModelType(Question), default=list()) status = StringType(choices=[ 'draft', 'active.tendering', 'active.pre-qualification', 'active.pre-qualification.stand-still', 'active.auction', 'active.qualification', 'active.qualification.stand-still', 'active.awarded', 'complete', 'cancelled', 'unsuccessful' ], default='active.tendering') tenderPeriod = ModelType(PeriodStartEndRequired, required=True) title_en = StringType(required=True, min_length=1) value = ModelType( Value, required=True) # The total estimated value of the procurement. agreementDuration = IsoDurationType( required=True, validators=[validate_max_agreement_duration_period]) def __local_roles__(self): roles = dict([('{}_{}'.format(self.owner, self.owner_token), 'tender_owner')]) for i in self.bids: roles['{}_{}'.format(i.owner, i.owner_token)] = 'bid_owner' return roles def __acl__(self): acl = [(Allow, '{}_{}'.format(i.owner, i.owner_token), 'create_qualification_complaint') for i in self.bids if i.status in ['active', 'unsuccessful', 'invalid.pre-qualification']] acl.extend([(Allow, '{}_{}'.format(i.owner, i.owner_token), 'create_award_complaint') for i in self.bids if i.status == 'active']) acl.extend([ (Allow, '{}_{}'.format(self.owner, self.owner_token), 'edit_tender'), (Allow, '{}_{}'.format(self.owner, self.owner_token), 'upload_tender_documents'), (Allow, '{}_{}'.format(self.owner, self.owner_token), 'edit_complaint'), ]) return acl def check_auction_time(self): if self.auctionPeriod and self.auctionPeriod.startDate and self.auctionPeriod.shouldStartAfter \ and self.auctionPeriod.startDate > calculate_business_date(parse_date(self.auctionPeriod.shouldStartAfter), AUCTION_PERIOD_TIME, self, True): self.auctionPeriod.startDate = None for lot in self.lots: if lot.auctionPeriod and lot.auctionPeriod.startDate and lot.auctionPeriod.shouldStartAfter \ and lot.auctionPeriod.startDate > calculate_business_date(parse_date(lot.auctionPeriod.shouldStartAfter), AUCTION_PERIOD_TIME, self, True): lot.auctionPeriod.startDate = None def invalidate_bids_data(self): self.check_auction_time() self.enquiryPeriod.invalidationDate = get_now() for bid in self.bids: if bid.status not in ["deleted", "draft"]: bid.status = "invalid"