Skip to content

Commit 7aad517

Browse files
authored
Merge pull request #188 from dinesh-aot/COMP-298
InspectionRequirements - GET By Id, Update
2 parents 9e8dbb8 + 2cfaf59 commit 7aad517

File tree

8 files changed

+319
-29
lines changed

8 files changed

+319
-29
lines changed

compliance-api/src/compliance_api/models/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@
3333
from .position import Position
3434
from .project import Project
3535
from .req_source_document_map import RequirementSourceDocumentMap
36-
from .requirement_source import RequirementSource
36+
from .requirement_source import RequirementSource, RequirementSourceEnum
3737
from .staff_user import StaffUser
3838
from .topic import Topic
3939
from .unapproved_project import UnapprovedProject

compliance-api/src/compliance_api/models/inspection/inspection_req_detail_doc.py

Lines changed: 27 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
from sqlalchemy import Column, ForeignKey, Integer, String
44
from sqlalchemy.orm import relationship
55

6-
from ..base_model import BaseModelVersioned
6+
from ..base_model import BaseModelVersioned, db
77

88

99
class InspectionReqDetailDocument(BaseModelVersioned):
@@ -52,7 +52,7 @@ class InspectionReqDetailDocument(BaseModelVersioned):
5252
"InspectionReqSourceDetail",
5353
back_populates="documents",
5454
lazy="select",
55-
uselist=False
55+
uselist=False,
5656
)
5757
document_type = relationship(
5858
"DocumentType", foreign_keys=[document_type_id], lazy="select"
@@ -68,3 +68,28 @@ def create_doc_detail(cls, doc_detail_obj, session=None):
6868
else:
6969
doc_detail.save()
7070
return doc_detail
71+
72+
@classmethod
73+
def update_doc_detail(cls, doc_detail_id, doc_detail_data, session=None):
74+
"""Update requirement doc detail."""
75+
query = cls.query.filter_by(id=doc_detail_id)
76+
doc_detail: InspectionReqDetailDocument = query.first()
77+
if not doc_detail or doc_detail.is_deleted:
78+
return None
79+
query.update(doc_detail_data)
80+
if session:
81+
session.flush()
82+
else:
83+
db.session.commit()
84+
return doc_detail
85+
86+
@classmethod
87+
def delete_req_doc_details_by_ids(cls, req_doc_detail_ids, session=None):
88+
"""Delete the requirement doc details by req_doc_detail_ids."""
89+
cls.query.filter(InspectionReqDetailDocument.id.in_(req_doc_detail_ids)).update(
90+
{cls.is_deleted: True, cls.is_active: False}
91+
)
92+
if session:
93+
session.flush()
94+
else:
95+
db.session.commit()

compliance-api/src/compliance_api/models/inspection/inspection_req_source_detail.py

Lines changed: 36 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
from sqlalchemy import Column, ForeignKey, Integer, String
44
from sqlalchemy.orm import relationship
55

6-
from ..base_model import BaseModelVersioned
6+
from ..base_model import BaseModelVersioned, db
77

88

99
class InspectionReqSourceDetail(BaseModelVersioned):
@@ -60,7 +60,7 @@ class InspectionReqSourceDetail(BaseModelVersioned):
6060
"InspectionRequirement",
6161
back_populates="requirement_source_details",
6262
lazy="select",
63-
uselist=False
63+
uselist=False,
6464
)
6565
requirement_source = relationship(
6666
"RequirementSource", foreign_keys=[requirement_source_id], lazy="joined"
@@ -81,3 +81,37 @@ def create_source_detail(cls, source_detail_obj, session=None):
8181
else:
8282
source_detail.save()
8383
return source_detail
84+
85+
@classmethod
86+
def update_requirement_source_detail(
87+
cls, req_detail_id, source_detail_data, session=None
88+
):
89+
"""Update requirement detail."""
90+
query = cls.query.filter_by(id=req_detail_id)
91+
source_detail: InspectionReqSourceDetail = query.first()
92+
if not source_detail or source_detail.is_deleted:
93+
return None
94+
query.update(source_detail_data)
95+
if session:
96+
session.flush()
97+
else:
98+
db.session.commit()
99+
return source_detail
100+
101+
@classmethod
102+
def get_all_by_requirement_id(cls, requirement_id):
103+
"""Get all requirement detail entries by requirement_id."""
104+
return cls.query.filter_by(
105+
requirement_id=requirement_id, is_active=True, is_deleted=False
106+
).all()
107+
108+
@classmethod
109+
def delete_req_details_by_ids(cls, req_detail_ids, session=None):
110+
"""Delete the requirement details by req_detail_ids."""
111+
cls.query.filter(InspectionReqSourceDetail.id.in_(req_detail_ids)).update(
112+
{cls.is_deleted: True, cls.is_active: False}
113+
)
114+
if session:
115+
session.flush()
116+
else:
117+
db.session.commit()

compliance-api/src/compliance_api/models/inspection/inspection_requirement.py

Lines changed: 20 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,7 @@ class InspectionRequirement(BaseModelVersioned):
6262
requirement_source_details = relationship(
6363
"InspectionReqSourceDetail",
6464
back_populates="inspection_requirement",
65-
lazy="select"
65+
lazy="select",
6666
)
6767

6868
@classmethod
@@ -79,8 +79,22 @@ def create_requirement(cls, requirement_obj, session=None):
7979
@classmethod
8080
def get_by_inspection_id(cls, inspection_id):
8181
"""Get requirements by inspection id."""
82-
return db.session.query(InspectionRequirement).filter(
83-
InspectionRequirement.inspection_id == inspection_id,
84-
InspectionRequirement.is_deleted.is_(False),
85-
InspectionRequirement.is_active.is_(True)
86-
).all()
82+
return (
83+
db.session.query(InspectionRequirement)
84+
.filter_by(inspection_id=inspection_id, is_deleted=False, is_active=True)
85+
.all()
86+
)
87+
88+
@classmethod
89+
def update_requirement(cls, requirement_id, requirement_data, session=None):
90+
"""Update inspection requirement."""
91+
query = cls.query.filter_by(id=requirement_id)
92+
requirement: InspectionRequirement = query.first()
93+
if not requirement or requirement.is_deleted:
94+
return None
95+
query.update(requirement_data)
96+
if session:
97+
session.flush()
98+
else:
99+
db.session.commit()
100+
return requirement

compliance-api/src/compliance_api/resources/inspection_requirement.py

Lines changed: 48 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,8 @@
55
from flask_restx import Namespace, Resource
66

77
from compliance_api.auth import auth
8-
from compliance_api.schemas.inspection_requirement import InspectionRequirementCreateSchema, InspectionRequirementSchema
8+
from compliance_api.schemas.inspection_requirement import (
9+
InspectionRequirementCreateSchema, InspectionRequirementSchema, InspectionRequirementUpdateSchema)
910
from compliance_api.services import InspectionRequirementService
1011
from compliance_api.utils.util import cors_preflight
1112

@@ -21,16 +22,24 @@
2122
API, InspectionRequirementSchema(), "InspectionRequirementList"
2223
)
2324

25+
inspection_requirement_update_model = ApiHelper.convert_ma_schema_to_restx_model(
26+
API, InspectionRequirementUpdateSchema(), "InspectionRequirementUpdate"
27+
)
28+
2429

2530
@cors_preflight("GET, OPTIONS, POST")
2631
@API.route("", methods=["POST", "GET", "OPTIONS"])
2732
class InspectionRequirements(Resource):
2833
"""InspectionRequirements."""
2934

3035
@staticmethod
31-
@ApiHelper.swagger_decorators(API, endpoint_description="Get all requirements by inspection")
36+
@ApiHelper.swagger_decorators(
37+
API, endpoint_description="Get all requirements by inspection"
38+
)
3239
@auth.require
33-
@API.response(code=200, description="Success", model=[inspection_requirement_list_model])
40+
@API.response(
41+
code=200, description="Success", model=[inspection_requirement_list_model]
42+
)
3443
def get(inspection_id):
3544
"""Get requirements by inspection id."""
3645
requirements = InspectionRequirementService.get_all(inspection_id)
@@ -56,3 +65,39 @@ def post(inspection_id):
5665
InspectionRequirementSchema().dump(created_requirement),
5766
HTTPStatus.CREATED,
5867
)
68+
69+
70+
@cors_preflight("GET, PATCH, DELETE, OPTIONS")
71+
@API.route("/<int:requirement_id>", methods=["GET", "PATCH", "OPTIONS", "DELETE"])
72+
class InspectionRequirement(Resource):
73+
"""InspectionRequirement resource."""
74+
75+
@staticmethod
76+
@API.response(
77+
code=200, description="Success", model=[inspection_requirement_list_model]
78+
)
79+
@ApiHelper.swagger_decorators(
80+
API, endpoint_description="Fetch inspection requirement by id"
81+
)
82+
@auth.require
83+
def get(requirement_id):
84+
"""Fetch all inspection requirement."""
85+
requirement = InspectionRequirementService.get_by_id(requirement_id)
86+
return InspectionRequirementSchema().dump(requirement), HTTPStatus.OK
87+
88+
@staticmethod
89+
@API.response(
90+
code=200, description="Sucess", model=[inspection_requirement_list_model]
91+
)
92+
@API.expect(inspection_requirement_update_model)
93+
@ApiHelper.swagger_decorators(
94+
API, endpoint_description="Update inspection requirement"
95+
)
96+
@auth.require
97+
def patch(inspection_id, requirement_id):
98+
"""Update inspection inspection requirement."""
99+
requirement_data = InspectionRequirementUpdateSchema().load(API.payload)
100+
updated_requirement = InspectionRequirementService.update(
101+
inspection_id, requirement_id, requirement_data
102+
)
103+
return InspectionRequirementSchema().dump(updated_requirement), HTTPStatus.OK

compliance-api/src/compliance_api/schemas/__init__.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,8 @@
2626
from .inspection import (
2727
InspectionAttendanceSchema, InspectionCreateSchema, InspectionOfficerSchema, InspectionSchema,
2828
InspectionStatusSchema, InspectionUpdateSchema)
29-
from .inspection_requirement import InspectionRequirementCreateSchema, InspectionRequirementSchema
29+
from .inspection_requirement import (
30+
InspectionRequirementCreateSchema, InspectionRequirementSchema, InspectionRequirementUpdateSchema)
3031
from .paginate import PaginationParameterSchema
3132
from .project import ProjectSchema
3233
from .staff_user import StaffUserCreateSchema, StaffUserSchema, StaffUserUpdateSchema

compliance-api/src/compliance_api/schemas/inspection_requirement.py

Lines changed: 86 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,9 +12,10 @@
1212
# See the License for the specific language governing permissions and
1313
# limitations under the License.
1414
"""Inspection requirement Schema Schema."""
15-
from marshmallow import EXCLUDE, fields
15+
from marshmallow import EXCLUDE, ValidationError, fields, validates_schema
1616

1717
from compliance_api.models import InspectionReqDetailDocument, InspectionReqSourceDetail, InspectionRequirement
18+
from compliance_api.models.requirement_source import RequirementSourceEnum
1819

1920
from .base_schema import AutoSchemaBase, BaseSchema
2021

@@ -37,6 +38,16 @@ class InspectionReqDetailDocCreateSchema(BaseSchema):
3738
)
3839

3940

41+
class InspectionReqDetailDocUpdateSchema(InspectionReqDetailDocCreateSchema):
42+
"""InspectionReqDetailDocUpdateSchema."""
43+
44+
id = fields.Int(
45+
metadata={
46+
"description": "The unique identifier of the requirement detail document"
47+
}
48+
)
49+
50+
4051
class InspectionReqSourceDetailCreateSchema(BaseSchema):
4152
"""InspectionReqSourceDetailSchema."""
4253

@@ -69,6 +80,69 @@ class InspectionReqSourceDetailCreateSchema(BaseSchema):
6980
)
7081
documents = fields.List(fields.Nested(InspectionReqDetailDocCreateSchema))
7182

83+
@validates_schema
84+
def validate_section_number(
85+
self, data, **kwargs
86+
): # pylint: disable=no-self-use, unused-argument
87+
"""Ensure the correct requirement is selected for the section number."""
88+
section_number = data.get("section_number", [])
89+
requirement_source_id = data.get("requirement_source_id", None)
90+
if section_number and RequirementSourceEnum(requirement_source_id) not in [
91+
RequirementSourceEnum.ACT_2002,
92+
RequirementSourceEnum.ACT_2018,
93+
RequirementSourceEnum.COMPLIANCE_AGREEMENT,
94+
RequirementSourceEnum.CERTIFIED_PROJECT_DESCRIPTION,
95+
RequirementSourceEnum.NOT_EA_ACT,
96+
]:
97+
raise ValidationError(
98+
"Invalid requirement source for the given section number",
99+
field_name="section_number",
100+
)
101+
102+
@validates_schema
103+
def validate_amendment_number(
104+
self, data, **kwargs
105+
): # pylint: disable=no-self-use, unused-argument
106+
"""Ensure the correct requirement is selected for the amendment number."""
107+
amendment_number = data.get("amendment_number", [])
108+
requirement_source_id = data.get("requirement_source_id", None)
109+
if (
110+
amendment_number
111+
and RequirementSourceEnum(requirement_source_id)
112+
!= RequirementSourceEnum.EAC_AMENDMENT
113+
):
114+
raise ValidationError(
115+
"Invalid requirement source for the given amendment number",
116+
field_name="amendment_number",
117+
)
118+
119+
@validates_schema
120+
def validate_condition_number(
121+
self, data, **kwargs
122+
): # pylint: disable=no-self-use, unused-argument
123+
"""Ensure the correct requirement is selected for the condition number."""
124+
condition_number = data.get("condition_number", [])
125+
requirement_source_id = data.get("requirement_source_id", None)
126+
if condition_number and RequirementSourceEnum(requirement_source_id) not in [
127+
RequirementSourceEnum.SCHEDULE_B,
128+
RequirementSourceEnum.EAC_CERTIFICATE,
129+
]:
130+
raise ValidationError(
131+
"Invalid requirement source for the given condition number",
132+
field_name="condition_number",
133+
)
134+
135+
136+
class InspectionReqSourceDetailUpdateSchema(InspectionReqSourceDetailCreateSchema):
137+
"""InspectionRequirementUpdateSchema."""
138+
139+
id = fields.Int(
140+
metadata={
141+
"description": "The unique identifier of the requirement source detail."
142+
}
143+
)
144+
documents = fields.List(fields.Nested(InspectionReqDetailDocUpdateSchema))
145+
72146

73147
class InspectionRequirementCreateSchema(BaseSchema):
74148
"""InspectionRequirementCreateSchema."""
@@ -100,6 +174,17 @@ class InspectionRequirementCreateSchema(BaseSchema):
100174
)
101175

102176

177+
class InspectionRequirementUpdateSchema(InspectionRequirementCreateSchema):
178+
"""InspectionRequirementUpdateSchema."""
179+
180+
id = fields.Int(
181+
metadata={"description": "The unique identifier of the requirement"}
182+
)
183+
requirement_source_details = fields.List(
184+
fields.Nested(InspectionReqSourceDetailUpdateSchema)
185+
)
186+
187+
103188
class InspectionReqDetailDocSchema(
104189
AutoSchemaBase
105190
): # pylint: disable=too-many-ancestors

0 commit comments

Comments
 (0)