Skip to content

Commit

Permalink
Merge branch 'jcdb2dev43_enquiryPeriod_editing' of https://github.com…
Browse files Browse the repository at this point in the history
…/prozorro-sale/openprocurement.auctions.dgf

* 'jcdb2dev43_enquiryPeriod_editing' of https://github.com/prozorro-sale/openprocurement.auctions.dgf:
  Autogenerated rectificationPeriod without timebased changes
  • Loading branch information
Andrew Leitsius committed Feb 8, 2018
2 parents b65b359 + e74a563 commit e4f2e47
Show file tree
Hide file tree
Showing 6 changed files with 61 additions and 31 deletions.
1 change: 0 additions & 1 deletion openprocurement/auctions/dgf/constants.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,6 @@ def read_json(name):
CLASSIFICATION_PRECISELY_FROM = datetime(2017, 7, 19, tzinfo=TZ)
MINIMAL_EXPOSITION_REQUIRED_FROM = datetime(2017, 11, 17, tzinfo=TZ)
DGF_ADDRESS_REQUIRED_FROM = datetime(2018, 2, 9, tzinfo=TZ)
RECTIFICATION_END_EDITING_AND_VALIDATION_REQUIRED_FROM = datetime(2018, 2, 9, tzinfo=TZ)

#codes
CAVPS_CODES = read_json('cav_ps.json')
Expand Down
24 changes: 7 additions & 17 deletions openprocurement/auctions/dgf/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,7 @@
get_auction, Administrator_role
)


from .utils import calculate_enddate, get_auction_creation_date
from .utils import calculate_enddate, get_auction_creation_date, generate_rectificationPeriod

from .constants import (
AWARD_PAYMENT_TIME, CONTRACT_SIGNING_TIME,
Expand All @@ -42,8 +41,7 @@
CPV_NON_SPECIFIC_LOCATION_UNITS,
CAV_NON_SPECIFIC_LOCATION_UNITS,
DGF_ADDRESS_REQUIRED_FROM,
MINIMAL_PERIOD_FROM_RECTIFICATION_END,
RECTIFICATION_END_EDITING_AND_VALIDATION_REQUIRED_FROM
MINIMAL_PERIOD_FROM_RECTIFICATION_END
)


Expand Down Expand Up @@ -393,19 +391,13 @@ def initialize(self):
self.enquiryPeriod = type(self).enquiryPeriod.model_class()
if not self.tenderPeriod:
self.tenderPeriod = type(self).tenderPeriod.model_class()
if not self.rectificationPeriod:
self.rectificationPeriod = type(self).rectificationPeriod.model_class()
now = get_now()
self.tenderPeriod.startDate = self.enquiryPeriod.startDate = self.rectificationPeriod.startDate = now
self.tenderPeriod.startDate = self.enquiryPeriod.startDate = now
pause_between_periods = self.auctionPeriod.startDate - (self.auctionPeriod.startDate.replace(hour=20, minute=0, second=0, microsecond=0) - timedelta(days=1))
self.tenderPeriod.endDate = self.enquiryPeriod.endDate = calculate_business_date(self.auctionPeriod.startDate, -pause_between_periods, self)
if not self.rectificationPeriod.endDate:
rectificationPeriod_calculated_endDate = calculate_business_date(self.tenderPeriod.endDate, -MINIMAL_PERIOD_FROM_RECTIFICATION_END, self)
if rectificationPeriod_calculated_endDate > now:
self.rectificationPeriod.endDate = rectificationPeriod_calculated_endDate
else:
self.rectificationPeriod.endDate = now
self.rectificationPeriod.invalidationDate = None
if not self.rectificationPeriod:
self.rectificationPeriod = generate_rectificationPeriod(self)
self.rectificationPeriod.startDate = now
self.auctionPeriod.startDate = None
self.auctionPeriod.endDate = None
self.date = now
Expand All @@ -425,11 +417,9 @@ def validate_tenderPeriod(self, data, period):
def validate_rectificationPeriod(self, data, period):
if not (period and period.startDate) or not period.endDate:
return
if get_auction_creation_date(data) < RECTIFICATION_END_EDITING_AND_VALIDATION_REQUIRED_FROM:
return
if period.endDate > calculate_business_date(data['tenderPeriod']['endDate'], -MINIMAL_PERIOD_FROM_RECTIFICATION_END, data):
raise ValidationError(u"rectificationPeriod.endDate should come at least 5 working days earlier than tenderPeriod.endDate")

def validate_value(self, data, value):
if value.currency != u'UAH':
raise ValidationError(u"currency should be only UAH")
Expand Down
33 changes: 28 additions & 5 deletions openprocurement/auctions/dgf/tests/tender.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,7 @@
from openprocurement.api.utils import ROUTE_PREFIX
from openprocurement.api.models import get_now, SANDBOX_MODE, TZ
from openprocurement.auctions.dgf.constants import (
MINIMAL_PERIOD_FROM_RECTIFICATION_END,
RECTIFICATION_END_EDITING_AND_VALIDATION_REQUIRED_FROM,
MINIMAL_PERIOD_FROM_RECTIFICATION_END
)
from openprocurement.auctions.dgf.models import DGFOtherAssets, DGFFinancialAssets, DGF_ID_REQUIRED_FROM, CLASSIFICATION_PRECISELY_FROM, DGF_ADDRESS_REQUIRED_FROM
from openprocurement.auctions.dgf.tests.base import test_auction_maximum_data, test_auction_data, test_financial_auction_data, test_organization, test_financial_organization, BaseWebTest, BaseAuctionWebTest, DEFAULT_ACCELERATION, test_bids, test_financial_bids
Expand Down Expand Up @@ -713,7 +712,6 @@ def test_create_auction_auctionPeriod(self):
self.assertEqual(parse_date(auction['tenderPeriod']['endDate']).date(), parse_date(data['auctionPeriod']['startDate'], TZ).date() - timedelta(days=1))
self.assertEqual(parse_date(auction['tenderPeriod']['endDate']).time(), time(20, 0))

@unittest.skipIf(get_now() < RECTIFICATION_END_EDITING_AND_VALIDATION_REQUIRED_FROM, "rectification.endDate validation required only from: {}".format(RECTIFICATION_END_EDITING_AND_VALIDATION_REQUIRED_FROM))
def test_create_auction_rectificationPeriod_generated(self):
response = self.app.post_json('/auctions', {'data': self.initial_data})
self.assertEqual(response.status, '201 Created')
Expand All @@ -731,7 +729,6 @@ def test_create_auction_rectificationPeriod_generated(self):
else:
self.assertEqual(timedelta_during_periods_ends, (MINIMAL_PERIOD_FROM_RECTIFICATION_END / DEFAULT_ACCELERATION))

@unittest.skipIf(get_now() < RECTIFICATION_END_EDITING_AND_VALIDATION_REQUIRED_FROM, "rectificationPeriod.endDate validation required only from: {}".format(RECTIFICATION_END_EDITING_AND_VALIDATION_REQUIRED_FROM))
def test_create_auction_rectificationPeriod_set(self):
now = get_now()
auction_data = deepcopy(self.initial_data)
Expand Down Expand Up @@ -1328,7 +1325,6 @@ def test_patch_auction(self):
self.assertEqual(response.content_type, 'application/json')
self.assertEqual(response.json['errors'][0]["description"], "Can't update auction in current (complete) status")

@unittest.skipIf(get_now() < RECTIFICATION_END_EDITING_AND_VALIDATION_REQUIRED_FROM, "rectificationPeriod.endDate validation required only from: {}".format(RECTIFICATION_END_EDITING_AND_VALIDATION_REQUIRED_FROM))
def test_patch_auction_rectificationPeriod_invalidationDate(self):

response = self.app.get('/auctions')
Expand All @@ -1351,6 +1347,33 @@ def test_patch_auction_rectificationPeriod_invalidationDate(self):
self.assertEqual(response.content_type, 'application/json')
self.assertIn('invalidationDate', response.json['data']['rectificationPeriod'])

def test_patch_old_auction_rectificationPeriod_invalidationDate(self):

response = self.app.get('/auctions')
self.assertEqual(response.status, '200 OK')
self.assertEqual(len(response.json['data']), 0)

data = deepcopy(self.initial_data)
data['auctionPeriod']['startDate'] = (get_now().date() + timedelta(days=8)).isoformat()
data['guarantee'] = {"amount": 100, "currency": "UAH"}

response = self.app.post_json('/auctions', {'data': data})
self.assertEqual(response.status, '201 Created')
self.assertNotIn('invalidationDate', response.json['data']['rectificationPeriod'])
auction = response.json['data']
owner_token = response.json['access']['token']

db_auction = self.db.get(auction['id'])
del db_auction['rectificationPeriod']
self.db.save(db_auction)

# patch one of main auction field by auction owner

response = self.app.patch_json('/auctions/{}?acc_token={}'.format(auction['id'], owner_token), {"data": {"value": {"amount": 120}}})
self.assertEqual(response.status, '200 OK')
self.assertEqual(response.content_type, 'application/json')
self.assertIn('invalidationDate', response.json['data']['rectificationPeriod'])

def test_dateModified_auction(self):
response = self.app.get('/auctions')
self.assertEqual(response.status, '200 OK')
Expand Down
21 changes: 17 additions & 4 deletions openprocurement/auctions/dgf/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,13 +10,15 @@
)
from openprocurement.auctions.core.utils import (
check_complaint_status,
check_auction_status, remove_draft_bids
check_auction_status,
remove_draft_bids
)

from .constants import (
DOCUMENT_TYPE_URL_ONLY,
DOCUMENT_TYPE_OFFLINE,
NUMBER_OF_BIDS_TO_BE_QUALIFIED
NUMBER_OF_BIDS_TO_BE_QUALIFIED,
MINIMAL_PERIOD_FROM_RECTIFICATION_END
)


Expand Down Expand Up @@ -222,8 +224,19 @@ def remove_invalid_bids(request):
auction.bids = [bid for bid in auction.bids if getattr(bid, "status", "active") != "invalid"]


def invalidate_bids_data(request):
auction = request.validated['auction']
def invalidate_bids_data(auction):
for bid in auction.bids:
setattr(bid, "status", "invalid")
auction.rectificationPeriod.invalidationDate = get_now()


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
6 changes: 4 additions & 2 deletions openprocurement/auctions/dgf/validation.py
Original file line number Diff line number Diff line change
@@ -1,12 +1,14 @@
# -*- coding: utf-8 -*-
from openprocurement.api.utils import error_handler
from openprocurement.api.models import get_now, TZ
from openprocurement.auctions.dgf.utils import generate_rectificationPeriod


def validate_rectification_period_editing(request):
if request.context.status == 'active.tendering' and request.authenticated_role not in ['chronograph', 'Administrator']:
auction = request.validated['auction']
if auction.rectificationPeriod.endDate.astimezone(TZ) < get_now():
request.errors.add('body', 'data', 'Auction can be edited only during the rectification period: from ({}) to ({}).'.format(auction.rectificationPeriod.startDate.isoformat(), auction.rectificationPeriod.endDate.isoformat()))
rectificationPeriod = auction.rectificationPeriod or generate_rectificationPeriod(auction)
if rectificationPeriod.endDate.astimezone(TZ) < get_now():
request.errors.add('body', 'data', 'Auction can be edited only during the rectification period: from ({}) to ({}).'.format(rectificationPeriod.startDate.isoformat(), rectificationPeriod.endDate.isoformat()))
request.errors.status = 403
raise error_handler(request.errors)
7 changes: 5 additions & 2 deletions openprocurement/auctions/dgf/views/other/tender.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,8 @@
)
from openprocurement.auctions.dgf.utils import (
check_status,
invalidate_bids_data
invalidate_bids_data,
generate_rectificationPeriod
)
from openprocurement.auctions.dgf.validation import (
validate_rectification_period_editing,
Expand Down Expand Up @@ -192,7 +193,9 @@ def patch(self):
else:
apply_patch(self.request, save=False, src=self.request.validated['auction_src'])
if auction.status == 'active.tendering' and self.request.authenticated_role == 'auction_owner':
invalidate_bids_data(self.request)
if not auction.rectificationPeriod:
auction.rectificationPeriod = generate_rectificationPeriod(auction)
invalidate_bids_data(auction)
save_auction(self.request)
self.LOGGER.info('Updated auction {}'.format(auction.id),
extra=context_unpack(self.request, {'MESSAGE_ID': 'auction_patch'}))
Expand Down

0 comments on commit e4f2e47

Please sign in to comment.