Skip to content

Commit

Permalink
Merge pull request #14 from gorserg/control_excess_30_percent
Browse files Browse the repository at this point in the history
Control excess 30 percent
  • Loading branch information
kroman0 committed Jul 15, 2016
2 parents 622d5c7 + 3c5f0dc commit 7de0355
Show file tree
Hide file tree
Showing 4 changed files with 70 additions and 18 deletions.
10 changes: 10 additions & 0 deletions openprocurement/tender/competitivedialogue/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
schematics_embedded_role, ListType, BooleanType
)
from schematics.transforms import whitelist, blacklist
from openprocurement.tender.competitivedialogue.utils import validate_features_custom_weight

# constants for procurementMethodtype
CD_UA_TYPE = "competitiveDialogueUA"
Expand All @@ -34,6 +35,8 @@

STAGE2_STATUS = 'draft.stage2'

FEATURES_MAX_SUM = 1

edit_role_ua = edit_role + blacklist('enquiryPeriod', 'status')
edit_stage2_pending = whitelist('status')
edit_stage2_waiting = whitelist('status', 'stage2TenderID')
Expand Down Expand Up @@ -198,6 +201,9 @@ def __acl__(self):
])
return acl

def validate_features(self, data, features):
validate_features_custom_weight(self, data, features, FEATURES_MAX_SUM)


CompetitiveDialogEU = Tender

Expand Down Expand Up @@ -331,6 +337,8 @@ class Options:
def __acl__(self):
return stage2__acl__(self)

def validate_features(self, data, features):
validate_features_custom_weight(self, data, features, FEATURES_MAX_SUM)

TenderStage2EU = Tender

Expand Down Expand Up @@ -359,5 +367,7 @@ class Options:
def __acl__(self):
return stage2__acl__(self)

def validate_features(self, data, features):
validate_features_custom_weight(self, data, features, FEATURES_MAX_SUM)

TenderStage2UA = Tender
23 changes: 17 additions & 6 deletions openprocurement/tender/competitivedialogue/tests/lot.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
test_tender_data_eu as test_tender_data,
test_lots)
from openprocurement.tender.openeu.tests.base import test_bids
from openprocurement.tender.competitivedialogue.models import FEATURES_MAX_SUM

test_bids.append(test_bids[0].copy()) # Minimal number of bits is 3

Expand Down Expand Up @@ -638,15 +639,19 @@ def test_tender_features_invalid(self):
u'location': u'body',
u'name': u'features'}
])
data['features'][0]["enum"][0]["value"] = 0.1
data['features'][0]["enum"][0]["value"] = 0.3
data['features'].append(data['features'][0].copy())
data['features'][1]["enum"][0]["value"] = 0.2
data['features'][1]["enum"][0]["value"] = 0.3
data['features'].append(data['features'][0].copy())
data['features'][2]["enum"][0]["value"] = 0.3
data['features'].append(data['features'][0].copy())
data['features'][3]["enum"][0]["value"] = 0.3
response = self.app.patch_json(request_path, {'data': data}, status=422)
self.assertEqual(response.status, '422 Unprocessable Entity')
self.assertEqual(response.content_type, 'application/json')
self.assertEqual(response.json['status'], 'error')
self.assertEqual(response.json['errors'], [
{u'description': [u'Sum of max value of all features for lot should be less then or equal to 30%'],
{u'description': [u'Sum of max value of all features for lot should be less then or equal to {:.0f}%'.format(FEATURES_MAX_SUM * 100)],
u'location': u'body',
u'name': u'features'}
])
Expand Down Expand Up @@ -2330,15 +2335,21 @@ def test_tender_features_invalid(self):
u'location': u'body',
u'name': u'features'}
])
data['features'][0]["enum"][0]["value"] = 0.1
data['features'][0]["enum"][0]["value"] = 0.3
data['features'].append(data['features'][0].copy())
data['features'][1]["enum"][0]["value"] = 0.3
data['features'].append(data['features'][0].copy())
data['features'][2]["enum"][0]["value"] = 0.3
data['features'].append(data['features'][0].copy())
data['features'][1]["enum"][0]["value"] = 0.2
data['features'][3]["enum"][0]["value"] = 0.3
response = self.app.patch_json(request_path, {'data': data}, status=422)
self.assertEqual(response.status, '422 Unprocessable Entity')
self.assertEqual(response.content_type, 'application/json')
self.assertEqual(response.json['status'], 'error')
self.assertEqual(response.json['errors'], [
{u'description': [u'Sum of max value of all features for lot should be less then or equal to 30%'],
{u'description': [
u'Sum of max value of all features for lot should be less then or equal to {:.0f}%'.format(
FEATURES_MAX_SUM * 100)],
u'location': u'body',
u'name': u'features'}
])
Expand Down
39 changes: 28 additions & 11 deletions openprocurement/tender/competitivedialogue/tests/tender.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
BaseCompetitiveDialogEUWebTest,
BaseCompetitiveDialogUAWebTest)
from copy import deepcopy
from openprocurement.tender.competitivedialogue.models import CD_EU_TYPE, CD_UA_TYPE
from openprocurement.tender.competitivedialogue.models import CD_EU_TYPE, CD_UA_TYPE, FEATURES_MAX_SUM

class CompetitiveDialogTest(BaseWebTest):

Expand Down Expand Up @@ -801,14 +801,22 @@ def test_tender_features_invalid(self):
self.assertEqual(response.json['errors'], [
{u'description': [u'Feature code should be uniq for all features'], u'location': u'body', u'name': u'features'}
])

data['features'][1]["code"] = u"OCDS-123454-YEARS"
data['features'][1]["enum"][0]["value"] = 0.2
data['features'][1]["enum"][0]["value"] = 0.3
data['features'].append(data['features'][0].copy())
data['features'][2]["code"] = u"OCDS-123455-YEARS"
data['features'][2]["enum"][0]["value"] = 0.3
data['features'].append(data['features'][0].copy())
data['features'][3]["code"] = u"OCDS-123456-YEARS"
data['features'][3]["enum"][0]["value"] = 0.3
response = self.app.post_json('/tenders', {'data': data}, status=422)
self.assertEqual(response.status, '422 Unprocessable Entity')
self.assertEqual(response.content_type, 'application/json')
self.assertEqual(response.json['status'], 'error')
self.assertEqual(response.json['errors'], [
{u'description': [u'Sum of max value of all features should be less then or equal to 30%'], u'location': u'body', u'name': u'features'}
{u'description': [u'Sum of max value of all features should be less then or equal to {:.0f}%'.format(FEATURES_MAX_SUM * 100)],
u'location': u'body', u'name': u'features'}
])

def test_tender_features(self):
Expand All @@ -833,7 +841,7 @@ def test_tender_features(self):
"title": u"До 1000 Вт"
},
{
"value": 0.1,
"value": 0.3,
"title": u"Більше 1000 Вт"
}
]
Expand All @@ -850,7 +858,7 @@ def test_tender_features(self):
"title": u"До 3 років"
},
{
"value": 0.1,
"value": 0.3,
"title": u"Більше 3 років"
}
]
Expand All @@ -867,7 +875,7 @@ def test_tender_features(self):
"title": u"До 90 днів"
},
{
"value": 0.1,
"value": 0.3,
"title": u"Більше 90 днів"
}
]
Expand Down Expand Up @@ -2081,14 +2089,23 @@ def test_tender_features_invalid(self):
self.assertEqual(response.json['errors'], [
{u'description': [u'Feature code should be uniq for all features'], u'location': u'body', u'name': u'features'}
])

data['features'][1]["code"] = u"OCDS-123454-YEARS"
data['features'][1]["enum"][0]["value"] = 0.2
data['features'][1]["enum"][0]["value"] = 0.3
data['features'].append(data['features'][0].copy())
data['features'][2]["code"] = u"OCDS-123455-YEARS"
data['features'][2]["enum"][0]["value"] = 0.3
data['features'].append(data['features'][0].copy())
data['features'][3]["code"] = u"OCDS-123456-YEARS"
data['features'][3]["enum"][0]["value"] = 0.3
response = self.app.post_json('/tenders', {'data': data}, status=422)
self.assertEqual(response.status, '422 Unprocessable Entity')
self.assertEqual(response.content_type, 'application/json')
self.assertEqual(response.json['status'], 'error')
self.assertEqual(response.json['errors'], [
{u'description': [u'Sum of max value of all features should be less then or equal to 30%'], u'location': u'body', u'name': u'features'}
{u'description': [u'Sum of max value of all features should be less then or equal to {:.0f}%'.format(
FEATURES_MAX_SUM * 100)],
u'location': u'body', u'name': u'features'}
])

def test_tender_features(self):
Expand All @@ -2110,7 +2127,7 @@ def test_tender_features(self):
"title": u"До 1000 Вт"
},
{
"value": 0.1,
"value": 0.2,
"title": u"Більше 1000 Вт"
}
]
Expand All @@ -2127,7 +2144,7 @@ def test_tender_features(self):
"title": u"До 3 років"
},
{
"value": 0.1,
"value": 0.2,
"title": u"Більше 3 років"
}
]
Expand All @@ -2144,7 +2161,7 @@ def test_tender_features(self):
"title": u"До 90 днів"
},
{
"value": 0.1,
"value": 0.2,
"title": u"Більше 90 днів"
}
]
Expand Down
16 changes: 15 additions & 1 deletion openprocurement/tender/competitivedialogue/utils.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
# -*- coding: utf-8 -*-
from logging import getLogger
from schematics.exceptions import ValidationError
from openprocurement.tender.openua.utils import calculate_business_date
from openprocurement.tender.openua.models import TENDERING_EXTRA_PERIOD
from openprocurement.api.models import get_now
Expand All @@ -8,7 +9,7 @@
from openprocurement.tender.openeu.models import PREQUALIFICATION_COMPLAINT_STAND_STILL as COMPLAINT_STAND_STILL
from openprocurement.tender.openua.utils import BLOCK_COMPLAINT_STATUS, check_complaint_status
from openprocurement.tender.openeu.utils import prepare_qualifications

from barbecue import vnmax

LOGGER = getLogger(__name__)
MINIMAL_NUMBER_OF_BITS = 3
Expand Down Expand Up @@ -134,6 +135,19 @@ def check_initial_bids_count(request):
extra=context_unpack(request, {'MESSAGE_ID': 'switched_tender_unsuccessful'}))
tender.status = 'unsuccessful'

def validate_features_custom_weight(self, data, features, max_sum):
if features and data['lots'] and any([
round(vnmax([
i
for i in features
if i.featureOf == 'tenderer' or i.featureOf == 'lot' and i.relatedItem == lot['id'] or i.featureOf == 'item' and i.relatedItem in [j.id for j in data['items'] if j.relatedLot == lot['id']]
]), 15) > max_sum
for lot in data['lots']
]):
raise ValidationError(u"Sum of max value of all features for lot should be less then or equal to {:.0f}%".format(max_sum * 100))
elif features and not data['lots'] and round(vnmax(features), 15) > max_sum:
raise ValidationError(u"Sum of max value of all features should be less then or equal to {:.0f}%".format(max_sum * 100))


def check_status(request):
tender = request.validated['tender']
Expand Down

0 comments on commit 7de0355

Please sign in to comment.