예제 #1
0
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"
예제 #2
0
    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)
예제 #3
0
 def test_iso_duration_type_from_timedelta(self):
     duration_instance = IsoDurationType()
     duration = timedelta(days=1)
     self.assertEqual(duration_instance(duration), duration)
예제 #4
0
 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"