# 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,
)
    procuring_entity_kinds = ['general', 'special', 'defense']
    block_tender_complaint_status = ['claim', 'pending', 'accepted', 'satisfied', 'stopping']
    block_complaint_status = ['pending', 'accepted', 'satisfied', 'stopping']

    def __acl__(self):
        acl = [
            (Allow, '{}_{}'.format(i.owner, i.owner_token), 'create_award_complaint')
            for i in self.bids
            if i.status == 'active'
        ]
        acl.extend([
            (Allow, '{}_{}'.format(self.owner, self.owner_token), 'edit_tender'),
            (Allow, '{}_{}'.format(self.owner, self.owner_token), 'upload_tender_documents'),
            (Allow, '{}_{}'.format(self.owner, self.owner_token), 'edit_complaint'),
        ])
        return acl

    def validate_tenderPeriod(self, data, period):
        # if data['_rev'] is None when tender was created just now
        if not data['_rev'] and calculate_business_date(get_now(), -timedelta(minutes=10)) >= period.startDate:
            raise ValidationError(u"tenderPeriod.startDate should be in greater than current date")
        if period and calculate_business_date(period.startDate, TENDER_PERIOD, data) > period.endDate:
            raise ValidationError(u"tenderPeriod should be greater than 15 days")

    @serializable(serialized_name="enquiryPeriod", type=ModelType(EnquiryPeriod))
    def tender_enquiryPeriod(self):
        endDate = calculate_business_date(self.tenderPeriod.endDate, -ENQUIRY_PERIOD_TIME, self)
        return EnquiryPeriod(dict(startDate=self.tenderPeriod.startDate,
                                  endDate=endDate,
                                  invalidationDate=self.enquiryPeriod and self.enquiryPeriod.invalidationDate,

# 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,
)

    procuring_entity_kinds = ['general', 'special', 'defense']
    block_tender_complaint_status = ['claim', 'pending', 'accepted', 'satisfied', 'stopping']
    block_complaint_status = ['pending', 'accepted', 'satisfied', 'stopping']

    def __acl__(self):
        acl = [
            (Allow, '{}_{}'.format(i.owner, i.owner_token), 'create_award_complaint')
            for i in self.bids
            if i.status == 'active'
        ]
        acl.extend([
            (Allow, '{}_{}'.format(self.owner, self.owner_token), 'edit_tender'),
            (Allow, '{}_{}'.format(self.owner, self.owner_token), 'upload_tender_documents'),
            (Allow, '{}_{}'.format(self.owner, self.owner_token), 'edit_complaint'),
        ])
        return acl

    def validate_tenderPeriod(self, data, period):
        # if data['_rev'] is None when tender was created just now
        if not data['_rev'] and calculate_business_date(get_now(), -timedelta(minutes=10)) >= period.startDate:
            raise ValidationError(u"tenderPeriod.startDate should be in greater than current date")
        if period and calculate_business_date(period.startDate, TENDER_PERIOD, data) > period.endDate:
            raise ValidationError(u"tenderPeriod should be greater than 15 days")

    @serializable(serialized_name="enquiryPeriod", type=ModelType(EnquiryPeriod))
    def tender_enquiryPeriod(self):
        endDate = calculate_business_date(self.tenderPeriod.endDate, -ENQUIRY_PERIOD_TIME, self)
        return EnquiryPeriod(dict(startDate=self.tenderPeriod.startDate,
                                  endDate=endDate,
                                  invalidationDate=self.enquiryPeriod and self.enquiryPeriod.invalidationDate,

                                  clarificationsUntil=calculate_business_date(endDate, ENQUIRY_STAND_STILL_TIME, self, True)))