def check_status(request):
    tender = request.validated['tender']
    now = get_now()

    if tender.status == 'active.tendering' and tender.tenderPeriod.endDate <= now and \
            not has_unanswered_complaints(tender) and not has_unanswered_questions(tender):
        for complaint in tender.complaints:
            check_complaint_status(request, complaint)
        LOGGER.info(
            'Switched tender {} to {}'.format(tender['id'],
                                              'active.pre-qualification'),
            extra=context_unpack(
                request,
                {'MESSAGE_ID': 'switched_tender_active.pre-qualification'}))
        tender.status = 'active.pre-qualification'
        tender.qualificationPeriod = type(tender).qualificationPeriod(
            {'startDate': now})
        check_initial_bids_count(request)
        prepare_qualifications(request)
        return

    elif tender.status == 'active.pre-qualification.stand-still' and tender.qualificationPeriod and tender.qualificationPeriod.endDate <= now and not any(
        [
            i.status in tender.block_complaint_status
            for q in tender.qualifications for i in q.complaints
        ]):
        LOGGER.info(
            'Switched tender {} to {}'.format(tender['id'],
                                              'active.stage2.pending'),
            extra=context_unpack(
                request,
                {'MESSAGE_ID': 'switched_tender_active_stage2_pending'}))
        tender.status = 'active.stage2.pending'
        check_initial_bids_count(request)
        return
def check_status(request):
    tender = request.validated['tender']
    now = get_now()

    if tender.status == 'active.tendering' and tender.tenderPeriod.endDate <= now and \
            not has_unanswered_complaints(tender) and not has_unanswered_questions(tender):
        for complaint in tender.complaints:
            check_complaint_status(request, complaint)
        LOGGER.info('Switched tender {} to {}'.format(tender['id'], 'active.pre-qualification'),
                    extra=context_unpack(request, {'MESSAGE_ID': 'switched_tender_active.pre-qualification'}))
        tender.status = 'active.pre-qualification'
        tender.qualificationPeriod = type(tender).qualificationPeriod({'startDate': now})
        check_initial_bids_count(request)
        prepare_qualifications(request)
        return

    elif tender.status == 'active.pre-qualification.stand-still' and tender.qualificationPeriod and tender.qualificationPeriod.endDate <= now and not any([
        i.status in tender.block_complaint_status
        for q in tender.qualifications
        for i in q.complaints
    ]):
        LOGGER.info('Switched tender {} to {}'.format(tender['id'], 'active.stage2.pending'),
                    extra=context_unpack(request, {'MESSAGE_ID': 'switched_tender_active_stage2_pending'}))
        tender.status = 'active.stage2.pending'
        check_initial_bids_count(request)
        return
    def test_has_unanswered_complaints(self):
        tender = Tender(self.tender_data)
        tender.block_tender_complaint_status = ['pending']
        tender.lots = self.lots
        tender.complaints = [Complaint({
            'status': 'pending',
            'relatedLot': '11111111111111111111111111111111',
            'title': 'Earth is mine!'
        })]
        self.assertEqual(True, has_unanswered_complaints(tender))

        tender.complaints[0].relatedLot = '33333333333333333333333333333333'
        self.assertEqual(False, has_unanswered_complaints(tender))

        self.assertEqual(True, has_unanswered_complaints(tender, False))

        tender.complaints[0].status = 'resolved'
        self.assertEqual(False, has_unanswered_complaints(tender, False))
Пример #4
0
    def test_has_unanswered_complaints(self):
        tender = Tender(self.tender_data)
        tender.block_tender_complaint_status = ["pending"]
        tender.lots = self.lots
        tender.complaints = [
            Complaint(
                {"status": "pending", "relatedLot": "11111111111111111111111111111111", "title": "Earth is mine!"}
            )
        ]
        self.assertEqual(True, has_unanswered_complaints(tender))

        tender.complaints[0].relatedLot = "33333333333333333333333333333333"
        self.assertEqual(False, has_unanswered_complaints(tender))

        self.assertEqual(True, has_unanswered_complaints(tender, False))

        tender.complaints[0].status = "resolved"
        self.assertEqual(False, has_unanswered_complaints(tender, False))
Пример #5
0
def check_status(request):
    tender = request.validated["tender"]
    now = get_now()

    check_complaint_statuses_at_complaint_period_end(tender, now)
    check_cancellation_status(request, CancelTenderLot)

    if cancellation_block_tender(tender):
        return

    active_lots = [
        lot.id
        for lot in tender.lots if lot.status == "active"
    ] if tender.lots else [None]

    if (
        tender.status == "active.tendering"
        and tender.tenderPeriod.endDate <= now
        and not has_unanswered_complaints(tender)
        and not has_unanswered_questions(tender)
    ):
        for complaint in tender.complaints:
            check_complaint_status(request, complaint)
        LOGGER.info(
            "Switched tender {} to {}".format(tender["id"], "active.pre-qualification"),
            extra=context_unpack(request, {"MESSAGE_ID": "switched_tender_active.pre-qualification"}),
        )
        tender.status = "active.pre-qualification"
        tender.qualificationPeriod = type(tender).qualificationPeriod({"startDate": now})
        remove_draft_bids(request)
        check_initial_bids_count(request)
        prepare_qualifications(request)
        return

    elif (
        tender.status == "active.pre-qualification.stand-still"
        and tender.qualificationPeriod
        and tender.qualificationPeriod.endDate <= now
        and not any(
            [
                i.status in tender.block_complaint_status
                for q in tender.qualifications
                for i in q.complaints
                if q.lotID in active_lots
            ]
        )
    ):
        LOGGER.info(
            "Switched tender {} to {}".format(tender["id"], "active.auction"),
            extra=context_unpack(request, {"MESSAGE_ID": "switched_tender_active.auction"}),
        )
        tender.status = "active.auction"
        check_initial_bids_count(request)
        return
    elif tender.status == "active.qualification.stand-still":
        check_tender_status_on_active_qualification_stand_still(request)
Пример #6
0
def check_status(request):
    tender = request.validated["tender"]
    now = get_now()
    check_cancellation_status(request, cancel_tender)

    if block_tender(request):
        return

    if (tender.status == "active.tendering"
            and tender.tenderPeriod.endDate <= now
            and not has_unanswered_complaints(tender)
            and not has_unanswered_questions(tender)):
        for complaint in tender.complaints:
            check_complaint_status(request, complaint)
        LOGGER.info(
            "Switched tender {} to {}".format(tender["id"],
                                              "active.pre-qualification"),
            extra=context_unpack(
                request,
                {"MESSAGE_ID": "switched_tender_active.pre-qualification"}),
        )
        tender.status = "active.pre-qualification"
        tender.qualificationPeriod = type(tender).qualificationPeriod(
            {"startDate": now})
        check_initial_bids_count(request)
        prepare_qualifications(request)

    elif (tender.status == "active.pre-qualification.stand-still"
          and tender.qualificationPeriod
          and tender.qualificationPeriod.endDate <= now and not any([
              i.status in tender.block_complaint_status
              for q in tender.qualifications for i in q.complaints
          ])):
        LOGGER.info(
            "Switched tender {} to {}".format(tender["id"],
                                              "active.stage2.pending"),
            extra=context_unpack(
                request,
                {"MESSAGE_ID": "switched_tender_active_stage2_pending"}),
        )
        tender.status = "active.stage2.pending"
        check_initial_bids_count(request)
Пример #7
0
def check_status(request):
    tender = request.validated['tender']
    now = get_now()
    active_lots = [lot.id for lot in tender.lots
                   if lot.status == 'active'] if tender.lots else [None]
    if tender.status == 'active.tendering' and tender.tenderPeriod.endDate <= now and \
            not has_unanswered_complaints(tender) and not has_unanswered_questions(tender):
        for complaint in tender.complaints:
            check_complaint_status(request, complaint)
        LOGGER.info(
            'Switched tender {} to {}'.format(tender['id'],
                                              'active.pre-qualification'),
            extra=context_unpack(
                request,
                {'MESSAGE_ID': 'switched_tender_active.pre-qualification'}))
        tender.status = 'active.pre-qualification'
        tender.qualificationPeriod = type(tender).qualificationPeriod(
            {'startDate': now})
        remove_draft_bids(request)
        check_initial_bids_count(request)
        prepare_qualifications(request)
        return

    elif tender.status == 'active.pre-qualification.stand-still' and tender.qualificationPeriod and tender.qualificationPeriod.endDate <= now and not any(
        [
            i.status in tender.block_complaint_status
            for q in tender.qualifications
            for i in q.complaints if q.lotID in active_lots
        ]):
        LOGGER.info('Switched tender {} to {}'.format(tender['id'],
                                                      'active.auction'),
                    extra=context_unpack(
                        request,
                        {'MESSAGE_ID': 'switched_tender_active.auction'}))
        tender.status = 'active.auction'
        check_initial_bids_count(request)
        return
    elif tender.status == 'active.qualification.stand-still':
        check_tender_status_on_active_qualification_stand_still(request)
        return
Пример #8
0
def check_status(request):
    tender = request.validated["tender"]
    now = get_now()

    check_complaint_statuses_at_complaint_period_end(tender, now)
    check_cancellation_status(request)

    if cancellation_block_tender(tender):
        return

    for award in tender.awards:
        if award.status == "active" and not any(
            [i.awardID == award.id for i in tender.contracts]):
            add_contract(request, award, now)
            add_next_award(request)
    if (not tender.lots and tender.status == "active.tendering"
            and tender.tenderPeriod.endDate <= now
            and not has_unanswered_complaints(tender)
            and not has_unanswered_questions(tender)):
        for complaint in tender.complaints:
            check_complaint_status(request, complaint)
        LOGGER.info(
            "Switched tender {} to {}".format(tender["id"], "active.auction"),
            extra=context_unpack(
                request, {"MESSAGE_ID": "switched_tender_active.auction"}),
        )
        tender.status = "active.auction"
        check_bids(request)
        if tender.numberOfBids < 2 and tender.auctionPeriod:
            tender.auctionPeriod.startDate = None
        return
    elif (tender.lots and tender.status == "active.tendering"
          and tender.tenderPeriod.endDate <= now
          and not has_unanswered_complaints(tender)
          and not has_unanswered_questions(tender)):
        for complaint in tender.complaints:
            check_complaint_status(request, complaint)
        LOGGER.info(
            "Switched tender {} to {}".format(tender["id"], "active.auction"),
            extra=context_unpack(
                request, {"MESSAGE_ID": "switched_tender_active.auction"}),
        )
        tender.status = "active.auction"
        check_bids(request)
        [
            setattr(i.auctionPeriod, "startDate", None) for i in tender.lots
            if i.numberOfBids < 2 and i.auctionPeriod
        ]
        return
    elif not tender.lots and tender.status == "active.awarded":
        standStillEnds = [
            a.complaintPeriod.endDate.astimezone(TZ) for a in tender.awards
            if a.complaintPeriod and a.complaintPeriod.endDate
        ]
        if not standStillEnds:
            return
        standStillEnd = max(standStillEnds)
        if standStillEnd <= now:
            pending_complaints = any([
                i["status"] in tender.block_complaint_status
                for i in tender.complaints
            ])
            pending_awards_complaints = any([
                i["status"] in tender.block_complaint_status
                for a in tender.awards for i in a.complaints
            ])
            awarded = any([i["status"] == "active" for i in tender.awards])
            if not pending_complaints and not pending_awards_complaints and not awarded:
                LOGGER.info(
                    "Switched tender {} to {}".format(tender.id,
                                                      "unsuccessful"),
                    extra=context_unpack(
                        request,
                        {"MESSAGE_ID": "switched_tender_unsuccessful"}),
                )
                check_tender_status(request)
                return
    elif tender.lots and tender.status in [
            "active.qualification", "active.awarded"
    ]:
        if any([
                i["status"] in tender.block_complaint_status
                and i.relatedLot is None for i in tender.complaints
        ]):
            return
        for lot in tender.lots:
            if lot["status"] != "active":
                continue
            lot_awards = [i for i in tender.awards if i.lotID == lot.id]
            standStillEnds = [
                a.complaintPeriod.endDate.astimezone(TZ) for a in lot_awards
                if a.complaintPeriod and a.complaintPeriod.endDate
            ]
            if not standStillEnds:
                continue
            standStillEnd = max(standStillEnds)
            if standStillEnd <= now:
                pending_complaints = any([
                    i["status"] in tender.block_complaint_status
                    and i.relatedLot == lot.id for i in tender.complaints
                ])
                pending_awards_complaints = any([
                    i["status"] in tender.block_complaint_status
                    for a in lot_awards for i in a.complaints
                ])
                awarded = any([i["status"] == "active" for i in lot_awards])
                if not pending_complaints and not pending_awards_complaints and not awarded:
                    LOGGER.info(
                        "Switched lot {} of tender {} to {}".format(
                            lot["id"], tender.id, "unsuccessful"),
                        extra=context_unpack(
                            request,
                            {"MESSAGE_ID": "switched_lot_unsuccessful"},
                            {"LOT_ID": lot["id"]}),
                    )
                    check_tender_status(request)
Пример #9
0
def check_status(request):
    tender = request.validated["tender"]
    now = get_now()
    configurator = request.content_configurator

    check_complaint_statuses_at_complaint_period_end(tender, now)
    check_cancellation_status(request, CancelTenderLot)

    active_lots = [lot.id for lot in tender.lots
                   if lot.status == "active"] if tender.lots else [None]
    for award in tender.awards:
        if award.status == "active" and not any(
            [i.awardID == award.id for i in tender.contracts]):
            add_contract(request, award, now)
            add_next_award(
                request,
                reverse=configurator.reverse_awarding_criteria,
                awarding_criteria_key=configurator.awarding_criteria_key,
            )

    if block_tender(request):
        return

    if (tender.status == "active.tendering"
            and tender.tenderPeriod.endDate <= now
            and not has_unanswered_complaints(tender)
            and not has_unanswered_questions(tender)):
        for complaint in tender.complaints:
            check_complaint_status(request, complaint)
        LOGGER.info(
            "Switched tender {} to {}".format(tender["id"],
                                              "active.pre-qualification"),
            extra=context_unpack(
                request,
                {"MESSAGE_ID": "switched_tender_active.pre-qualification"}),
        )
        tender.status = "active.pre-qualification"
        tender.qualificationPeriod = type(tender).qualificationPeriod(
            {"startDate": now})
        remove_draft_bids(request)
        check_initial_bids_count(request)
        prepare_qualifications(request)

    elif (tender.status == "active.pre-qualification.stand-still"
          and tender.qualificationPeriod
          and tender.qualificationPeriod.endDate <= now and not any([
              i.status in tender.block_complaint_status
              for q in tender.qualifications
              for i in q.complaints if q.lotID in active_lots
          ])):
        LOGGER.info(
            "Switched tender {} to {}".format(tender["id"], "active.auction"),
            extra=context_unpack(
                request, {"MESSAGE_ID": "switched_tender_active.auction"}),
        )
        tender.status = "active.auction"
        check_initial_bids_count(request)

    elif not tender.lots and tender.status == "active.awarded":
        standStillEnds = [
            a.complaintPeriod.endDate.astimezone(TZ) for a in tender.awards
            if a.complaintPeriod and a.complaintPeriod.endDate
        ]
        if standStillEnds:
            standStillEnd = max(standStillEnds)
            if standStillEnd <= now:
                check_tender_status(request)
    elif tender.lots and tender.status in [
            "active.qualification", "active.awarded"
    ]:
        for lot in tender.lots:
            if lot["status"] != "active":
                continue
            lot_awards = [i for i in tender.awards if i.lotID == lot.id]
            standStillEnds = [
                a.complaintPeriod.endDate.astimezone(TZ) for a in lot_awards
                if a.complaintPeriod and a.complaintPeriod.endDate
            ]
            if not standStillEnds:
                continue
            standStillEnd = max(standStillEnds)
            if standStillEnd <= now:
                check_tender_status(request)
                break
Пример #10
0
def check_status(request):
    tender = request.validated["tender"]
    now = get_now()
    configurator = request.content_configurator
    for award in tender.awards:
        if award.status == "active" and not any([i.awardID == award.id for i in tender.contracts]):
            add_contract(request, award, now)
            add_next_award(
                request,
                reverse=configurator.reverse_awarding_criteria,
                awarding_criteria_key=configurator.awarding_criteria_key,
            )
    if (
        not tender.lots
        and tender.status == "active.tendering"
        and tender.tenderPeriod.endDate <= now
        and not has_unanswered_complaints(tender)
        and not has_unanswered_questions(tender)
    ):
        for complaint in tender.complaints:
            check_complaint_status(request, complaint)
        LOGGER.info(
            "Switched tender {} to {}".format(tender["id"], "active.auction"),
            extra=context_unpack(request, {"MESSAGE_ID": "switched_tender_active.auction"}),
        )
        tender.status = "active.auction"
        remove_draft_bids(request)
        check_bids(request)
        if tender.numberOfBids < 2 and tender.auctionPeriod:
            tender.auctionPeriod.startDate = None
        return
    elif (
        tender.lots
        and tender.status == "active.tendering"
        and tender.tenderPeriod.endDate <= now
        and not has_unanswered_complaints(tender)
        and not has_unanswered_questions(tender)
    ):
        for complaint in tender.complaints:
            check_complaint_status(request, complaint)
        LOGGER.info(
            "Switched tender {} to {}".format(tender["id"], "active.auction"),
            extra=context_unpack(request, {"MESSAGE_ID": "switched_tender_active.auction"}),
        )
        tender.status = "active.auction"
        remove_draft_bids(request)
        check_bids(request)
        [setattr(i.auctionPeriod, "startDate", None) for i in tender.lots if i.numberOfBids < 2 and i.auctionPeriod]
        return
    elif not tender.lots and tender.status == "active.awarded":
        standStillEnds = [a.complaintPeriod.endDate.astimezone(TZ) for a in tender.awards if a.complaintPeriod.endDate]
        if not standStillEnds:
            return
        standStillEnd = max(standStillEnds)
        if standStillEnd <= now:
            check_tender_status(request)
    elif tender.lots and tender.status in ["active.qualification", "active.awarded"]:
        if any([i["status"] in tender.block_complaint_status and i.relatedLot is None for i in tender.complaints]):
            return
        for lot in tender.lots:
            if lot["status"] != "active":
                continue
            lot_awards = [i for i in tender.awards if i.lotID == lot.id]
            standStillEnds = [a.complaintPeriod.endDate.astimezone(TZ) for a in lot_awards if a.complaintPeriod.endDate]
            if not standStillEnds:
                continue
            standStillEnd = max(standStillEnds)
            if standStillEnd <= now:
                check_tender_status(request)
                return
Пример #11
0
    def __call__(self, obj):
        now = get_now()
        checks = []
        configurator = getAdapter(obj, IContentConfigurator)
        if (obj.status == "active.tendering" and obj.tenderPeriod.endDate
                and not has_unanswered_complaints(obj)
                and not has_unanswered_questions(obj)):
            checks.append(obj.tenderPeriod.endDate.astimezone(configurator.tz))
        elif (obj.status == "active.pre-qualification.stand-still"
              and obj.qualificationPeriod and obj.qualificationPeriod.endDate):
            active_lots = [
                lot.id for lot in obj.lots if lot.status == "active"
            ] if obj.lots else [None]
            if not any([
                    i.status in obj.block_complaint_status
                    for q in obj.qualifications
                    for i in q.complaints if q.lotID in active_lots
            ]):
                checks.append(
                    obj.qualificationPeriod.endDate.astimezone(
                        configurator.tz))
        elif (not obj.lots and obj.status == "active.auction"
              and obj.auctionPeriod and obj.auctionPeriod.startDate
              and not obj.auctionPeriod.endDate):
            if now < obj.auctionPeriod.startDate:
                checks.append(
                    obj.auctionPeriod.startDate.astimezone(configurator.tz))
            elif now < calc_auction_end_time(
                    obj.numberOfBids, obj.auctionPeriod.startDate).astimezone(
                        configurator.tz):
                checks.append(
                    calc_auction_end_time(
                        obj.numberOfBids,
                        obj.auctionPeriod.startDate).astimezone(
                            configurator.tz))
        elif obj.lots and obj.status == "active.auction":
            for lot in obj.lots:
                if (lot.status != "active" or not lot.auctionPeriod
                        or not lot.auctionPeriod.startDate
                        or lot.auctionPeriod.endDate):
                    continue
                if now < lot.auctionPeriod.startDate:
                    checks.append(
                        lot.auctionPeriod.startDate.astimezone(
                            configurator.tz))
                elif now < calc_auction_end_time(
                        lot.numberOfBids,
                        lot.auctionPeriod.startDate).astimezone(
                            configurator.tz):
                    checks.append(
                        calc_auction_end_time(
                            lot.numberOfBids,
                            lot.auctionPeriod.startDate).astimezone(
                                configurator.tz))
        elif obj.status == "active.qualification.stand-still" and obj.awardPeriod and obj.awardPeriod.endDate:
            active_lots = [
                lot.id for lot in obj.lots if lot.status == "active"
            ] if obj.lots else [None]
            if not any([
                    i.status in obj.block_complaint_status
                    for q in obj.qualifications
                    for i in q.complaints if q.lotID in active_lots
            ]):
                checks.append(
                    obj.awardPeriod.endDate.astimezone(configurator.tz))

        extend_next_check_by_complaint_period_ends(obj, checks)

        return min(checks).isoformat() if checks else None
def check_status(request):
    tender = request.validated['tender']
    now = get_now()
    active_lots = [lot.id for lot in tender.lots
                   if lot.status == 'active'] if tender.lots else [None]
    configurator = request.content_configurator
    for award in tender.awards:
        if award.status == 'active' and not any(
            [i.awardID == award.id for i in tender.contracts]):
            tender.contracts.append(
                type(tender).contracts.model_class({
                    'awardID':
                    award.id,
                    'suppliers':
                    award.suppliers,
                    'value':
                    award.value,
                    'date':
                    now,
                    'items':
                    [i for i in tender.items if i.relatedLot == award.lotID],
                    'contractID':
                    '{}-{}{}'.format(tender.tenderID,
                                     request.registry.server_id,
                                     len(tender.contracts) + 1)
                }))
            add_next_award(
                request,
                reverse=configurator.reverse_awarding_criteria,
                awarding_criteria_key=configurator.awarding_criteria_key)

    if tender.status == 'active.tendering' and tender.tenderPeriod.endDate <= now and \
            not has_unanswered_complaints(tender) and not has_unanswered_questions(tender):
        for complaint in tender.complaints:
            check_complaint_status(request, complaint)
        LOGGER.info(
            'Switched tender {} to {}'.format(tender['id'],
                                              'active.pre-qualification'),
            extra=context_unpack(
                request,
                {'MESSAGE_ID': 'switched_tender_active.pre-qualification'}))
        tender.status = 'active.pre-qualification'
        tender.qualificationPeriod = type(tender).qualificationPeriod(
            {'startDate': now})
        remove_draft_bids(request)
        check_initial_bids_count(request)
        prepare_qualifications(request)
        return

    elif tender.status == 'active.pre-qualification.stand-still' and tender.qualificationPeriod and tender.qualificationPeriod.endDate <= now and not any(
        [
            i.status in tender.block_complaint_status
            for q in tender.qualifications
            for i in q.complaints if q.lotID in active_lots
        ]):
        LOGGER.info('Switched tender {} to {}'.format(tender['id'],
                                                      'active.auction'),
                    extra=context_unpack(
                        request,
                        {'MESSAGE_ID': 'switched_tender_active.auction'}))
        tender.status = 'active.auction'
        check_initial_bids_count(request)
        return

    elif not tender.lots and tender.status == 'active.awarded':
        standStillEnds = [
            a.complaintPeriod.endDate.astimezone(TZ) for a in tender.awards
            if a.complaintPeriod.endDate
        ]
        if not standStillEnds:
            return
        standStillEnd = max(standStillEnds)
        if standStillEnd <= now:
            check_tender_status(request)
    elif tender.lots and tender.status in [
            'active.qualification', 'active.awarded'
    ]:
        if any([
                i['status'] in tender.block_complaint_status
                and i.relatedLot is None for i in tender.complaints
        ]):
            return
        for lot in tender.lots:
            if lot['status'] != 'active':
                continue
            lot_awards = [i for i in tender.awards if i.lotID == lot.id]
            standStillEnds = [
                a.complaintPeriod.endDate.astimezone(TZ) for a in lot_awards
                if a.complaintPeriod.endDate
            ]
            if not standStillEnds:
                continue
            standStillEnd = max(standStillEnds)
            if standStillEnd <= now:
                check_tender_status(request)
                return
Пример #13
0
def check_status(request):
    tender = request.validated['tender']
    now = get_now()
    for award in tender.awards:
        if award.status == 'active' and not any(
            [i.awardID == award.id for i in tender.contracts]):
            tender.contracts.append(
                type(tender).contracts.model_class({
                    'awardID':
                    award.id,
                    'suppliers':
                    award.suppliers,
                    'value':
                    award.value,
                    'date':
                    now,
                    'items':
                    [i for i in tender.items if i.relatedLot == award.lotID],
                    'contractID':
                    '{}-{}{}'.format(tender.tenderID,
                                     request.registry.server_id,
                                     len(tender.contracts) + 1)
                }))
            add_next_award(request)
    if not tender.lots and tender.status == 'active.tendering' and tender.tenderPeriod.endDate <= now and \
            not has_unanswered_complaints(tender) and not has_unanswered_questions(tender):
        for complaint in tender.complaints:
            check_complaint_status(request, complaint)
        LOGGER.info('Switched tender {} to {}'.format(tender['id'],
                                                      'active.auction'),
                    extra=context_unpack(
                        request,
                        {'MESSAGE_ID': 'switched_tender_active.auction'}))
        tender.status = 'active.auction'
        check_bids(request)
        if tender.numberOfBids < 2 and tender.auctionPeriod:
            tender.auctionPeriod.startDate = None
        return
    elif tender.lots and tender.status == 'active.tendering' and tender.tenderPeriod.endDate <= now and \
            not has_unanswered_complaints(tender) and not has_unanswered_questions(tender):
        for complaint in tender.complaints:
            check_complaint_status(request, complaint)
        LOGGER.info('Switched tender {} to {}'.format(tender['id'],
                                                      'active.auction'),
                    extra=context_unpack(
                        request,
                        {'MESSAGE_ID': 'switched_tender_active.auction'}))
        tender.status = 'active.auction'
        check_bids(request)
        [
            setattr(i.auctionPeriod, 'startDate', None) for i in tender.lots
            if i.numberOfBids < 2 and i.auctionPeriod
        ]
        return
    elif not tender.lots and tender.status == 'active.awarded':
        standStillEnds = [
            a.complaintPeriod.endDate.astimezone(TZ) for a in tender.awards
            if a.complaintPeriod.endDate
        ]
        if not standStillEnds:
            return
        standStillEnd = max(standStillEnds)
        if standStillEnd <= now:
            pending_complaints = any([
                i['status'] in tender.block_complaint_status
                for i in tender.complaints
            ])
            pending_awards_complaints = any([
                i['status'] in tender.block_complaint_status
                for a in tender.awards for i in a.complaints
            ])
            awarded = any([i['status'] == 'active' for i in tender.awards])
            if not pending_complaints and not pending_awards_complaints and not awarded:
                LOGGER.info(
                    'Switched tender {} to {}'.format(tender.id,
                                                      'unsuccessful'),
                    extra=context_unpack(
                        request,
                        {'MESSAGE_ID': 'switched_tender_unsuccessful'}))
                check_tender_status(request)
                return
    elif tender.lots and tender.status in [
            'active.qualification', 'active.awarded'
    ]:
        if any([
                i['status'] in tender.block_complaint_status
                and i.relatedLot is None for i in tender.complaints
        ]):
            return
        for lot in tender.lots:
            if lot['status'] != 'active':
                continue
            lot_awards = [i for i in tender.awards if i.lotID == lot.id]
            standStillEnds = [
                a.complaintPeriod.endDate.astimezone(TZ) for a in lot_awards
                if a.complaintPeriod.endDate
            ]
            if not standStillEnds:
                continue
            standStillEnd = max(standStillEnds)
            if standStillEnd <= now:
                pending_complaints = any([
                    i['status'] in tender.block_complaint_status
                    and i.relatedLot == lot.id for i in tender.complaints
                ])
                pending_awards_complaints = any([
                    i['status'] in tender.block_complaint_status
                    for a in lot_awards for i in a.complaints
                ])
                awarded = any([i['status'] == 'active' for i in lot_awards])
                if not pending_complaints and not pending_awards_complaints and not awarded:
                    LOGGER.info(
                        'Switched lot {} of tender {} to {}'.format(
                            lot['id'], tender.id, 'unsuccessful'),
                        extra=context_unpack(
                            request,
                            {'MESSAGE_ID': 'switched_lot_unsuccessful'},
                            {'LOT_ID': lot['id']}))
                    check_tender_status(request)
Пример #14
0
def check_status(request):
    tender = request.validated["tender"]

    now = get_now()

    check_complaint_statuses_at_complaint_period_end(tender, now)
    check_cancellation_status(request, cancel_class=CancelTenderLot)

    for award in tender.awards:
        if award.status == "active" and not any(
            [i.awardID == award.id for i in tender.contracts]):
            add_contracts(request, award, now)
            add_next_award(request)

    if cancellation_block_tender(tender):
        return

    if (not tender.lots and tender.status == "active.tendering"
            and tender.tenderPeriod.endDate <= now
            and not has_unanswered_complaints(tender)
            and not has_unanswered_questions(tender)):
        for complaint in tender.complaints:
            check_complaint_status(request, complaint)
        LOGGER.info(
            "Switched tender {} to {}".format(tender["id"], "active.auction"),
            extra=context_unpack(
                request, {"MESSAGE_ID": "switched_tender_active.auction"}),
        )
        tender.status = "active.auction"
        remove_draft_bids(request)
        check_bids(request)
        if tender.numberOfBids < 2 and tender.auctionPeriod:
            tender.auctionPeriod.startDate = None
    elif (tender.lots and tender.status == "active.tendering"
          and tender.tenderPeriod.endDate <= now
          and not has_unanswered_complaints(tender)
          and not has_unanswered_questions(tender)):
        for complaint in tender.complaints:
            check_complaint_status(request, complaint)
        LOGGER.info(
            "Switched tender {} to {}".format(tender["id"], "active.auction"),
            extra=context_unpack(
                request, {"MESSAGE_ID": "switched_tender_active.auction"}),
        )
        tender.status = "active.auction"
        remove_draft_bids(request)
        check_bids(request)
        [
            setattr(i.auctionPeriod, "startDate", None) for i in tender.lots
            if i.numberOfBids < 2 and i.auctionPeriod
        ]

    elif not tender.lots and tender.status == "active.awarded":
        standStillEnds = [
            a.complaintPeriod.endDate.astimezone(TZ) for a in tender.awards
            if a.complaintPeriod and a.complaintPeriod.endDate
        ]
        if standStillEnds:
            standStillEnd = max(standStillEnds)
            if standStillEnd <= now:
                check_tender_status(request)
    elif tender.lots and tender.status in [
            "active.qualification", "active.awarded"
    ]:
        for lot in tender.lots:
            if lot["status"] != "active":
                continue
            lot_awards = [i for i in tender.awards if i.lotID == lot.id]
            standStillEnds = [
                a.complaintPeriod.endDate.astimezone(TZ) for a in lot_awards
                if a.complaintPeriod and a.complaintPeriod.endDate
            ]
            if not standStillEnds:
                continue
            standStillEnd = max(standStillEnds)
            if standStillEnd <= now:
                check_tender_status(request)
                break
 def next_check(self):
     now = get_now()
     checks = []
     if self.status == 'active.tendering' and self.tenderPeriod.endDate and \
         not has_unanswered_complaints(self) and not has_unanswered_questions(self):
         checks.append(self.tenderPeriod.endDate.astimezone(TZ))
     elif not self.lots and self.status == 'active.auction' and self.auctionPeriod and self.auctionPeriod.startDate and not self.auctionPeriod.endDate:
         if now < self.auctionPeriod.startDate:
             checks.append(self.auctionPeriod.startDate.astimezone(TZ))
         elif now < calc_auction_end_time(
                 self.numberOfBids,
                 self.auctionPeriod.startDate).astimezone(TZ):
             checks.append(
                 calc_auction_end_time(
                     self.numberOfBids,
                     self.auctionPeriod.startDate).astimezone(TZ))
     elif self.lots and self.status == 'active.auction':
         for lot in self.lots:
             if lot.status != 'active' or not lot.auctionPeriod or not lot.auctionPeriod.startDate or lot.auctionPeriod.endDate:
                 continue
             if now < lot.auctionPeriod.startDate:
                 checks.append(lot.auctionPeriod.startDate.astimezone(TZ))
             elif now < calc_auction_end_time(
                     lot.numberOfBids,
                     lot.auctionPeriod.startDate).astimezone(TZ):
                 checks.append(
                     calc_auction_end_time(
                         lot.numberOfBids,
                         lot.auctionPeriod.startDate).astimezone(TZ))
     elif not self.lots and self.status == 'active.awarded' and not any(
         [i.status in self.block_complaint_status
          for i in self.complaints]) and not any([
              i.status in self.block_complaint_status for a in self.awards
              for i in a.complaints
          ]):
         standStillEnds = [
             a.complaintPeriod.endDate.astimezone(TZ) for a in self.awards
             if a.complaintPeriod.endDate
         ]
         last_award_status = self.awards[-1].status if self.awards else ''
         if standStillEnds and last_award_status == 'unsuccessful':
             checks.append(max(standStillEnds))
     elif self.lots and self.status in [
             'active.qualification', 'active.awarded'
     ] and not any([
             i.status in self.block_complaint_status
             and i.relatedLot is None for i in self.complaints
     ]):
         for lot in self.lots:
             if lot['status'] != 'active':
                 continue
             lot_awards = [i for i in self.awards if i.lotID == lot.id]
             pending_complaints = any([
                 i['status'] in self.block_complaint_status
                 and i.relatedLot == lot.id for i in self.complaints
             ])
             pending_awards_complaints = any([
                 i.status in self.block_complaint_status for a in lot_awards
                 for i in a.complaints
             ])
             standStillEnds = [
                 a.complaintPeriod.endDate.astimezone(TZ)
                 for a in lot_awards if a.complaintPeriod.endDate
             ]
             last_award_status = lot_awards[-1].status if lot_awards else ''
             if not pending_complaints and not pending_awards_complaints and standStillEnds and last_award_status == 'unsuccessful':
                 checks.append(max(standStillEnds))
     if self.status.startswith('active'):
         for award in self.awards:
             if award.status == 'active' and not any(
                 [i.awardID == award.id for i in self.contracts]):
                 checks.append(award.date)
     return min(checks).isoformat() if checks else None
Пример #16
0
    def next_check(self):
        now = get_now()
        checks = []
        if (self.status == "active.tendering" and self.tenderPeriod.endDate
                and not has_unanswered_complaints(self)
                and not has_unanswered_questions(self)):
            checks.append(self.tenderPeriod.endDate.astimezone(TZ))
        elif (not self.lots and self.status == "active.auction"
              and self.auctionPeriod and self.auctionPeriod.startDate
              and not self.auctionPeriod.endDate):
            if now < self.auctionPeriod.startDate:
                checks.append(self.auctionPeriod.startDate.astimezone(TZ))
            elif now < calc_auction_end_time(
                    self.numberOfBids,
                    self.auctionPeriod.startDate).astimezone(TZ):
                checks.append(
                    calc_auction_end_time(
                        self.numberOfBids,
                        self.auctionPeriod.startDate).astimezone(TZ))
        elif self.lots and self.status == "active.auction":
            for lot in self.lots:
                if (lot.status != "active" or not lot.auctionPeriod
                        or not lot.auctionPeriod.startDate
                        or lot.auctionPeriod.endDate):
                    continue
                if now < lot.auctionPeriod.startDate:
                    checks.append(lot.auctionPeriod.startDate.astimezone(TZ))
                elif now < calc_auction_end_time(
                        lot.numberOfBids,
                        lot.auctionPeriod.startDate).astimezone(TZ):
                    checks.append(
                        calc_auction_end_time(
                            lot.numberOfBids,
                            lot.auctionPeriod.startDate).astimezone(TZ))
        elif (not self.lots and self.status == "active.awarded" and not any(
            [i.status in self.block_complaint_status for i in self.complaints])
              and not any([
                  i.status in self.block_complaint_status for a in self.awards
                  for i in a.complaints
              ])):
            standStillEnds = [
                a.complaintPeriod.endDate.astimezone(TZ) for a in self.awards
                if a.complaintPeriod.endDate
            ]
            last_award_status = self.awards[-1].status if self.awards else ""
            if standStillEnds and last_award_status == "unsuccessful":
                checks.append(max(standStillEnds))
        elif (self.lots
              and self.status in ["active.qualification", "active.awarded"]
              and not any([
                  i.status in self.block_complaint_status
                  and i.relatedLot is None for i in self.complaints
              ])):
            for lot in self.lots:
                if lot["status"] != "active":
                    continue
                lot_awards = [i for i in self.awards if i.lotID == lot.id]
                pending_complaints = any([
                    i["status"] in self.block_complaint_status
                    and i.relatedLot == lot.id for i in self.complaints
                ])
                pending_awards_complaints = any([
                    i.status in self.block_complaint_status for a in lot_awards
                    for i in a.complaints
                ])
                standStillEnds = [
                    a.complaintPeriod.endDate.astimezone(TZ)
                    for a in lot_awards if a.complaintPeriod.endDate
                ]
                last_award_status = lot_awards[-1].status if lot_awards else ""
                if (not pending_complaints and not pending_awards_complaints
                        and standStillEnds
                        and last_award_status == "unsuccessful"):
                    checks.append(max(standStillEnds))
        if self.status.startswith("active"):
            for award in self.awards:
                if award.status == "active" and not any(
                    [i.awardID == award.id for i in self.contracts]):
                    checks.append(award.date)

        extend_next_check_by_complaint_period_ends(self, checks)

        return min(checks).isoformat() if checks else None
def check_status(request):
    tender = request.validated['tender']
    now = get_now()
    for award in tender.awards:
        if award.status == 'active' and not any([i.awardID == award.id for i in tender.contracts]):
            tender.contracts.append(type(tender).contracts.model_class({
                'awardID': award.id,
                'suppliers': award.suppliers,
                'value': award.value,
                'date': now,
                'items': [i for i in tender.items if i.relatedLot == award.lotID],
                'contractID': '{}-{}{}'.format(tender.tenderID, request.registry.server_id, len(tender.contracts) + 1)}))
            add_next_award(request)
    if not tender.lots and tender.status == 'active.tendering' and tender.tenderPeriod.endDate <= now and \
            not has_unanswered_complaints(tender) and not has_unanswered_questions(tender):
        for complaint in tender.complaints:
            check_complaint_status(request, complaint)
        LOGGER.info('Switched tender {} to {}'.format(tender['id'], 'active.auction'),
                    extra=context_unpack(request, {'MESSAGE_ID': 'switched_tender_active.auction'}))
        tender.status = 'active.auction'
        check_bids(request)
        if tender.numberOfBids < 2 and tender.auctionPeriod:
            tender.auctionPeriod.startDate = None
        return
    elif tender.lots and tender.status == 'active.tendering' and tender.tenderPeriod.endDate <= now and \
            not has_unanswered_complaints(tender) and not has_unanswered_questions(tender):
        for complaint in tender.complaints:
            check_complaint_status(request, complaint)
        LOGGER.info('Switched tender {} to {}'.format(tender['id'], 'active.auction'),
                    extra=context_unpack(request, {'MESSAGE_ID': 'switched_tender_active.auction'}))
        tender.status = 'active.auction'
        check_bids(request)
        [setattr(i.auctionPeriod, 'startDate', None) for i in tender.lots if i.numberOfBids < 2 and i.auctionPeriod]
        return
    elif not tender.lots and tender.status == 'active.awarded':
        standStillEnds = [
            a.complaintPeriod.endDate.astimezone(TZ)
            for a in tender.awards
            if a.complaintPeriod.endDate
        ]
        if not standStillEnds:
            return
        standStillEnd = max(standStillEnds)
        if standStillEnd <= now:
            pending_complaints = any([
                i['status'] in tender.block_complaint_status
                for i in tender.complaints
            ])
            pending_awards_complaints = any([
                i['status'] in tender.block_complaint_status
                for a in tender.awards
                for i in a.complaints
            ])
            awarded = any([
                i['status'] == 'active'
                for i in tender.awards
            ])
            if not pending_complaints and not pending_awards_complaints and not awarded:
                LOGGER.info('Switched tender {} to {}'.format(tender.id, 'unsuccessful'),
                            extra=context_unpack(request, {'MESSAGE_ID': 'switched_tender_unsuccessful'}))
                check_tender_status(request)
                return
    elif tender.lots and tender.status in ['active.qualification', 'active.awarded']:
        if any([i['status'] in tender.block_complaint_status and i.relatedLot is None for i in tender.complaints]):
            return
        for lot in tender.lots:
            if lot['status'] != 'active':
                continue
            lot_awards = [i for i in tender.awards if i.lotID == lot.id]
            standStillEnds = [
                a.complaintPeriod.endDate.astimezone(TZ)
                for a in lot_awards
                if a.complaintPeriod.endDate
            ]
            if not standStillEnds:
                continue
            standStillEnd = max(standStillEnds)
            if standStillEnd <= now:
                pending_complaints = any([
                    i['status'] in tender.block_complaint_status and i.relatedLot == lot.id
                    for i in tender.complaints
                ])
                pending_awards_complaints = any([
                    i['status'] in tender.block_complaint_status
                    for a in lot_awards
                    for i in a.complaints
                ])
                awarded = any([
                    i['status'] == 'active'
                    for i in lot_awards
                ])
                if not pending_complaints and not pending_awards_complaints and not awarded:
                    LOGGER.info('Switched lot {} of tender {} to {}'.format(lot['id'], tender.id, 'unsuccessful'),
                                extra=context_unpack(request, {'MESSAGE_ID': 'switched_lot_unsuccessful'}, {'LOT_ID': lot['id']}))
                    check_tender_status(request)