Skip to content

Commit

Permalink
Merge branch 'a168770784473030_block_cancellation'
Browse files Browse the repository at this point in the history
  • Loading branch information
kroman0 committed Aug 23, 2016
2 parents 1c38af6 + 00c6af0 commit a997836
Show file tree
Hide file tree
Showing 2 changed files with 116 additions and 1 deletion.
99 changes: 98 additions & 1 deletion openprocurement/tender/openua/tests/cancellation.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
import unittest

from openprocurement.api.tests.base import test_lots
from openprocurement.tender.openua.tests.base import BaseTenderUAContentWebTest
from openprocurement.tender.openua.tests.base import BaseTenderUAContentWebTest, test_bids


class TenderCancellationResourceTest(BaseTenderUAContentWebTest):
Expand Down Expand Up @@ -419,6 +419,103 @@ def test_patch_tender_cancellation(self):
self.assertEqual(response.json['data']["reason"], "cancellation reason")


class TenderAwardsCancellationResourceTest(BaseTenderUAContentWebTest):
initial_lots = 2 * test_lots
initial_status = 'active.auction'
initial_bids = test_bids

def test_cancellation_active_award(self):
self.app.authorization = ('Basic', ('auction', ''))
response = self.app.get('/tenders/{}/auction'.format(self.tender_id))
auction_bids_data = response.json['data']['bids']
for i in self.initial_lots:
response = self.app.post_json('/tenders/{}/auction/{}'.format(self.tender_id, i['id']),
{'data': {'bids': auction_bids_data}})

self.app.authorization = ('Basic', ('token', ''))
response = self.app.get('/tenders/{}/awards'.format(self.tender_id))
award_id = [i['id'] for i in response.json['data'] if i['status'] == 'pending' and i['lotID'] == self.initial_lots[0]['id']][0]
response = self.app.patch_json('/tenders/{}/awards/{}?acc_token={}'.format(self.tender_id, award_id, self.tender_token),
{"data": {"status": "active", "qualified": True, "eligible": True}})

response = self.app.post_json('/tenders/{}/cancellations?acc_token={}'.format(self.tender_id, self.tender_token), {'data': {
'reason': 'cancellation reason',
'status': 'active',
"cancellationOf": "lot",
"relatedLot": self.initial_lots[0]['id']
}})
self.assertEqual(response.status, '201 Created')
self.assertEqual(response.content_type, 'application/json')
cancellation = response.json['data']
self.assertEqual(cancellation['reason'], 'cancellation reason')
self.assertEqual(cancellation['status'], 'active')
self.assertIn('id', cancellation)
self.assertIn(cancellation['id'], response.headers['Location'])

response = self.app.post_json('/tenders/{}/cancellations?acc_token={}'.format(self.tender_id, self.tender_token), {'data': {
'reason': 'cancellation reason',
'status': 'active',
}})
self.assertEqual(response.status, '201 Created')
self.assertEqual(response.content_type, 'application/json')
cancellation = response.json['data']
self.assertEqual(cancellation['reason'], 'cancellation reason')
self.assertEqual(cancellation['status'], 'active')
self.assertIn('id', cancellation)
self.assertIn(cancellation['id'], response.headers['Location'])

def test_cancellation_unsuccessful_award(self):
self.app.authorization = ('Basic', ('auction', ''))
response = self.app.get('/tenders/{}/auction'.format(self.tender_id))
auction_bids_data = response.json['data']['bids']
for i in self.initial_lots:
response = self.app.post_json('/tenders/{}/auction/{}'.format(self.tender_id, i['id']),
{'data': {'bids': auction_bids_data}})

self.app.authorization = ('Basic', ('token', ''))
response = self.app.get('/tenders/{}/awards'.format(self.tender_id))
award_id = [i['id'] for i in response.json['data'] if i['status'] == 'pending' and i['lotID'] == self.initial_lots[0]['id']][0]
response = self.app.patch_json('/tenders/{}/awards/{}?acc_token={}'.format(self.tender_id, award_id, self.tender_token),
{"data": {"status": "unsuccessful"}})

response = self.app.get('/tenders/{}/awards'.format(self.tender_id))
award_id = [i['id'] for i in response.json['data'] if i['status'] == 'pending' and i['lotID'] == self.initial_lots[0]['id']][0]
response = self.app.patch_json('/tenders/{}/awards/{}?acc_token={}'.format(self.tender_id, award_id, self.tender_token),
{"data": {"status": "unsuccessful"}})

response = self.app.post_json('/tenders/{}/cancellations?acc_token={}'.format(self.tender_id, self.tender_token), {'data': {
'reason': 'cancellation reason',
'status': 'active',
"cancellationOf": "lot",
"relatedLot": self.initial_lots[0]['id']
}}, status=403)
self.assertEqual(response.status, '403 Forbidden')
self.assertEqual(response.content_type, 'application/json')
self.assertEqual(response.json['errors'][0]["description"], "Can't add cancellation if all awards is unsuccessful")

response = self.app.post_json('/tenders/{}/cancellations?acc_token={}'.format(self.tender_id, self.tender_token), {'data': {
'reason': 'cancellation reason',
'status': 'active',
}}, status=403)
self.assertEqual(response.status, '403 Forbidden')
self.assertEqual(response.content_type, 'application/json')
self.assertEqual(response.json['errors'][0]["description"], "Can't add cancellation if all awards is unsuccessful")

response = self.app.post_json('/tenders/{}/cancellations?acc_token={}'.format(self.tender_id, self.tender_token), {'data': {
'reason': 'cancellation reason',
'status': 'active',
"cancellationOf": "lot",
"relatedLot": self.initial_lots[1]['id']
}})
self.assertEqual(response.status, '201 Created')
self.assertEqual(response.content_type, 'application/json')
cancellation = response.json['data']
self.assertEqual(cancellation['reason'], 'cancellation reason')
self.assertEqual(cancellation['status'], 'active')
self.assertIn('id', cancellation)
self.assertIn(cancellation['id'], response.headers['Location'])


class TenderCancellationDocumentResourceTest(BaseTenderUAContentWebTest):

def setUp(self):
Expand Down
18 changes: 18 additions & 0 deletions openprocurement/tender/openua/views/cancellation.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,3 +29,21 @@ def cancel_lot(self, cancellation=None):
if i.status == 'active'
]):
add_next_award(self.request)

def validate_cancellation(self, operation):
if not super(TenderUaCancellationResource, self).validate_cancellation(operation):
return
tender = self.request.validated['tender']
cancellation = self.request.validated['cancellation']
if not cancellation.relatedLot and tender.lots:
active_lots = [i.id for i in tender.lots if i.status == 'active']
statuses = [set([i.status for i in tender.awards if i.lotID == lot_id]) for lot_id in active_lots]
block_cancellation = any([not i.difference(set(['unsuccessful', 'cancelled'])) if i else False for i in statuses])
elif cancellation.relatedLot and tender.lots or not cancellation.relatedLot and not tender.lots:
statuses = set([i.status for i in tender.awards if i.lotID == cancellation.relatedLot])
block_cancellation = not statuses.difference(set(['unsuccessful', 'cancelled'])) if statuses else False
if block_cancellation:
self.request.errors.add('body', 'data', 'Can\'t {} cancellation if all awards is unsuccessful'.format(operation))
self.request.errors.status = 403
return
return True

0 comments on commit a997836

Please sign in to comment.