Skip to content

Commit

Permalink
Create inspection requirement
Browse files Browse the repository at this point in the history
  • Loading branch information
dinesh-aot committed Jan 2, 2025
1 parent 83e758b commit 7727260
Show file tree
Hide file tree
Showing 10 changed files with 394 additions and 8 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
"""inspection_requirement patches
Revision ID: 791cc75df1c4
Revises: a684c47ac3e8
Create Date: 2025-01-02 15:02:27.066126
"""
from alembic import op
import sqlalchemy as sa


# revision identifiers, used by Alembic.
revision = '791cc75df1c4'
down_revision = 'a684c47ac3e8'
branch_labels = None
depends_on = None


def upgrade():
# ### commands auto generated by Alembic - please adjust! ###
with op.batch_alter_table('inspection_req_detail_documents', schema=None) as batch_op:
batch_op.alter_column('document_title',
existing_type=sa.VARCHAR(),
nullable=True,
existing_comment='The title of the document')

with op.batch_alter_table('inspection_requirements', schema=None) as batch_op:
batch_op.add_column(sa.Column('sort_order', sa.Integer(), nullable=False, comment='The order of requirements'))
batch_op.alter_column('enforcement_action_id',
existing_type=sa.INTEGER(),
nullable=True,
existing_comment='The enforcement action taken on the requirement')
batch_op.alter_column('compliance_finding_id',
existing_type=sa.INTEGER(),
nullable=True,
existing_comment='Compliance finding of the requirement')

with op.batch_alter_table('inspection_requirements_version', schema=None) as batch_op:
batch_op.add_column(sa.Column('sort_order', sa.Integer(), autoincrement=False, nullable=True, comment='The order of requirements'))
batch_op.add_column(sa.Column('sort_order_mod', sa.Boolean(), server_default=sa.text('false'), nullable=False))

# ### end Alembic commands ###


def downgrade():
# ### commands auto generated by Alembic - please adjust! ###
with op.batch_alter_table('inspection_requirements_version', schema=None) as batch_op:
batch_op.drop_column('sort_order_mod')
batch_op.drop_column('sort_order')

with op.batch_alter_table('inspection_requirements', schema=None) as batch_op:
batch_op.alter_column('compliance_finding_id',
existing_type=sa.INTEGER(),
nullable=False,
existing_comment='Compliance finding of the requirement')
batch_op.alter_column('enforcement_action_id',
existing_type=sa.INTEGER(),
nullable=False,
existing_comment='The enforcement action taken on the requirement')
batch_op.drop_column('sort_order')

with op.batch_alter_table('inspection_req_detail_documents', schema=None) as batch_op:
batch_op.alter_column('document_title',
existing_type=sa.VARCHAR(),
nullable=False,
existing_comment='The title of the document')

# ### end Alembic commands ###
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ class InspectionReqDetailDocument(BaseModelVersioned):
comment="The unique identifier of the document type",
nullable=False,
)
document_title = Column(String, nullable=False, comment="The title of the document")
document_title = Column(String, nullable=True, comment="The title of the document")
section_number = Column(
String,
nullable=True,
Expand All @@ -49,8 +49,21 @@ class InspectionReqDetailDocument(BaseModelVersioned):
String, nullable=True, comment="Additional description of the document"
)
requirement_source_detail = relationship(
"InspectionReqSourceDetail", foreign_keys=[req_detail_id], lazy="select"
"InspectionReqSourceDetail",
back_populates="documents",
lazy="select",
)
document_type = relationship(
"DocumentType", foreign_keys=[document_type_id], lazy="select"
)

@classmethod
def create_doc_detail(cls, doc_detail_obj, session=None):
"""Persist doc detail in database."""
doc_detail = InspectionReqDetailDocument(**doc_detail_obj)
if session:
session.add(doc_detail)
session.flush()
else:
doc_detail.save()
return doc_detail
Original file line number Diff line number Diff line change
Expand Up @@ -57,8 +57,26 @@ class InspectionReqSourceDetail(BaseModelVersioned):
comment="The description of the requirement source detail",
)
inspection_requirement = relationship(
"InspectionRequirement", foreign_keys=[requirement_id], lazy="select"
"InspectionRequirement",
back_populates="requirement_source_details",
lazy="select",
)
requirement_source = relationship(
"RequirementSource", foreign_keys=[requirement_source_id], lazy="joined"
)
documents = relationship(
"InspectionReqDetailDocument",
back_populates="requirement_source_detail",
lazy="joined",
)

@classmethod
def create_source_detail(cls, source_detail_obj, session=None):
"""Persist source detail in database."""
source_detail = InspectionReqSourceDetail(**source_detail_obj)
if session:
session.add(source_detail)
session.flush()
else:
source_detail.save()
return source_detail
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ class InspectionRequirement(BaseModelVersioned):
"enforcement_action_options.id",
name="insepction_requirements_enforcement_action_fkey",
),
nullable=False,
nullable=True,
comment="The enforcement action taken on the requirement",
)
compliance_finding_id = Column(
Expand All @@ -44,12 +44,12 @@ class InspectionRequirement(BaseModelVersioned):
"compliance_finding_options.id",
name="inspection_req_compliance_finding_fkey",
),
nullable=False,
nullable=True,
comment="Compliance finding of the requirement",
)
findings = Column(
String, comment="The findings of the requirement"
)
findings = Column(String, nullable=True, comment="The findings of the requirement")
sort_order = Column(Integer, nullable=False, comment="The order of requirements")

inspection = relationship("Inspection", foreign_keys=[inspection_id], lazy="select")
topic = relationship("Topic", foreign_keys=[topic_id], lazy="joined")
enforcement_action = relationship(
Expand All @@ -58,3 +58,19 @@ class InspectionRequirement(BaseModelVersioned):
compliance_finding = relationship(
"ComplianceFindingOption", foreign_keys=[compliance_finding_id], lazy="joined"
)
requirement_source_details = relationship(
"InspectionReqSourceDetail",
back_populates="inspection_requirement",
lazy="joined",
)

@classmethod
def create_requirement(cls, requirement_obj, session=None):
"""Persist inspection requirement in database."""
requirement = InspectionRequirement(**requirement_obj)
if session:
session.add(requirement)
session.flush()
else:
requirement.save()
return requirement
2 changes: 2 additions & 0 deletions compliance-api/src/compliance_api/resources/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@
from .continuation_report import API as CONTINUATION_REPORT_API
from .enforcement_action import API as ENFORCEMENT_ACTION_API
from .inspection import API as INSPECTION_API
from .inspection_requirement import API as INSPECTION_REQUIREMENT_API
from .ops import API as OPS_API
from .position import API as POSITION_API
from .project import API as PROJECT_API
Expand Down Expand Up @@ -85,3 +86,4 @@
API.add_namespace(CONTINUATION_REPORT_API)
API.add_namespace(ENFORCEMENT_ACTION_API)
API.add_namespace(COMPLIANCE_FINDING_API)
API.add_namespace(INSPECTION_REQUIREMENT_API, path="inspections/<int:inspection_id>/requirements")
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
"""InspectionRequirementResource."""

from http import HTTPStatus

from flask_restx import Namespace, Resource

from compliance_api.auth import auth
from compliance_api.schemas.inspection_requirement import InspectionRequirementCreateSchema, InspectionRequirementSchema
from compliance_api.services import InspectionRequirementService
from compliance_api.utils.util import cors_preflight

from .apihelper import Api as ApiHelper


API = Namespace("requirements", description="Endpoints for Inspection Requirement")
inspection_requirement_create_model = ApiHelper.convert_ma_schema_to_restx_model(
API, InspectionRequirementCreateSchema(), "InspectionRequirement"
)

inspection_requirement_list_model = ApiHelper.convert_ma_schema_to_restx_model(
API, InspectionRequirementSchema(), "InspectionRequirementList"
)


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

@staticmethod
@ApiHelper.swagger_decorators(API, endpoint_description="Create an inspection")
@API.expect(inspection_requirement_create_model)
@API.response(
code=201,
model=inspection_requirement_list_model,
description="InspectionCreated",
)
@API.response(400, "Bad Request")
@auth.require
def post(inspection_id):
"""Create an inspection."""
requirement_data = InspectionRequirementCreateSchema().load(API.payload)
created_requirement = InspectionRequirementService.create(
inspection_id, requirement_data
)
return (
InspectionRequirementSchema().dump(created_requirement),
HTTPStatus.CREATED,
)
1 change: 1 addition & 0 deletions compliance-api/src/compliance_api/schemas/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
from .inspection import (
InspectionAttendanceSchema, InspectionCreateSchema, InspectionOfficerSchema, InspectionSchema,
InspectionStatusSchema, InspectionUpdateSchema)
from .inspection_requirement import InspectionRequirementCreateSchema, InspectionRequirementSchema
from .paginate import PaginationParameterSchema
from .project import ProjectSchema
from .staff_user import StaffUserCreateSchema, StaffUserSchema, StaffUserUpdateSchema
Expand Down
144 changes: 144 additions & 0 deletions compliance-api/src/compliance_api/schemas/inspection_requirement.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,144 @@
# Copyright © 2024 Province of British Columbia
#
# Licensed under the Apache License, Version 2.0 (the 'License');
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an 'AS IS' BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
"""Inspection requirement Schema Schema."""
from marshmallow import EXCLUDE, fields

from compliance_api.models import InspectionReqDetailDocument, InspectionReqSourceDetail, InspectionRequirement

from .base_schema import AutoSchemaBase, BaseSchema


class InspectionReqDetailDocCreateSchema(BaseSchema):
"""InpsectionReqDetailDocCreateSchema."""

document_type_id = fields.Int(
metadata={"description": "The unique identifier of the document type"},
required=True,
)
document_title = fields.Str(metadata={"description": "The title of the document"})
section_number = fields.Str(
metadata={
"description": "The highlighted section number in the uploaded document"
}
)
section_title = fields.Str(
metadata={"description": "Additional description of the document"}
)


class InspectionReqSourceDetailCreateSchema(BaseSchema):
"""InspectionReqSourceDetailSchema."""

requirement_source_id = fields.Int(
metadata={"description": "The unique identifier of the requirement."},
required=True,
)
section_number = fields.Str(
metadata={
"description": "The optional section number associated with requirement sources"
"(Act (2018), Schedule A, Compliance Agreement, Act (2002))"
}
)
condition_number = fields.Str(
metadata={
"description": "The optional condition number associated with"
"rquirement sources(Schedule B, EAC Certificate)"
}
)
amendment_number = fields.Str(
metadata={
"description": "The optional amendment number if the requirement source is EAC Amendment"
}
)
title = fields.Str(
metadata={"description": "The title of the requirement source detail"}
)
description = fields.Str(
metadata={"description": "The description of the requirement source detail"}
)
documents = fields.List(fields.Nested(InspectionReqDetailDocCreateSchema))


class InspectionRequirementCreateSchema(BaseSchema):
"""InspectionRequirementCreateSchema."""

summary = fields.Str(
metadata={"description": "The summary of the requirement."}, required=True
)
topic_id = fields.Int(
metadata={
"description": "The unique identifier of the topic associated with the inspection"
},
required=True,
)
enforcement_action_id = fields.Int(
metadata={"description": "The enforcement action identifier."}
)
compliance_finding_id = fields.Int(
metadata={"description": "The unique identifier of the compliance findings."}
)
findings = fields.Str(
metadata={"description": "The requirement findings in html format."}
)
sort_order = fields.Int(
metadata={"description": "The order of the inspection requirements"},
required=True,
)
requirement_source_details = fields.List(
fields.Nested(InspectionReqSourceDetailCreateSchema)
)


class InspectionReqDetailDocSchema(
AutoSchemaBase
): # pylint: disable=too-many-ancestors
"""InspectionReqDetailDocSchema."""

class Meta(AutoSchemaBase.Meta): # pylint: disable=too-few-public-methods
"""Meta."""

unknown = EXCLUDE
model = InspectionReqDetailDocument
include_fk = True


class InspectionReqSourceDetailSchema(
AutoSchemaBase
): # pylint: disable=too-many-ancestors
"""InspectionReqSourceSchema."""

class Meta(AutoSchemaBase.Meta): # pylint: disable=too-few-public-methods
"""Meta."""

unknown = EXCLUDE
model = InspectionReqSourceDetail
include_fk = True


documents = fields.List(fields.Nested(InspectionReqDetailDocSchema))


class InspectionRequirementSchema(AutoSchemaBase): # pylint: disable=too-many-ancestors
"""InspectionRequirementSchema."""

class Meta(AutoSchemaBase.Meta): # pylint: disable=too-few-public-methods
"""Meta."""

unknown = EXCLUDE
model = InspectionRequirement
include_fk = True

requirement_source_details = fields.List(
fields.Nested(InspectionReqSourceDetailSchema)
)
1 change: 1 addition & 0 deletions compliance-api/src/compliance_api/services/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
from .continuation_report import ContinuationReportService
from .enforcement_action import EnforcementActionService
from .inspection import InspectionService
from .inspection_requirement import InspectionRequirementService
from .position import PositionService
from .project import ProjectService
from .project_status import ProjectStatusService
Expand Down
Loading

0 comments on commit 7727260

Please sign in to comment.