def shouldStartAfter(self): if self.endDate: return tender = get_tender(self) lot = self.__parent__ if (tender.status not in [ "active.tendering", "active.pre-qualification.stand-still", "active.auction" ] or lot.status != "active"): return start_after = None if tender.status == "active.tendering" and tender.tenderPeriod.endDate: start_after = calculate_tender_business_date( tender.tenderPeriod.endDate, TENDERING_AUCTION, tender) elif self.startDate and get_now() > calc_auction_end_time( lot.numberOfBids, self.startDate): start_after = calc_auction_end_time(lot.numberOfBids, self.startDate) elif tender.qualificationPeriod and tender.qualificationPeriod.endDate: decision_dates = [ datetime.combine( complaint.dateDecision.date() + timedelta(days=3), time(0, tzinfo=complaint.dateDecision.tzinfo)) for qualification in tender.qualifications for complaint in qualification.complaints if complaint.dateDecision ] decision_dates.append(tender.qualificationPeriod.endDate) start_after = max(decision_dates) if start_after: return rounding_shouldStartAfter(start_after, tender).isoformat()
def __call__(self, obj): now = get_now() checks = [] configurator = getAdapter(obj, IContentConfigurator) if obj.status == "active.enquiries" and obj.enquiryPeriod and obj.enquiryPeriod.endDate: checks.append(obj.enquiryPeriod.endDate.astimezone( configurator.tz)) elif obj.status == "active.tendering" and obj.tenderPeriod and obj.tenderPeriod.endDate: checks.append(obj.tenderPeriod.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.lots and obj.status in [ "active.qualification", "active.awarded" ]: for lot in obj.lots: if lot["status"] != "active": continue if obj.status.startswith("active"): for award in obj.awards: if award.status == "active" and not any( [i.awardID == award.id for i in obj.contracts]): checks.append(award.date) return min(checks).isoformat() if checks else None
def shouldStartAfter(self): if self.endDate: return tender = self.__parent__ if tender.lots or tender.status not in ['active.tendering', 'active.auction']: return if self.startDate and get_now() > calc_auction_end_time(tender.numberOfBids, self.startDate): start_after = calc_auction_end_time(tender.numberOfBids, self.startDate) else: start_after = tender.tenderPeriod.endDate return rounding_shouldStartAfter(start_after, tender).isoformat()
def shouldStartAfter(self): if self.endDate: return tender = get_tender(self) lot = self.__parent__ if tender.status not in ["active.tendering", "active.auction"] or lot.status != "active": return if tender.status == "active.auction" and lot.numberOfBids < 2: return if self.startDate and get_now() > calc_auction_end_time(lot.numberOfBids, self.startDate): start_after = calc_auction_end_time(tender.numberOfBids, self.startDate) else: start_after = tender.tenderPeriod.endDate return rounding_shouldStartAfter(start_after, tender).isoformat()
def shouldStartAfter(self): if self.endDate: return tender = get_tender(self) lot = self.__parent__ if tender.status not in ['active.tendering', 'active.auction'] or lot.status != 'active': return if self.startDate and get_now() > calc_auction_end_time(lot.numberOfBids, self.startDate): start_after = calc_auction_end_time(lot.numberOfBids, self.startDate) else: decision_dates = [ datetime.combine(complaint.dateDecision.date() + timedelta(days=3), time(0, tzinfo=complaint.dateDecision.tzinfo)) for complaint in tender.complaints if complaint.dateDecision ] decision_dates.append(tender.tenderPeriod.endDate) start_after = max(decision_dates) return rounding_shouldStartAfter(start_after, tender).isoformat()
def next_check(self): now = get_now() checks = [] if self.status == "active.enquiries" and self.enquiryPeriod and self.enquiryPeriod.endDate: checks.append(self.enquiryPeriod.endDate.astimezone(TZ)) elif 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)) else: auction_end_time = calc_auction_end_time( self.numberOfBids, self.auctionPeriod.startDate).astimezone(TZ) if now < auction_end_time: checks.append(auction_end_time) 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)) else: auction_end_time = calc_auction_end_time( lot.numberOfBids, lot.auctionPeriod.startDate).astimezone(TZ) if now < auction_end_time: checks.append(auction_end_time) elif self.lots and self.status in [ "active.qualification", "active.awarded" ]: for lot in self.lots: if lot["status"] != "active": continue 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
def shouldStartAfter(self): if self.endDate: return tender = get_tender(self) lot = self.__parent__ if tender.status not in ['active.tendering', 'active.auction'] or lot.status != 'active': return if tender.status == 'active.auction' and lot.numberOfBids < 2: return if self.startDate and get_now() > calc_auction_end_time(lot.numberOfBids, self.startDate): return calc_auction_end_time(lot.numberOfBids, self.startDate).isoformat() else: decision_dates = [ datetime.combine(complaint.dateDecision.date() + timedelta(days=3), time(0, tzinfo=complaint.dateDecision.tzinfo)) for complaint in tender.complaints if complaint.dateDecision ] decision_dates.append(tender.tenderPeriod.endDate) return max(decision_dates).isoformat()
def shouldStartAfter(self): if self.endDate: return tender = self.__parent__ if tender.lots or tender.status not in ["active.tendering", "active.auction"]: return if self.startDate and get_now() > calc_auction_end_time(tender.numberOfBids, self.startDate): start_after = calc_auction_end_time(tender.numberOfBids, self.startDate) else: decision_dates = [ datetime.combine( complaint.dateDecision.date() + timedelta(days=3), time(0, tzinfo=complaint.dateDecision.tzinfo) ) for complaint in tender.complaints if complaint.dateDecision ] decision_dates.append(tender.tenderPeriod.endDate) start_after = max(decision_dates) return normalize_should_start_after(start_after, tender).isoformat()
def shouldStartAfter(self): if self.endDate: return tender = self.__parent__ if tender.lots or tender.status not in [ 'active.tendering', 'active.pre-qualification.stand-still', 'active.auction' ]: return start_after = None if tender.status == 'active.tendering' and tender.tenderPeriod.endDate: start_after = calculate_business_date(tender.tenderPeriod.endDate, TENDERING_AUCTION, tender) elif self.startDate and get_now() > calc_auction_end_time( tender.numberOfBids, self.startDate): start_after = calc_auction_end_time(tender.numberOfBids, self.startDate) elif tender.qualificationPeriod and tender.qualificationPeriod.endDate: start_after = tender.qualificationPeriod.endDate if start_after: return rounding_shouldStartAfter(start_after, tender).isoformat()
def shouldStartAfter(self): if self.endDate: return tender = get_tender(self) lot = self.__parent__ if tender.status not in ["active.tendering", "active.auction" ] or lot.status != "active": return if tender.status == "active.auction" and lot.numberOfBids < 2: return if self.startDate and get_now() > calc_auction_end_time( lot.numberOfBids, self.startDate): return calc_auction_end_time(lot.numberOfBids, self.startDate).isoformat() else: decision_dates = [ datetime.combine( complaint.dateDecision.date() + timedelta(days=3), time(0, tzinfo=complaint.dateDecision.tzinfo)) for complaint in tender.complaints if complaint.dateDecision ] decision_dates.append(tender.tenderPeriod.endDate) return max(decision_dates).isoformat()
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 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
def next_check(self): now = get_now() checks = [] if self.status == 'active.enquiries' and self.tenderPeriod.startDate: checks.append(self.tenderPeriod.startDate.astimezone(TZ)) elif self.status == 'active.enquiries' and self.enquiryPeriod.endDate: checks.append(self.enquiryPeriod.endDate.astimezone(TZ)) elif self.status == 'active.tendering' 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)) 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'): from openprocurement.tender.core.utils import calculate_business_date for complaint in self.complaints: if complaint.status == 'answered' and complaint.dateAnswered: checks.append( calculate_business_date(complaint.dateAnswered, COMPLAINT_STAND_STILL_TIME, self)) elif complaint.status == 'pending': checks.append(self.dateModified) 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) for complaint in award.complaints: if complaint.status == 'answered' and complaint.dateAnswered: checks.append( calculate_business_date( complaint.dateAnswered, COMPLAINT_STAND_STILL_TIME, self)) elif complaint.status == 'pending': checks.append(self.dateModified) return min(checks).isoformat() if checks else None
def next_check(self): now = get_now() checks = [] if self.status == "active.enquiries" and self.tenderPeriod.startDate: checks.append(self.tenderPeriod.startDate.astimezone(TZ)) elif self.status == "active.enquiries" and self.enquiryPeriod.endDate: checks.append(self.enquiryPeriod.endDate.astimezone(TZ)) elif self.status == "active.tendering" 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)) else: auction_end_time = calc_auction_end_time( self.numberOfBids, self.auctionPeriod.startDate).astimezone(TZ) if now < auction_end_time: checks.append(auction_end_time) 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)) else: auction_end_time = calc_auction_end_time( lot.numberOfBids, lot.auctionPeriod.startDate).astimezone(TZ) if now < auction_end_time: checks.append(auction_end_time) 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 and 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 and 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 complaint in self.complaints: if complaint.status == "answered" and complaint.dateAnswered: check = calculate_tender_date(complaint.dateAnswered, COMPLAINT_STAND_STILL_TIME, self) checks.append(check) elif complaint.status == "pending": checks.append(self.dateModified) 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) for complaint in award.complaints: if complaint.status == "answered" and complaint.dateAnswered: check = calculate_tender_date( complaint.dateAnswered, COMPLAINT_STAND_STILL_TIME, self) checks.append(check) elif complaint.status == "pending": checks.append(self.dateModified) return min(checks).isoformat() if checks else None
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