def initialize(self):
     if not self.enquiryPeriod:
         self.enquiryPeriod = type(self).enquiryPeriod.model_class()
     if not self.tenderPeriod:
         self.tenderPeriod = type(self).tenderPeriod.model_class()
     now = get_now()
     start_date = TZ.localize(
         self.auctionPeriod.startDate.replace(tzinfo=None))
     self.auctionPeriod.startDate = None
     self.auctionPeriod.endDate = None
     self.tenderPeriod.startDate = self.enquiryPeriod.startDate = now
     pause_between_periods = start_date - (start_date.replace(
         hour=20, minute=0, second=0, microsecond=0) - timedelta(days=1))
     self.enquiryPeriod.endDate = calculate_business_date(
         start_date, -pause_between_periods, self).astimezone(TZ)
     time_before_tendering_end = (
         start_date.replace(hour=9, minute=30, second=0, microsecond=0) +
         DUTCH_PERIOD) - self.enquiryPeriod.endDate
     self.tenderPeriod.endDate = calculate_business_date(
         self.enquiryPeriod.endDate, time_before_tendering_end, self)
     if SANDBOX_MODE and self.submissionMethodDetails and 'quick' in self.submissionMethodDetails:
         self.tenderPeriod.endDate = (self.enquiryPeriod.endDate +
                                      QUICK_DUTCH_PERIOD).astimezone(TZ)
     self.auctionPeriod.startDate = None
     self.auctionPeriod.endDate = None
     self.date = now
     self.documents.append(
         type(self).documents.model_class(DGF_PLATFORM_LEGAL_DETAILS))
     if not self.auctionParameters:
         self.auctionParameters = type(self).auctionParameters.model_class()
Ejemplo n.º 2
0
 def next_check(self):
     now = get_now()
     checks = []
     if self.status == 'active.tendering' and self.tenderPeriod and self.tenderPeriod.endDate:
         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))
     # Use next_check part from awarding
     request = get_request_from_root(self)
     if request is not None:
         awarding_check = request.registry.getAdapter(
             self, IAwardingNextCheck).add_awarding_checks(self)
         if awarding_check is not None:
             checks.append(awarding_check)
     if self.status.startswith('active'):
         for complaint in self.complaints:
             if complaint.status == 'claim' and complaint.dateSubmitted:
                 checks.append(
                     calculate_business_date(complaint.dateSubmitted,
                                             COMPLAINT_STAND_STILL_TIME,
                                             self))
             elif complaint.status == 'answered' and complaint.dateAnswered:
                 checks.append(
                     calculate_business_date(complaint.dateAnswered,
                                             COMPLAINT_STAND_STILL_TIME,
                                             self))
         for award in self.awards:
             for complaint in award.complaints:
                 if complaint.status == 'claim' and complaint.dateSubmitted:
                     checks.append(
                         calculate_business_date(
                             complaint.dateSubmitted,
                             COMPLAINT_STAND_STILL_TIME, self))
                 elif complaint.status == 'answered' and complaint.dateAnswered:
                     checks.append(
                         calculate_business_date(
                             complaint.dateAnswered,
                             COMPLAINT_STAND_STILL_TIME, self))
     return min(checks).isoformat() if checks else None
Ejemplo n.º 3
0
    def rectification_period(self):
        if self.tenderPeriod:
            self.rectificationPeriod = RectificationPeriod(
            ) if not self.rectificationPeriod else self.rectificationPeriod
            self.rectificationPeriod.startDate = self.tenderPeriod.startDate

            # for a new type of procedure we should allow tenderPeriod of 1 day.
            # In this case rectificationPeriod does not exist. But if rectificationPeriod does not exist
            # procedure is editable. To make it unchangeable,
            # we should create rectificationPeriod with startDate == endDate == tenderPeriod.startDate
            five_working_days_after_start_date = calculate_business_date(
                self.tenderPeriod.startDate,
                timedelta(days=5),
                None,
                working_days=True)
            if self.tenderPeriod.endDate < five_working_days_after_start_date:
                self.rectificationPeriod.endDate = self.rectificationPeriod.startDate
                return self.rectificationPeriod

            self.rectificationPeriod.endDate = calculate_business_date(
                self.tenderPeriod.endDate.astimezone(TZ),
                -timedelta(days=5),
                self,
                working_days=True)

            if self.rectificationPeriod.startDate > self.rectificationPeriod.endDate:
                self.rectificationPeriod.startDate = self.rectificationPeriod.endDate = None

        return self.rectificationPeriod
    def create_auction(self, request):
        self._validate(request, self.create_validation)

        auction = request.validated['auction']

        if not auction.enquiryPeriod:
            auction.enquiryPeriod = type(auction).enquiryPeriod.model_class()
        if not auction.tenderPeriod:
            auction.tenderPeriod = type(auction).tenderPeriod.model_class()

        now = get_now()
        start_date = TZ.localize(auction.auctionPeriod.startDate.replace(tzinfo=None))
        auction.auctionPeriod.startDate = None
        auction.auctionPeriod.endDate = None

        auction.tenderPeriod.startDate = auction.enquiryPeriod.startDate = now

        # Specific logic to make enquiryPeriod.endDate be one day before auctionPeriod.startDate and be set 20 hour
        pause_between_periods = start_date - (start_date.replace(hour=20, minute=0, second=0, microsecond=0) - timedelta(days=1))
        auction.enquiryPeriod.endDate = calculate_business_date(start_date, -pause_between_periods, auction).astimezone(TZ)

        # Specific logic to make tenderPeriod.endDate be from enquiryPeriod.endDate until end of auction
        time_before_tendering_end = (start_date.replace(hour=9, minute=30, second=0, microsecond=0) + DUTCH_PERIOD) - auction.enquiryPeriod.endDate
        auction.tenderPeriod.endDate = calculate_business_date(auction.enquiryPeriod.endDate, time_before_tendering_end, auction)

        if SANDBOX_MODE and auction.submissionMethodDetails and 'quick' in auction.submissionMethodDetails:
            auction.tenderPeriod.endDate = (auction.enquiryPeriod.endDate + QUICK_DUTCH_PERIOD).astimezone(TZ)

        auction.auctionPeriod.startDate = None
        auction.auctionPeriod.endDate = None
        auction.date = now
        if not auction.auctionParameters:
            auction.auctionParameters = type(auction).auctionParameters.model_class()
Ejemplo n.º 5
0
def calculate_enddate(auction, period, duration):
    period.endDate = calculate_business_date(period.startDate, duration,
                                             auction, True)
    round_to_18_hour_delta = period.endDate.replace(
        hour=18, minute=0, second=0) - period.endDate
    period.endDate = calculate_business_date(period.endDate,
                                             round_to_18_hour_delta, auction,
                                             False)
Ejemplo n.º 6
0
    def next_check(self):
        if self.suspended:
            return None
        now = get_now()
        checks = []
        if self.status == 'active.tendering' and self.enquiryPeriod and self.enquiryPeriod.endDate:
            checks.append(self.enquiryPeriod.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(
                    NUMBER_OF_STAGES,
                    self.auctionPeriod.startDate).astimezone(TZ):
                checks.append(
                    calc_auction_end_time(
                        NUMBER_OF_STAGES,
                        self.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))
        if self.status.startswith('active'):
            from openprocurement.auctions.core.utils import calculate_business_date
            for complaint in self.complaints:
                if complaint.status == 'claim' and complaint.dateSubmitted:
                    checks.append(
                        calculate_business_date(
                            complaint.dateSubmitted,
                            AUCTIONS_COMPLAINT_STAND_STILL_TIME, self))
                elif complaint.status == 'answered' and complaint.dateAnswered:
                    checks.append(
                        calculate_business_date(
                            complaint.dateAnswered,
                            AUCTIONS_COMPLAINT_STAND_STILL_TIME, self))
            for award in self.awards:
                for complaint in award.complaints:
                    if complaint.status == 'claim' and complaint.dateSubmitted:
                        checks.append(
                            calculate_business_date(
                                complaint.dateSubmitted,
                                AUCTIONS_COMPLAINT_STAND_STILL_TIME, self))
                    elif complaint.status == 'answered' and complaint.dateAnswered:
                        checks.append(
                            calculate_business_date(
                                complaint.dateAnswered,
                                AUCTIONS_COMPLAINT_STAND_STILL_TIME, self))
        return min(checks).isoformat() if checks else None
    def create_auction(self, request):
        auction = request.validated['auction']
        now = get_now()
        start_date = TZ.localize(
            auction.auctionPeriod.startDate.replace(tzinfo=None))
        pause_between_periods = start_date - (
            set_specific_hour(start_date, hour=20) - timedelta(days=1))
        end_date = calculate_business_date(start_date, -pause_between_periods,
                                           auction)
        if auction.tenderPeriod and auction.tenderPeriod.endDate:
            three_workingDays_before_startDate = calculate_business_date(
                start_date,
                -timedelta(days=3),
                auction,
                working_days=True,
                specific_hour=20)
            if auction.tenderPeriod.endDate.date(
            ) != three_workingDays_before_startDate.date():
                request.errors.add(
                    'body', 'data',
                    'The only possible value for tenderPeriod.endDate is {}'.
                    format(three_workingDays_before_startDate))
                request.errors.status = 422
                return
            else:
                auction.tenderPeriod.endDate = three_workingDays_before_startDate
        else:
            auction.tenderPeriod = type(auction).tenderPeriod.model_class()
            auction.tenderPeriod.endDate = end_date
        if not auction.enquiryPeriod:
            auction.enquiryPeriod = type(auction).enquiryPeriod.model_class()
        auction.enquiryPeriod.endDate = end_date
        if not auction.rectificationPeriod:
            auction.rectificationPeriod = generate_rectificationPeriod_tender_period_margin(
                auction)
        auction.tenderPeriod.startDate = auction.enquiryPeriod.startDate = auction.rectificationPeriod.startDate = auction.date = now
        auction.auctionPeriod.startDate = None
        auction.auctionPeriod.endDate = None
        if auction.lots:
            for lot in auction.lots:
                lot.date = now

        mandatory_additional_classificator = type(
            auction).items.model_class.additionalClassifications.model_class(
                MANDATORY_ADDITIONAL_CLASSIFICATOR)
        for item in auction['items']:
            for additionalClassification in item['additionalClassifications']:
                if (additionalClassification['scheme'] == u'CPVS'
                        and additionalClassification['id'] == u'PA01-7'):
                    break
            else:
                item['additionalClassifications'].append(
                    mandatory_additional_classificator)
Ejemplo n.º 8
0
    def _context(self):
        context = {}
        now = get_now()
        status = get_next_status(self.status)

        shouldStartAfter = iso8601.parse_date(
            self._auction['auctionPeriod']['shouldStartAfter'])
        enquiry_period_end = iso8601.parse_date(
            self._auction['enquiryPeriod']['endDate'])
        odds = shouldStartAfter - enquiry_period_end

        duration_rectification = get_period_duration(self._auction,
                                                     'rectificationPeriod')
        duration_tendering = get_period_duration(self._auction, 'tenderPeriod')
        duration_enquiry = get_period_duration(self._auction, 'enquiryPeriod')

        end_date_rectification = now
        end_date_tendering = calculate_business_date(now, duration_tendering,
                                                     self._auction)
        end_date_enquiry = calculate_business_date(now, duration_enquiry,
                                                   self._auction)

        new_shoulfStartAfter = calculate_business_date(end_date_enquiry, odds,
                                                       self._auction)

        start_date_rectification = calculate_business_date(
            now, -duration_rectification, self._auction)
        start_date_tendering = now
        start_date_enquiry = now

        tender_period = {
            "startDate": start_date_tendering.isoformat(),
            "endDate": end_date_tendering.isoformat()
        }
        enquiry_period = {
            "startDate": start_date_enquiry.isoformat(),
            "endDate": end_date_enquiry.isoformat()
        }

        rectification_period = {
            "startDate": start_date_rectification.isoformat(),
            "endDate": end_date_rectification.isoformat()
        }

        context['status'] = status
        context['rectificationPeriod'] = rectification_period
        context['tenderPeriod'] = tender_period
        context['enquiryPeriod'] = enquiry_period
        context['auctionPeriod'] = {}
        context['auctionPeriod'][
            'shouldStartAfter'] = new_shoulfStartAfter.isoformat()
        return context
 def initialize(self):
     if not self.enquiryPeriod:
         self.enquiryPeriod = type(self).enquiryPeriod.model_class()
     if not self.tenderPeriod:
         self.tenderPeriod = type(self).tenderPeriod.model_class()
     now = get_now()
     start_date = TZ.localize(
         self.auctionPeriod.startDate.replace(
             tzinfo=None))
     self.auctionPeriod.startDate = None
     self.auctionPeriod.endDate = None
     self.tenderPeriod.startDate = self.enquiryPeriod.startDate = now
     pause_between_periods = start_date - (
         start_date.replace(hour=20, minute=0, second=0, microsecond=0) -
         # set period end at 19:30-20:30 to reduce system load
         timedelta(days=1, minutes=randint(-30, 30))
     )
     end_date = calculate_business_date(
         start_date, -pause_between_periods, self)
     self.enquiryPeriod.endDate = end_date
     self.tenderPeriod.endDate = self.enquiryPeriod.endDate
     self.date = now
     if self.lots:
         for lot in self.lots:
             lot.date = now
Ejemplo n.º 10
0
 def initialize(self):
     if not self.enquiryPeriod:
         self.enquiryPeriod = type(self).enquiryPeriod.model_class()
     if not self.tenderPeriod:
         self.tenderPeriod = type(self).tenderPeriod.model_class()
     now = get_now()
     start_date = TZ.localize(
         self.auctionPeriod.startDate.replace(tzinfo=None))
     self.tenderPeriod.startDate = self.enquiryPeriod.startDate = now
     pause_between_periods = start_date - (start_date.replace(
         hour=20, minute=0, second=0, microsecond=0) - timedelta(days=1))
     end_date = calculate_business_date(start_date, -pause_between_periods,
                                        self)
     self.enquiryPeriod.endDate = end_date
     self.tenderPeriod.endDate = self.enquiryPeriod.endDate
     if not self.rectificationPeriod:
         self.rectificationPeriod = generate_rectificationPeriod_tender_period_margin(
             self)
     self.rectificationPeriod.startDate = now
     self.auctionPeriod.startDate = None
     self.auctionPeriod.endDate = None
     self.date = now
     if self.lots:
         for lot in self.lots:
             lot.date = now
Ejemplo n.º 11
0
 def validate_tenderPeriod(self, data, period):
     if not (period and period.startDate and period.endDate):
         return
     if get_auction_creation_date(data) < MINIMAL_EXPOSITION_REQUIRED_FROM:
         return
     if calculate_business_date(period.startDate, MINIMAL_EXPOSITION_PERIOD, data) > period.endDate:
         raise ValidationError(u"tenderPeriod should be greater than 6 days")
Ejemplo n.º 12
0
 def tender_period(self):
     if self.tenderPeriod and self.auctionPeriod.startDate:
         end_date = calculate_business_date(self.auctionPeriod.startDate, DUTCH_PERIOD, self)
         if SANDBOX_MODE and self.submissionMethodDetails and 'quick' in self.submissionMethodDetails:
             end_date = self.auctionPeriod.startDate + QUICK_DUTCH_PERIOD
         if self.auctionPeriod.endDate and self.auctionPeriod.endDate <= self.tenderPeriod.endDate:
             end_date = self.auctionPeriod.endDate.astimezone(TZ)
         self.tenderPeriod.endDate = end_date
     return self.tenderPeriod
Ejemplo n.º 13
0
    def _context(self):
        context = {}
        now = get_now()
        status = get_next_status(self.status)
        duration_rectification = get_period_duration(self._auction,
                                                     'rectificationPeriod')
        duration_tendering = get_period_duration(self._auction, 'tenderPeriod')
        duration_enquiry = get_period_duration(self._auction, 'enquiryPeriod')

        start_tendering_and_enquiry = calculate_business_date(
            now, -duration_tendering, self.auction)

        end_date_rectification = start_tendering_and_enquiry
        end_date_tendering = now
        remainder = duration_enquiry - duration_tendering
        end_date_enquiry = calculate_business_date(now, remainder,
                                                   self.auction)

        start_date_rectification = calculate_business_date(
            end_date_rectification, -duration_rectification, self.auction)
        start_date_tendering = start_tendering_and_enquiry
        start_date_enquiry = start_tendering_and_enquiry

        tender_period = {
            "startDate": start_date_tendering.isoformat(),
            "endDate": end_date_tendering.isoformat()
        }

        enquiry_period = {
            "startDate": start_date_enquiry.isoformat(),
            "endDate": end_date_enquiry.isoformat()
        }

        rectification_period = {
            "startDate": start_date_rectification.isoformat(),
            "endDate": end_date_rectification.isoformat()
        }

        context['status'] = status
        context['rectificationPeriod'] = rectification_period
        context['tenderPeriod'] = tender_period
        context['enquiryPeriod'] = enquiry_period
        return context
Ejemplo n.º 14
0
 def validate_rectificationPeriod(self, data, period):
     if not (period and period.startDate) or not period.endDate:
         return
     if period.endDate > calculate_business_date(
             data['tenderPeriod']['endDate'],
             -MINIMAL_PERIOD_FROM_RECTIFICATION_END, data).astimezone(
                 getattr(period.endDate, 'tzinfo', TZ)):
         raise ValidationError(
             u"rectificationPeriod.endDate should come at least 5 working days earlier than tenderPeriod.endDate"
         )
    def _initialize_rectificationPeriod(self):
        period = self.context.__class__.rectificationPeriod.model_class()

        start_date = self.now
        end_date = calculate_business_date(
            self.now, AUCTION_RECTIFICATION_PERIOD_DURATION, self.context)

        period.startDate = start_date
        period.endDate = end_date

        self.context.rectificationPeriod = period
Ejemplo n.º 16
0
    def set_dueDate(self, milestone, contract):
        """Sets dueDate of the Milestone

        Also takes into account milestone's type, so this method can be used on
        any milestone of Ceasefire contracting.

        :param milestone: milestone to work with
        :param contract: contract, related to milestone

        :type milestone: openprocurement.contracting.ceasefire.models.Milestone
        :type start_date: openprocurement.contracting.ceasefire.models.Contract

        :return: dueDate of milestone
        :rtype: datetime.datetime
        """
        if milestone.type_ == 'financing':
            milestone.dueDate = calculate_business_date(
                contract.dateSigned,
                MILESTONE_FINANCING_DUEDATE_OFFSET,
                context=contract,
                working_days=True,
                specific_hour=18)
        elif milestone.type_ == 'approval':
            financing_milestone = search_list_with_dicts(
                contract.milestones, 'type_', 'financing')
            milestone.dueDate = calculate_business_date(
                financing_milestone.dateMet,
                MILESTONE_APPROVAL_DUEDATE_OFFSET,
                context=contract,
                working_days=True,
                specific_hour=18)
        elif milestone.type_ == 'reporting' and milestone.dueDate is None:
            approval_milestone = search_list_with_dicts(
                contract.milestones, 'type_', 'approval')
            milestone.dueDate = datetime.combine(
                date(
                    approval_milestone.dateMet.year +
                    MILESTONE_REPORTING_DUEDATE_OFFSET_YEARS,
                    approval_milestone.dateMet.month,
                    approval_milestone.dateMet.day),
                approval_milestone.dateMet.time())
Ejemplo n.º 17
0
    def validate_tenderPeriod(self, data, value):
        if value and value.get('startDate') and value.get('endDate'):

            min_end_date_limit = calculate_business_date(
                value['startDate'],
                timedelta(days=MIN_TENDER_PERIOD_DAYS_AMOUNT),
                data,
                working_days=True)
            if value['endDate'] < min_end_date_limit:
                raise ValidationError(
                    u"tenderPeriod should be at least {} working days".format(
                        MIN_TENDER_PERIOD_DAYS_AMOUNT))
Ejemplo n.º 18
0
def generate_rectificationPeriod(auction):
    now = get_now()
    if not auction.rectificationPeriod:
        period = type(auction).rectificationPeriod.model_class()
    period.startDate = period.startDate or now
    if not period.endDate:
        calculated_endDate = calculate_business_date(
            auction.tenderPeriod.endDate,
            -MINIMAL_PERIOD_FROM_RECTIFICATION_END, auction)
        period.endDate = calculated_endDate if calculated_endDate > now else now
    period.invalidationDate = None
    return period
    def _initialize_tenderPeriod(self):
        period = self._context.__class__.tenderPeriod.model_class()

        start_date = self._context.rectificationPeriod.endDate
        end_date = calculate_business_date(start_date,
                                           TENDER_PERIOD_DURATION,
                                           self._context,
                                           working_days=True)

        period.startDate = start_date
        period.endDate = end_date

        self._context.tenderPeriod = period
    def _initialize_enquiryPeriod(self):
        period = self._context.__class__.enquiryPeriod.model_class()

        start_date = self._now
        end_date = calculate_business_date(self._context.auctionPeriod.startDate,
                                           -timedelta(days=1),
                                           self._context,
                                           specific_hour=20)

        period.startDate = start_date
        period.endDate = end_date

        self._context.enquiryPeriod = period
Ejemplo n.º 21
0
    def create_auction(self, request):
        self._validate(request, self.create_validation)

        auction = request.validated['auction']

        for i in request.validated['json_data'].get('documents', []):
            document = type(auction).documents.model_class(i)
            document.__parent__ = auction
            auction.documents.append(document)

        if not auction.enquiryPeriod:
            auction.enquiryPeriod = type(auction).enquiryPeriod.model_class()
        if not auction.tenderPeriod:
            auction.tenderPeriod = type(auction).tenderPeriod.model_class()
        now = get_now()
        start_date = TZ.localize(
            auction.auctionPeriod.startDate.replace(tzinfo=None))
        auction.auctionPeriod.startDate = None
        auction.auctionPeriod.endDate = None
        auction.tenderPeriod.startDate = auction.enquiryPeriod.startDate = now
        pause_between_periods = start_date - (start_date.replace(
            hour=20, minute=0, second=0, microsecond=0) - timedelta(days=1))
        auction.enquiryPeriod.endDate = calculate_business_date(
            start_date, -pause_between_periods, auction).astimezone(TZ)
        time_before_tendering_end = (
            start_date.replace(hour=9, minute=30, second=0, microsecond=0) +
            DUTCH_PERIOD) - auction.enquiryPeriod.endDate
        auction.tenderPeriod.endDate = calculate_business_date(
            auction.enquiryPeriod.endDate, time_before_tendering_end, auction)
        if SANDBOX_MODE and auction.submissionMethodDetails and 'quick' in auction.submissionMethodDetails:
            auction.tenderPeriod.endDate = (auction.enquiryPeriod.endDate +
                                            QUICK_DUTCH_PERIOD).astimezone(TZ)
        auction.auctionPeriod.startDate = None
        auction.auctionPeriod.endDate = None
        auction.date = now
        if not auction.auctionParameters:
            auction.auctionParameters = type(
                auction).auctionParameters.model_class()
    def _initialize_tenderPeriod(self):
        period = self._context.__class__.tenderPeriod.model_class()

        start_date = self._context.rectificationPeriod.endDate
        end_date = calculate_business_date(self._context.auctionPeriod.startDate,
                                           -timedelta(days=4),
                                           self._context,
                                           specific_hour=20,
                                           working_days=True)

        period.startDate = start_date
        period.endDate = end_date

        self._context.tenderPeriod = period
Ejemplo n.º 23
0
    def test_set_dueDate_financing(self):
        self.prepare_mocked_contract()
        manager = CeasefireMilestoneManager(Mock())

        milestone_mock = Mock()
        milestone_mock.type_ = 'financing'

        self.contract.dateSigned = datetime.now()
        target_dueDate = calculate_business_date(
            self.contract.dateSigned,
            MILESTONE_FINANCING_DUEDATE_OFFSET,
            context=None,
            working_days=True,
            specific_hour=18)
        manager.set_dueDate(milestone_mock, self.contract)
        self.assertEqual(milestone_mock.dueDate, target_dueDate,
                         'dueDate has been calculated incorrectly')
Ejemplo n.º 24
0
def check_signing_period(self):
    response = self.app.get('/auctions/{}'.format(self.auction_id), )
    self.assertEqual(response.status, '200 OK')
    self.assertEqual(response.content_type, 'application/json')
    auction = response.json['data']
    self.assertEqual('active.qualification', auction["status"])
    first_award = auction['awards'][0]

    signing_period_start = parse_date(
        first_award['signingPeriod']['startDate']).astimezone(TZ)
    signing_period_end = parse_date(
        first_award['signingPeriod']['endDate']).astimezone(TZ)
    expected_end = calculate_business_date(start=signing_period_start,
                                           context=auction,
                                           **SIGNING_PERIOD_PARAMS)

    self.assertEqual(signing_period_end, expected_end)
 def initialize(self):
     if not self.enquiryPeriod:
         self.enquiryPeriod = type(self).enquiryPeriod.model_class()
     if not self.tenderPeriod:
         self.tenderPeriod = type(self).tenderPeriod.model_class()
     now = get_now()
     start_date = TZ.localize(self.auctionPeriod.startDate.replace(tzinfo=None))
     self.auctionPeriod.startDate = None
     self.auctionPeriod.endDate = None
     self.tenderPeriod.startDate = self.enquiryPeriod.startDate = now
     pause_between_periods = start_date - (start_date.replace(hour=20, minute=0, second=0, microsecond=0) - timedelta(days=1))
     end_date = calculate_business_date(start_date, -pause_between_periods, self)
     self.enquiryPeriod.endDate = end_date
     self.tenderPeriod.endDate = self.enquiryPeriod.endDate
     self.date = now
     if self.lots:
         for lot in self.lots:
             lot.date = now
     self.documents.append(type(self).documents.model_class(DGF_PLATFORM_LEGAL_DETAILS))
Ejemplo n.º 26
0
    def test_set_dueDate_financing_with_accelerator(self):
        self.prepare_mocked_contract()
        manager = CeasefireMilestoneManager(Mock())

        milestone_mock = Mock()
        milestone_mock.type_ = 'financing'

        if SANDBOX_MODE:
            self.contract.sandbox_parameters = 'quick, accelerator=1440'
        self.contract.dateSigned = datetime.now()

        target_dueDate = calculate_business_date(
            self.contract.dateSigned,
            MILESTONE_FINANCING_DUEDATE_OFFSET,
            context=self.contract,
            working_days=True,
            specific_hour=18)
        manager.set_dueDate(milestone_mock, self.contract)
        self.assertEqual(milestone_mock.dueDate, target_dueDate,
                         'dueDate has been calculated incorrectly')
    def generate_rectificationPeriod(self):
        """Generate rectificationPeriod only when it not defined"""
        # avoid period generation if
        if getattr(self, 'tenderPeriod') is None:
            return
        if (
            # it's already generated
            (
                getattr(self, 'rectificationPeriod', False)
                # and not just present, but actually holds some real value
                and self.rectificationPeriod.startDate is not None
            )
        ):
            return self.rectificationPeriod.serialize()
        start = self.tenderPeriod.startDate
        end = calculate_business_date(start, RECTIFICATION_PERIOD_DURATION, self, working_days=True)

        period = RectificationPeriod()
        period.startDate = start
        period.endDate = end

        return period.serialize()
Ejemplo n.º 28
0
    def test_set_dueDate_approval(self):
        self.prepare_mocked_contract()
        manager = CeasefireMilestoneManager(Mock())

        financing_milestone_mock = Mock()
        financing_milestone_mock.type_ = 'financing'
        financing_milestone_mock.get.return_value = 'financing'
        financing_milestone_mock.dateMet = datetime.now()
        approval_milestone_mock = Mock()
        approval_milestone_mock.type_ = 'approval'
        self.contract.milestones = (financing_milestone_mock,
                                    approval_milestone_mock)

        self.contract.dateSigned = datetime.now()
        target_dueDate = calculate_business_date(
            financing_milestone_mock.dateMet,
            MILESTONE_APPROVAL_DUEDATE_OFFSET,
            context=None,
            working_days=True,
            specific_hour=18)
        manager.set_dueDate(approval_milestone_mock, self.contract)
        self.assertEqual(approval_milestone_mock.dueDate, target_dueDate,
                         'dueDate has been calculated incorrectly')
    def set_status(self, status, extra=None):
        data = {'status': status}
        if status == 'active.tendering':
            data.update({
                "enquiryPeriod": {
                    "startDate": now.isoformat(),
                    "endDate": (now + timedelta(days=1)).isoformat()
                },
                "tenderPeriod": {
                    "startDate":
                    now.isoformat(),
                    "endDate":
                    calculate_business_date(now,
                                            timedelta(days=8),
                                            None,
                                            working_days=True).isoformat()
                }
            })
        elif status == 'active.auction':
            data.update({
                "enquiryPeriod": {
                    "startDate": (now - timedelta(days=20)).isoformat(),
                    "endDate": now.isoformat()
                },
                "tenderPeriod": {
                    "startDate": (now - timedelta(days=20)).isoformat(),
                    "endDate":
                    calculate_business_date(now - timedelta(days=20),
                                            timedelta(days=8),
                                            None,
                                            working_days=True).isoformat()
                },
                "auctionPeriod": {
                    "startDate": now.isoformat()
                }
            })
            if self.initial_lots:
                data.update({
                    'lots': [{
                        "auctionPeriod": {
                            "startDate": now.isoformat()
                        }
                    } for i in self.initial_lots]
                })
        elif status == 'active.qualification':
            data.update({
                "enquiryPeriod": {
                    "startDate": (now - timedelta(days=20)).isoformat(),
                    "endDate": (now - timedelta(days=13)).isoformat()
                },
                "tenderPeriod": {
                    "startDate": (now - timedelta(days=20)).isoformat(),
                    "endDate":
                    calculate_business_date(now - timedelta(days=20),
                                            timedelta(days=8),
                                            None,
                                            working_days=True).isoformat()
                },
                "auctionPeriod": {
                    "startDate": (now - timedelta(days=2)).isoformat(),
                    "endDate": now.isoformat()
                },
                "awardPeriod": {
                    "startDate": now.isoformat()
                }
            })
            if self.initial_lots:
                data.update({
                    'lots': [{
                        "auctionPeriod": {
                            "startDate": (now - timedelta(days=1)).isoformat(),
                            "endDate": now.isoformat()
                        }
                    } for i in self.initial_lots]
                })
        elif status == 'active.awarded':
            data.update({
                "enquiryPeriod": {
                    "startDate": (now - timedelta(days=20)).isoformat(),
                    "endDate": (now - timedelta(days=13)).isoformat()
                },
                "tenderPeriod": {
                    "startDate":
                    calculate_business_date(now,
                                            -timedelta(days=20),
                                            None,
                                            working_days=True).isoformat(),
                    "endDate":
                    calculate_business_date(calculate_business_date(
                        now, -timedelta(days=20), None, working_days=True),
                                            timedelta(days=8),
                                            None,
                                            working_days=True).isoformat()
                },
                "auctionPeriod": {
                    "startDate":
                    calculate_business_date(calculate_business_date(
                        now, -timedelta(days=20), None, working_days=True),
                                            timedelta(days=8),
                                            None,
                                            working_days=True).isoformat(),
                    "endDate":
                    calculate_business_date(calculate_business_date(
                        now, -timedelta(days=20), None, working_days=True),
                                            timedelta(days=10),
                                            None,
                                            working_days=True).isoformat()
                },
                "awardPeriod": {
                    "startDate":
                    calculate_business_date(calculate_business_date(
                        now, -timedelta(days=20), None, working_days=True),
                                            timedelta(days=10),
                                            None,
                                            working_days=True).isoformat(),
                    "endDate":
                    now.isoformat()
                }
            })
            if self.initial_lots:
                data.update({
                    'lots': [{
                        "auctionPeriod": {
                            "startDate": (now - timedelta(days=1)).isoformat(),
                            "endDate": now.isoformat()
                        }
                    } for i in self.initial_lots]
                })
        elif status == 'complete':
            data.update({
                "enquiryPeriod": {
                    "startDate": (now - timedelta(days=20)).isoformat(),
                    "endDate": (now - timedelta(days=13)).isoformat()
                },
                "tenderPeriod": {
                    "startDate": (now - timedelta(days=20)).isoformat(),
                    "endDate":
                    calculate_business_date(now - timedelta(days=20),
                                            timedelta(days=8),
                                            None,
                                            working_days=True).isoformat()
                },
                "auctionPeriod": {
                    "startDate":
                    calculate_business_date(now - timedelta(days=20),
                                            timedelta(days=11),
                                            None,
                                            working_days=True).isoformat(),
                    "endDate":
                    calculate_business_date(now - timedelta(days=20),
                                            timedelta(days=10),
                                            None,
                                            working_days=True).isoformat(),
                },
                "awardPeriod": {
                    "startDate":
                    calculate_business_date(now - timedelta(days=20),
                                            timedelta(days=10),
                                            None,
                                            working_days=True).isoformat(),
                    "endDate":
                    calculate_business_date(now - timedelta(days=20),
                                            timedelta(days=10),
                                            None,
                                            working_days=True).isoformat()
                }
            })

            if self.initial_lots:
                data.update({
                    'lots': [{
                        "auctionPeriod": {
                            "startDate":
                            (now - timedelta(days=11)).isoformat(),
                            "endDate": (now - timedelta(days=10)).isoformat()
                        }
                    } for i in self.initial_lots]
                })
        if extra:
            data.update(extra)
        auction = self.db.get(self.auction_id)
        auction.update(apply_data_patch(auction, data))
        self.db.save(auction)
        authorization = self.app.authorization
        self.app.authorization = ('Basic', ('chronograph', ''))
        #response = self.app.patch_json('/auctions/{}'.format(self.auction_id), {'data': {'id': self.auction_id}})
        response = self.app.get('/auctions/{}'.format(self.auction_id))
        self.app.authorization = authorization
        self.assertEqual(response.status, '200 OK')
        self.assertEqual(response.content_type, 'application/json')
        return response
MOCK_CONFIG = connection_mock_config(PARTIAL_MOCK_CONFIG,
                                     base=BASE_MOCK_CONFIG,
                                     connector=('plugins', 'api', 'plugins',
                                                'auctions.core', 'plugins'))

TEST_ROUTE_PREFIX = '/api/{}'.format(
    MOCK_CONFIG['config']['main']['api_version'])

MOCK_CONFIG = connection_mock_config(MOCK_CONFIG_PARTIAL_AUCTION,
                                     base=MOCK_CONFIG,
                                     connector=('config', 'auction'))

test_appraisal_auction_data = deepcopy(test_auction_data)
test_appraisal_auction_data['auctionPeriod'] = {
    'startDate':
    calculate_business_date(now, timedelta(days=8), None,
                            working_days=True).isoformat()
}
test_appraisal_auction_data['lotIdentifier'] = 'Q24421K222'
for item in test_appraisal_auction_data['items']:
    item['classification']['scheme'] = 'CPV'
    item['classification']['id'] = '51413000-0'

test_appraisal_auction_data['auctionParameters'] = {
    'type': 'insider',
    'dutchSteps': 88
}
test_appraisal_auction_data.update({
    'description': 'description of appraisal auction',
    'registrationFee': {
        'amount': 700.87,
        'currency': 'UAH'