Skip to content

Commit 481e229

Browse files
Merge pull request #151 from VineetBala-AOT/main
Refactor condition creation and enums
2 parents a4bebe0 + 6ccfc0f commit 481e229

File tree

28 files changed

+448
-326
lines changed

28 files changed

+448
-326
lines changed

condition-api/src/condition_api/resources/condition.py

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -152,15 +152,24 @@ def post(project_id, document_id):
152152
query_params = request.args
153153
allow_duplicate_condition = query_params.get(
154154
'allow_duplicate_condition', 'true').lower() == 'true'
155+
check_condition_over_project = query_params.get(
156+
'check_condition_over_project', 'false').lower() == 'true'
155157
created_condition = ConditionService.create_condition(project_id,
156158
document_id,
157159
conditions_data,
158-
allow_duplicate_condition)
160+
allow_duplicate_condition,
161+
check_condition_over_project)
159162
return created_condition, HTTPStatus.OK
160163
except ValidationError as err:
161164
return {"message": str(err)}, HTTPStatus.BAD_REQUEST
162165
except ConditionNumberExistsError as err:
163166
return {"message": str(err)}, HTTPStatus.CONFLICT
167+
except ConditionNumberExistsInProjectError as err:
168+
response = {
169+
"message": str(err),
170+
"is_amendment": err.is_amendment
171+
}
172+
return response, HTTPStatus.PRECONDITION_FAILED
164173

165174

166175
@cors_preflight("GET, OPTIONS, PATCH, DELETE")

condition-api/src/condition_api/services/attribute_key_service.py

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -51,11 +51,12 @@ def get_all_attributes(condition_id, management_plan_id=None):
5151
)
5252
.filter(
5353
~attribute_keys.id.in_(db.session.query(subquery.c.attribute_key_id)),
54-
~attribute_keys.id.in_([AttributeKeys.PARTIES_REQUIRED_TO_BE_SUBMITTED,
55-
# exlucding Parties required to be submitted from attribute_keys
56-
AttributeKeys.DELIVERABLE_NAME,
57-
AttributeKeys.MANAGEMENT_PLAN_ACRONYM,
58-
AttributeKeys.MANAGEMENT_PLAN_NAME]),
54+
~attribute_keys.key_name.in_([
55+
AttributeKeys.PARTIES_REQUIRED_TO_BE_SUBMITTED.value,
56+
AttributeKeys.DELIVERABLE_NAME.value,
57+
AttributeKeys.MANAGEMENT_PLAN_ACRONYM.value,
58+
AttributeKeys.MANAGEMENT_PLAN_NAME.value,
59+
]),
5960
)
6061
.order_by(attribute_keys.sort_order)
6162
.all()

condition-api/src/condition_api/services/condition_attribute_service.py

Lines changed: 21 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -123,7 +123,7 @@ def _upsert_single_attribute(condition_id, attribute_data, management_plan_id=No
123123
if existing_attribute:
124124
existing_attribute.attribute_value = value
125125
else:
126-
if key.id == AttributeKeys.DELIVERABLE_NAME:
126+
if key.key_name == AttributeKeys.DELIVERABLE_NAME.value:
127127
return
128128

129129
attribute = ConditionAttribute(
@@ -135,12 +135,12 @@ def _upsert_single_attribute(condition_id, attribute_data, management_plan_id=No
135135
db.session.add(attribute)
136136
db.session.flush()
137137

138-
if key.id == AttributeKeys.REQUIRES_CONSULTATION and value == 'true':
138+
if key.key_name == AttributeKeys.REQUIRES_CONSULTATION.value and value == 'true':
139139
ConditionAttributeService._handle_requires_consultation(
140140
condition_id, management_plan_id
141141
)
142142

143-
if key.id == AttributeKeys.REQUIRES_IEM_TERMS_OF_ENGAGEMENT and value == 'true':
143+
if key.key_name == AttributeKeys.REQUIRES_IEM_TERMS_OF_ENGAGEMENT.value and value == 'true':
144144
ConditionAttributeService._handle_requires_iem_terms_of_engagement(
145145
condition_id, value, management_plan_id
146146
)
@@ -156,7 +156,7 @@ def _handle_requires_consultation(condition_id, management_plan_id):
156156
:param management_plan_id: If the attribute is for a management plan.
157157
"""
158158
consultation_key = db.session.query(AttributeKey).filter(
159-
AttributeKey.id == AttributeKeys.PARTIES_REQUIRED_TO_BE_CONSULTED
159+
AttributeKey.key_name == AttributeKeys.PARTIES_REQUIRED_TO_BE_CONSULTED.value
160160
).first()
161161

162162
existing_attribute = db.session.query(ConditionAttribute).filter_by(
@@ -184,28 +184,32 @@ def _handle_requires_iem_terms_of_engagement(condition_id, attribute_value, mana
184184
:param attribute_value: Value of the current attribute.
185185
:param management_plan_id: If the attribute is for a management plan.
186186
"""
187-
deliverable_key_id = AttributeKeys.DELIVERABLE_NAME
187+
deliverable_key_name = AttributeKeys.DELIVERABLE_NAME.value
188188
deliverable_value = IEMTermsConfig.DELIVERABLE_VALUE
189189
required_keys = IEMTermsConfig.required_attribute_keys()
190190

191191
if attribute_value != 'true':
192192
# Remove deliverable attribute if present
193-
db.session.query(ConditionAttribute).filter_by(
194-
condition_id=condition_id,
195-
attribute_key_id=deliverable_key_id
196-
).delete()
193+
deliverable_key = db.session.query(AttributeKey).filter(
194+
AttributeKey.key_name == deliverable_key_name
195+
).first()
196+
if deliverable_key:
197+
db.session.query(ConditionAttribute).filter_by(
198+
condition_id=condition_id,
199+
attribute_key_id=deliverable_key.id
200+
).delete()
197201
db.session.commit()
198202
return
199203

200-
keys = db.session.query(AttributeKey).filter(AttributeKey.id.in_(required_keys)).all()
204+
keys = db.session.query(AttributeKey).filter(AttributeKey.key_name.in_(required_keys)).all()
201205
for key in keys:
202206
existing = db.session.query(ConditionAttribute).filter_by(
203207
condition_id=condition_id, attribute_key_id=key.id
204208
).first()
205209

206210
if not existing:
207211
# Check if the current key is DELIVERABLE_NAME
208-
attribute_value = deliverable_value if key.id == deliverable_key_id else None
212+
attribute_value = deliverable_value if key.key_name == deliverable_key_name else None
209213
new_attribute = ConditionAttribute(
210214
condition_id=condition_id,
211215
attribute_key_id=key.id,
@@ -216,7 +220,7 @@ def _handle_requires_iem_terms_of_engagement(condition_id, attribute_value, mana
216220
db.session.flush()
217221
else:
218222
# Update DELIVERABLE_NAME if it already exists
219-
if key.id == deliverable_key_id:
223+
if key.key_name == deliverable_key_name:
220224
current_value = existing.attribute_value or ""
221225
values = current_value.strip('{}').split(',') if current_value else []
222226
values = [v.strip() for v in values if v.strip()]
@@ -239,15 +243,15 @@ def _handle_requires_management_plan(condition_id, management_plan_id):
239243
"""
240244
required_keys = ManagementPlanConfig.required_attribute_keys()
241245

242-
all_attribute_keys = db.session.query(AttributeKey).filter(AttributeKey.id.in_(required_keys)).all()
246+
all_attribute_keys = db.session.query(AttributeKey).filter(AttributeKey.key_name.in_(required_keys)).all()
243247
for key in all_attribute_keys:
244248
existing_attribute = db.session.query(ConditionAttribute).filter_by(
245249
condition_id=condition_id, attribute_key_id=key.id
246250
).first()
247251

248252
if not existing_attribute:
249253
# Check if the current key is MANAGEMENT_PLAN_NAME
250-
attribute_value = '{}' if key.id == AttributeKeys.MANAGEMENT_PLAN_NAME else None
254+
attribute_value = '{}' if key.key_name == AttributeKeys.MANAGEMENT_PLAN_NAME.value else None
251255
new_attribute = ConditionAttribute(
252256
condition_id=condition_id,
253257
attribute_key_id=key.id,
@@ -260,7 +264,7 @@ def _handle_requires_management_plan(condition_id, management_plan_id):
260264
@staticmethod
261265
def _fetch_all_attributes(requires_management_plan, condition_id):
262266
"""Fetch and format all independent and management plan attributes."""
263-
excluded_keys = {AttributeKeys.PARTIES_REQUIRED_TO_BE_SUBMITTED}
267+
excluded_key_names = {AttributeKeys.PARTIES_REQUIRED_TO_BE_SUBMITTED.value}
264268

265269
# Fetch all attributes for this condition, joined with keys, and sort using sort_key
266270
if requires_management_plan:
@@ -274,7 +278,7 @@ def _fetch_all_attributes(requires_management_plan, condition_id):
274278
.filter(
275279
ConditionAttribute.condition_id == condition_id,
276280
ConditionAttribute.management_plan_id == plan.id,
277-
~ConditionAttribute.attribute_key_id.in_([key.value for key in excluded_keys])
281+
~AttributeKey.key_name.in_(excluded_key_names)
278282
)
279283
.order_by(AttributeKey.sort_order)
280284
.all()
@@ -307,7 +311,7 @@ def _fetch_all_attributes(requires_management_plan, condition_id):
307311
.filter(
308312
ConditionAttribute.condition_id == condition_id,
309313
ConditionAttribute.management_plan_id.is_(None),
310-
~ConditionAttribute.attribute_key_id.in_([key.value for key in excluded_keys]),
314+
~AttributeKey.key_name.in_(excluded_key_names),
311315
)
312316
.order_by(AttributeKey.sort_order)
313317
.all()

condition-api/src/condition_api/services/condition_service.py

Lines changed: 43 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -503,7 +503,8 @@ def upsert_subconditions(condition_id, subconditions, parent_id=None):
503503
condition_id, subcond_data["subconditions"], parent_id=subcondition_id)
504504

505505
@staticmethod
506-
def create_condition(project_id, document_id, conditions_data, allow_duplicate_condition=None):
506+
def create_condition(project_id, document_id, conditions_data,
507+
allow_duplicate_condition=None, check_condition_over_project=None):
507508
"""Create a new condition."""
508509
amendment = (
509510
db.session.query(Amendment.document_id)
@@ -548,6 +549,28 @@ def create_condition(project_id, document_id, conditions_data, allow_duplicate_c
548549
db.session.add(condition)
549550
else:
550551
final_document_id = document_id
552+
# Check for duplicate condition number within the same document
553+
condition_number = conditions_data.get("condition_number")
554+
if condition_number:
555+
ConditionService._check_duplicate_condition_number(
556+
condition=Condition(
557+
document_id=final_document_id,
558+
amended_document_id=None
559+
),
560+
condition_id=None,
561+
condition_number=condition_number
562+
)
563+
564+
# Check for condition number conflict across the project
565+
condition_number = conditions_data.get("condition_number")
566+
if check_condition_over_project and condition_number:
567+
temp_condition = Condition(
568+
document_id=final_document_id,
569+
amended_document_id=amended_document_id,
570+
project_id=project_id
571+
)
572+
ConditionService._check_condition_conflict_in_project(
573+
temp_condition, condition_number)
551574

552575
new_condition = Condition(
553576
document_id=final_document_id,
@@ -999,23 +1022,23 @@ def _fetch_condition_attributes_external(
9991022
if not include_condition_attributes:
10001023
return []
10011024

1002-
excluded_keys = {AttributeKeys.PARTIES_REQUIRED_TO_BE_SUBMITTED}
1003-
formatted_keys = {
1004-
AttributeKeys.PARTIES_REQUIRED_TO_BE_CONSULTED,
1005-
AttributeKeys.MILESTONES_RELATED_TO_PLAN_SUBMISSION,
1006-
AttributeKeys.MILESTONES_RELATED_TO_PLAN_IMPLEMENTATION,
1007-
AttributeKeys.MANAGEMENT_PLAN_NAME,
1025+
excluded_key_names = {AttributeKeys.PARTIES_REQUIRED_TO_BE_SUBMITTED.value}
1026+
formatted_key_names = {
1027+
AttributeKeys.PARTIES_REQUIRED_TO_BE_CONSULTED.value,
1028+
AttributeKeys.MILESTONES_RELATED_TO_PLAN_SUBMISSION.value,
1029+
AttributeKeys.MILESTONES_RELATED_TO_PLAN_IMPLEMENTATION.value,
1030+
AttributeKeys.MANAGEMENT_PLAN_NAME.value,
10081031
}
10091032

10101033
query = db.session.query(
1011-
AttributeKey.id,
1034+
AttributeKey.key_name,
10121035
AttributeKey.external_key,
10131036
ConditionAttribute.attribute_value,
10141037
).outerjoin(
10151038
AttributeKey, ConditionAttribute.attribute_key_id == AttributeKey.id
10161039
).filter(
10171040
ConditionAttribute.condition_id == condition_id,
1018-
~ConditionAttribute.attribute_key_id.in_([key.value for key in excluded_keys]),
1041+
~AttributeKey.key_name.in_(excluded_key_names),
10191042
)
10201043

10211044
if management_plan_id:
@@ -1029,31 +1052,29 @@ def _fetch_condition_attributes_external(
10291052
requires_iem = False
10301053
deliverables = []
10311054

1032-
for attr_id, external_key, raw_value in attributes_data:
1055+
for key_name, external_key, raw_value in attributes_data:
10331056
if not external_key:
10341057
continue
10351058

1036-
key_enum = AttributeKeys(attr_id)
1037-
10381059
# Handle requires_iem_terms_of_engagement
1039-
if key_enum == AttributeKeys.REQUIRES_IEM_TERMS_OF_ENGAGEMENT:
1060+
if key_name == AttributeKeys.REQUIRES_IEM_TERMS_OF_ENGAGEMENT.value:
10401061
requires_iem = raw_value
10411062
result[external_key] = requires_iem
10421063
continue
10431064

10441065
# Handle deliverable_name separately
1045-
if key_enum == AttributeKeys.DELIVERABLE_NAME:
1046-
deliverables.append((raw_value or "", attr_id))
1066+
if key_name == AttributeKeys.DELIVERABLE_NAME.value:
1067+
deliverables.append((raw_value or "", key_name))
10471068
continue
10481069

10491070
# Format value
1050-
value = ConditionService._format_attribute_value(key_enum, raw_value, formatted_keys)
1071+
value = ConditionService._format_attribute_value(key_name, raw_value, formatted_key_names)
10511072
result[external_key] = value
10521073

10531074
# Handle deliverables
10541075
if deliverables:
10551076
result.update(
1056-
ConditionService._process_deliverables(deliverables, requires_iem, formatted_keys)
1077+
ConditionService._process_deliverables(deliverables, requires_iem, formatted_key_names)
10571078
)
10581079

10591080
if management_plan_id:
@@ -1063,9 +1084,9 @@ def _fetch_condition_attributes_external(
10631084
return result
10641085

10651086
@staticmethod
1066-
def _format_attribute_value(key_enum, raw_value, formatted_keys):
1087+
def _format_attribute_value(key_name, raw_value, formatted_key_names):
10671088
"""Format value"""
1068-
if key_enum in formatted_keys:
1089+
if key_name in formatted_key_names:
10691090
return ConditionService.format_attribute_value(raw_value)
10701091
return (
10711092
raw_value.replace("{", "").replace("}", "").replace('"', "")
@@ -1074,7 +1095,7 @@ def _format_attribute_value(key_enum, raw_value, formatted_keys):
10741095
)
10751096

10761097
@staticmethod
1077-
def _process_deliverables(deliverables, requires_iem, formatted_keys):
1098+
def _process_deliverables(deliverables, requires_iem, formatted_key_names):
10781099
deliverable_phrase = IEMTermsConfig.DELIVERABLE_VALUE
10791100
selected_value = None
10801101

@@ -1089,7 +1110,7 @@ def _process_deliverables(deliverables, requires_iem, formatted_keys):
10891110
if not selected_value:
10901111
return {}
10911112

1092-
if AttributeKeys.DELIVERABLE_NAME in formatted_keys:
1113+
if AttributeKeys.DELIVERABLE_NAME.value in formatted_key_names:
10931114
return {"deliverable_name": [ConditionService.format_attribute_value(selected_value)]}
10941115

10951116
return {
@@ -1275,7 +1296,7 @@ def _fetch_condition_attributes(requires_management_plan, condition_id):
12751296
.outerjoin(AttributeKey, ConditionAttribute.attribute_key_id == AttributeKey.id)
12761297
.filter(
12771298
ManagementPlan.condition_id == condition_id,
1278-
~ConditionAttribute.attribute_key_id.in_([5])
1299+
AttributeKey.key_name != AttributeKeys.PARTIES_REQUIRED_TO_BE_SUBMITTED.value
12791300
)
12801301
.order_by(ManagementPlan.id, AttributeKey.sort_order)
12811302
.all()

0 commit comments

Comments
 (0)