Skip to content

Commit 75c7168

Browse files
committed
Merge branch 'feature/requirements-validation' into 'quinta'
Drop zope && add validation of criterion.requirementGroup and bid.requirementsResponses See merge request pricequotation/openprocurement.api!16
2 parents 01e254e + c668679 commit 75c7168

File tree

17 files changed

+895
-731
lines changed

17 files changed

+895
-731
lines changed

src/openprocurement/tender/pricequotation/configure.zcml

Lines changed: 0 additions & 56 deletions
This file was deleted.

src/openprocurement/tender/pricequotation/includeme.py

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
PriceQuotationTender
1212
from openprocurement.tender.pricequotation.adapters import\
1313
PQTenderConfigurator
14-
from zope.configuration.xmlconfig import file as ZcmlFile
14+
1515

1616
LOGGER = getLogger("openprocurement.tender.pricequotation")
1717

@@ -26,8 +26,3 @@ def includeme(config):
2626
(IPriceQuotationTender, IRequest),
2727
IContentConfigurator
2828
)
29-
30-
ZcmlFile(
31-
os.path.join(os.path.dirname(os.path.abspath(__file__)), 'configure.zcml'),
32-
package=openprocurement.tender.pricequotation
33-
)

src/openprocurement/tender/pricequotation/models/bid.py

Lines changed: 13 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,8 @@
11
from uuid import uuid4
22

3-
from openprocurement.tender.pricequotation.utils import get_requirement_response_class
43
from pyramid.security import Allow
5-
from schematics.types import MD5Type, StringType, BooleanType, IntType, DecimalType
6-
from schematics.types.compound import ModelType, PolyModelType
4+
from schematics.types import MD5Type, StringType
5+
from schematics.types.compound import ModelType
76
from schematics.transforms import whitelist
87

98
from openprocurement.api.utils import get_now
@@ -19,39 +18,18 @@
1918
from openprocurement.tender.pricequotation.models.document import\
2019
Document
2120
from openprocurement.tender.pricequotation.validation import\
22-
validate_bid_value
23-
24-
25-
class BidOffer(Model):
26-
id = MD5Type(required=True, default=lambda: uuid4().hex)
27-
relatedItem = MD5Type(required=True)
28-
requirementsResponse = StringType(required=True)
21+
validate_bid_value, validate_requirement_responses
2922

3023

3124
class RequirementReference(Model):
3225
id = StringType(required=True)
3326
title = StringType()
3427

3528

36-
class BaseRequirementResponse(Model):
29+
class RequirementResponse(Model):
3730
id = MD5Type(required=True, default=lambda: uuid4().hex)
3831
requirement = ModelType(RequirementReference, required=True)
39-
40-
41-
class RequirementResponseString(BaseRequirementResponse):
42-
value = StringType()
43-
44-
45-
class RequirementResponseInt(BaseRequirementResponse):
46-
value = IntType()
47-
48-
49-
class RequirementResponseNumber(BaseRequirementResponse):
50-
value = DecimalType()
51-
52-
53-
class RequirementResponseBoolean(BaseRequirementResponse):
54-
value = BooleanType()
32+
value = StringType(required=True)
5533

5634

5735
class Bid(Model):
@@ -96,29 +74,10 @@ def __local_roles__(self):
9674
transfer_token = StringType()
9775
owner = StringType()
9876
requirementResponses = ListType(
99-
PolyModelType(
100-
(
101-
BaseRequirementResponse,
102-
RequirementResponseInt,
103-
RequirementResponseNumber,
104-
RequirementResponseString,
105-
RequirementResponseBoolean,
106-
),
107-
claim_function=get_requirement_response_class,
108-
required=True
109-
),
77+
ModelType(RequirementResponse),
11078
required=True,
111-
min_size=1
79+
min_size=1,
11280
)
113-
# TODO:
114-
# offers = ListType(
115-
# ModelType(BidOffer, required=True),
116-
# required=True,
117-
# min_size=1,
118-
# validators=[validate_items_uniq],
119-
# )
120-
121-
__name__ = ""
12281

12382
def import_data(self, raw_data, **kw):
12483
"""
@@ -145,3 +104,9 @@ def validate_value(self, data, value):
145104
parent = data["__parent__"]
146105
if isinstance(parent, Model):
147106
validate_bid_value(parent, value)
107+
108+
def validate_requirementResponses(self, data, value):
109+
criterion = data["__parent__"]['criteria']
110+
validate_requirement_responses(
111+
criterion, value
112+
)
Lines changed: 9 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,24 +1,21 @@
1-
from openprocurement.api.models import ListType, Model
2-
from openprocurement.tender.pricequotation.models.requirement import (RequirementBoolean, RequirementDateTime,
3-
RequirementInteger, RequirementNumber,
4-
RequirementString)
5-
from openprocurement.tender.pricequotation.utils import get_requirement_class
61
from schematics.types import StringType
7-
from schematics.types.compound import ModelType, PolyModelType
2+
from schematics.types.compound import ModelType
3+
4+
from openprocurement.api.models import ListType, Model
5+
from openprocurement.tender.pricequotation.models.requirement import Requirement
6+
from openprocurement.tender.pricequotation.validation import validate_requirement_groups
87

98

109
class RequirementGroup(Model):
1110
id = StringType(required=True)
1211
description = StringType(required=True)
13-
requirements = ListType(PolyModelType((RequirementInteger,
14-
RequirementDateTime,
15-
RequirementString,
16-
RequirementNumber,
17-
RequirementBoolean), claim_function=get_requirement_class), default=list())
12+
requirements = ListType(ModelType(Requirement, required=True), default=list())
1813

1914

2015
class Criterion(Model):
2116
id = StringType(required=True)
2217
title = StringType(required=True)
2318
description = StringType(required=True)
24-
requirementGroups = ListType(ModelType(RequirementGroup), required=True)
19+
requirementGroups = ListType(ModelType(RequirementGroup),
20+
required=True,
21+
validators=[validate_requirement_groups])
Lines changed: 14 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -1,52 +1,32 @@
1-
from openprocurement.api.models import DecimalType, IsoDateTimeType, ListType, Model
2-
from openprocurement.api.models import Unit as BaseUnit
3-
from schematics.types import BaseType, BooleanType, FloatType, IntType, StringType
1+
from schematics.types import BaseType, BooleanType, FloatType, IntType, StringType, BaseType
42
from schematics.types.compound import ModelType
3+
from schematics.exceptions import ValidationError
54

6-
7-
class Period(Model):
8-
startDate = IsoDateTimeType()
9-
endDate = IsoDateTimeType()
10-
durationInDays = IntType()
5+
from openprocurement.api.models import DecimalType, IsoDateTimeType, ListType, Model
6+
from openprocurement.api.models import Unit as BaseUnit
7+
from openprocurement.tender.pricequotation.validation import validate_value_type
118

129

1310
class Unit(BaseUnit):
1411
name = StringType(required=True)
1512

1613

17-
class BaseRequirement(Model):
14+
class Requirement(Model):
1815
id = StringType(required=True)
1916
title = StringType(required=True)
2017
description = StringType()
21-
dataType = StringType(required=True, choices=["string", "date-time", "number", "integer", "boolean"])
22-
pattern = StringType()
23-
period = ModelType(Period)
18+
dataType = StringType(required=True,
19+
choices=["string", "number", "integer", "boolean"])
2420
unit = ModelType(Unit)
25-
26-
27-
class RequirementString(BaseRequirement):
2821
minValue = StringType()
2922
maxValue = StringType()
3023
expectedValue = StringType()
3124

25+
def validate_minValue(self, data, value):
26+
validate_value_type(value, data['dataType'])
3227

33-
class RequirementDateTime(BaseRequirement):
34-
minValue = IsoDateTimeType()
35-
maxValue = IsoDateTimeType()
36-
expectedValue = IsoDateTimeType()
37-
38-
39-
class RequirementNumber(BaseRequirement):
40-
minValue = DecimalType()
41-
maxValue = DecimalType()
42-
expectedValue = DecimalType()
43-
44-
45-
class RequirementInteger(BaseRequirement):
46-
minValue = IntType()
47-
maxValue = IntType()
48-
expectedValue = IntType()
49-
28+
def validate_maxValue(self, data, value):
29+
validate_value_type(value, data['dataType'])
5030

51-
class RequirementBoolean(BaseRequirement):
52-
expectedValue = BooleanType()
31+
def validate_expectedValue(self, data, value):
32+
validate_value_type(value, data['dataType'])

src/openprocurement/tender/pricequotation/tests/award.py

Lines changed: 3 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -76,16 +76,9 @@ class TenderAwardDocumentResourceTest(TenderContentWebTest, TenderAwardDocumentR
7676

7777
def setUp(self):
7878
super(TenderAwardDocumentResourceTest, self).setUp()
79-
# Create award
80-
auth = self.app.authorization
81-
self.app.authorization = ("Basic", ("token", ""))
82-
response = self.app.post_json(
83-
"/tenders/{}/awards".format(self.tender_id),
84-
{"data": {"suppliers": [test_organization], "status": "pending", "bid_id": self.initial_bids[0]["id"]}},
85-
)
86-
award = response.json["data"]
87-
self.award_id = award["id"]
88-
self.app.authorization = auth
79+
response = self.app.get("/tenders/{}/awards".format(self.tender_id))
80+
self.awards_ids = [award["id"] for award in response.json["data"]]
81+
self.award_id = self.awards_ids[0]
8982

9083

9184
class TenderAwardDocumentWithDSResourceTest(TenderAwardDocumentResourceTest):

0 commit comments

Comments
 (0)