# Path: openprocurement/tender/openua/utils.py
# def calculate_normalized_date(dt, tender, ceil=False):
#     if (tender.revisions[0].date if tender.revisions else get_now()) > NORMALIZED_COMPLAINT_PERIOD_FROM and \
#             not (SANDBOX_MODE and tender.procurementMethodDetails):
#         if ceil:
#             return dt.astimezone(TZ).replace(hour=0, minute=0, second=0, microsecond=0) + timedelta(days=1)
#         return dt.astimezone(TZ).replace(hour=0, minute=0, second=0, microsecond=0)
#     return dt
# 
# Path: openprocurement/tender/openua/constants.py
# ENQUIRY_STAND_STILL_TIME = timedelta(days=3)
# 
# COMPLAINT_SUBMIT_TIME = timedelta(days=4)
# 
# TENDER_PERIOD = timedelta(days=15)
# 
# ENQUIRY_PERIOD_TIME = timedelta(days=10)
# 
# AUCTION_PERIOD_TIME = timedelta(days=2)
# 
# PERIOD_END_REQUIRED_FROM = datetime(2016, 7, 16, tzinfo=TZ)


from datetime import time, timedelta, datetime
from iso8601 import parse_date
from zope.interface import implementer
from pyramid.security import Allow
from schematics.exceptions import ValidationError
from schematics.transforms import whitelist, blacklist
from schematics.types import StringType, BooleanType
from schematics.types.compound import ModelType
from schematics.types.serializable import serializable
from openprocurement.api.utils import get_now
from openprocurement.api.models import (
    plain_role, listing_role,
    schematics_default_role, schematics_embedded_role, draft_role,
    Model, PeriodEndRequired as BasePeriodEndRequired,
    ListType, SifterListType, Period, IsoDateTimeType, Address
)
from openprocurement.api.constants import (
    TZ
)
from openprocurement.api.validation import (
    validate_cpv_group, validate_items_uniq
)
from openprocurement.tender.core.models import (
    view_role, create_role, edit_role,
    auction_view_role, auction_post_role, auction_patch_role,
    auction_role, chronograph_role, embedded_lot_role,
    chronograph_view_role, view_bid_role, Administrator_bid_role,
    get_tender, validate_lots_uniq, bids_validation_wrapper, Lot,
    ComplaintModelType, Award as BaseAward, Parameter as BaseParameter,
    Bid as BaseBid, Complaint as BaseComplaint,
    default_lot_role, LotValue as BaseLotValue, Item as BaseItem,
    Contract as BaseContract, Cancellation as BaseCancellation,
    validate_parameters_uniq, ITender,
    PeriodStartEndRequired,
    EnquiryPeriod
    # TenderAuctionPeriod
)
from openprocurement.tender.core.utils import (
    rounding_shouldStartAfter, calc_auction_end_time, calculate_business_date,
    has_unanswered_questions, has_unanswered_complaints
)
from openprocurement.tender.core.validation import (
    validate_LotValue_value,
)
from openprocurement.tender.belowthreshold.models import (
    Tender as BaseTender,
    enquiries_role,
    Administrator_role
)
from openprocurement.tender.openua.utils import (
    calculate_normalized_date
)
from openprocurement.tender.openua.constants import (
    ENQUIRY_STAND_STILL_TIME,
    COMPLAINT_SUBMIT_TIME,
    TENDER_PERIOD,
    ENQUIRY_PERIOD_TIME,
    AUCTION_PERIOD_TIME,
    PERIOD_END_REQUIRED_FROM,
)
            ]):
            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 invalidate_bids_data(self):
        if self.auctionPeriod and self.auctionPeriod.startDate and self.auctionPeriod.shouldStartAfter \

# Path: openprocurement/tender/openua/utils.py
# def calculate_normalized_date(dt, tender, ceil=False):
#     if (tender.revisions[0].date if tender.revisions else get_now()) > NORMALIZED_COMPLAINT_PERIOD_FROM and \
#             not (SANDBOX_MODE and tender.procurementMethodDetails):
#         if ceil:
#             return dt.astimezone(TZ).replace(hour=0, minute=0, second=0, microsecond=0) + timedelta(days=1)
#         return dt.astimezone(TZ).replace(hour=0, minute=0, second=0, microsecond=0)
#     return dt
# 
# Path: openprocurement/tender/openua/constants.py
# ENQUIRY_STAND_STILL_TIME = timedelta(days=3)
# 
# COMPLAINT_SUBMIT_TIME = timedelta(days=4)
# 
# TENDER_PERIOD = timedelta(days=15)
# 
# ENQUIRY_PERIOD_TIME = timedelta(days=10)
# 
# AUCTION_PERIOD_TIME = timedelta(days=2)
# 
# PERIOD_END_REQUIRED_FROM = datetime(2016, 7, 16, tzinfo=TZ)


# Path: openprocurement/tender/openua/models.py
from datetime import time, timedelta, datetime
from iso8601 import parse_date
from zope.interface import implementer
from pyramid.security import Allow
from schematics.exceptions import ValidationError
from schematics.transforms import whitelist, blacklist
from schematics.types import StringType, BooleanType
from schematics.types.compound import ModelType
from schematics.types.serializable import serializable
from openprocurement.api.utils import get_now
from openprocurement.api.models import (
    plain_role, listing_role,
    schematics_default_role, schematics_embedded_role, draft_role,
    Model, PeriodEndRequired as BasePeriodEndRequired,
    ListType, SifterListType, Period, IsoDateTimeType, Address
)
from openprocurement.api.constants import (
    TZ
)
from openprocurement.api.validation import (
    validate_cpv_group, validate_items_uniq
)
from openprocurement.tender.core.models import (
    view_role, create_role, edit_role,
    auction_view_role, auction_post_role, auction_patch_role,
    auction_role, chronograph_role, embedded_lot_role,
    chronograph_view_role, view_bid_role, Administrator_bid_role,
    get_tender, validate_lots_uniq, bids_validation_wrapper, Lot,
    ComplaintModelType, Award as BaseAward, Parameter as BaseParameter,
    Bid as BaseBid, Complaint as BaseComplaint,
    default_lot_role, LotValue as BaseLotValue, Item as BaseItem,
    Contract as BaseContract, Cancellation as BaseCancellation,
    validate_parameters_uniq, ITender,
    PeriodStartEndRequired,
    EnquiryPeriod
    # TenderAuctionPeriod
)
from openprocurement.tender.core.utils import (
    rounding_shouldStartAfter, calc_auction_end_time, calculate_business_date,
    has_unanswered_questions, has_unanswered_complaints
)
from openprocurement.tender.core.validation import (
    validate_LotValue_value,
)
from openprocurement.tender.belowthreshold.models import (
    Tender as BaseTender,
    enquiries_role,
    Administrator_role
)
from openprocurement.tender.openua.utils import (
    calculate_normalized_date
)
from openprocurement.tender.openua.constants import (
    ENQUIRY_STAND_STILL_TIME,
    COMPLAINT_SUBMIT_TIME,
    TENDER_PERIOD,
    ENQUIRY_PERIOD_TIME,
    AUCTION_PERIOD_TIME,
    PERIOD_END_REQUIRED_FROM,
)

            ]):
            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 invalidate_bids_data(self):
        if self.auctionPeriod and self.auctionPeriod.startDate and self.auctionPeriod.shouldStartAfter \

                and self.auctionPeriod.startDate > calculate_business_date(parse_date(self.auctionPeriod.shouldStartAfter), AUCTION_PERIOD_TIME, self, True):