Skip to content

Commit 006e292

Browse files
authored
Merge pull request #228 from dinesh-aot/COMP-347
inspection requirement images table creationb
2 parents 3580935 + 3907218 commit 006e292

File tree

10 files changed

+538
-12
lines changed

10 files changed

+538
-12
lines changed
Lines changed: 101 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,101 @@
1+
"""inspection_images table creation
2+
3+
Revision ID: 199147664d8e
4+
Revises: ff7d002a8a12
5+
Create Date: 2025-02-18 10:11:33.606897
6+
7+
"""
8+
from alembic import op
9+
import sqlalchemy as sa
10+
11+
12+
# revision identifiers, used by Alembic.
13+
revision = '199147664d8e'
14+
down_revision = 'ff7d002a8a12'
15+
branch_labels = None
16+
depends_on = None
17+
18+
19+
def upgrade():
20+
# ### commands auto generated by Alembic - please adjust! ###
21+
op.create_table('inspection_req_images_version',
22+
sa.Column('id', sa.Integer(), autoincrement=False, nullable=False, comment='The unique identifier'),
23+
sa.Column('requirement_id', sa.Integer(), autoincrement=False, nullable=True, comment='The requirement id'),
24+
sa.Column('sort_order', sa.Integer(), autoincrement=False, nullable=True, comment='The order of images. grouped by the type.'),
25+
sa.Column('image_type', sa.Enum('PHOTO', 'FIGURE', name='imagetype'), autoincrement=False, nullable=True),
26+
sa.Column('original_file_name', sa.String(), autoincrement=False, nullable=True, comment='The original filename of the uploaded image'),
27+
sa.Column('date_taken', sa.DateTime(timezone=True), autoincrement=False, nullable=True, comment='The time of the image when it is captured'),
28+
sa.Column('taken_by_id', sa.Integer(), autoincrement=False, nullable=True, comment='The unique identifier of the staff who captured the image'),
29+
sa.Column('caption', sa.String(), autoincrement=False, nullable=True, comment='The caption of the image'),
30+
sa.Column('url', sa.String(), autoincrement=False, nullable=True, comment='The actual url of the final uploaded image'),
31+
sa.Column('created_date', sa.DateTime(), autoincrement=False, nullable=True),
32+
sa.Column('updated_date', sa.DateTime(), autoincrement=False, nullable=True),
33+
sa.Column('created_by', sa.String(length=100), autoincrement=False, nullable=True),
34+
sa.Column('updated_by', sa.String(length=100), autoincrement=False, nullable=True),
35+
sa.Column('is_active', sa.Boolean(), server_default='t', autoincrement=False, nullable=True),
36+
sa.Column('is_deleted', sa.Boolean(), server_default='f', autoincrement=False, nullable=True),
37+
sa.Column('transaction_id', sa.BigInteger(), autoincrement=False, nullable=False),
38+
sa.Column('end_transaction_id', sa.BigInteger(), nullable=True),
39+
sa.Column('operation_type', sa.SmallInteger(), nullable=False),
40+
sa.Column('requirement_id_mod', sa.Boolean(), server_default=sa.text('false'), nullable=False),
41+
sa.Column('sort_order_mod', sa.Boolean(), server_default=sa.text('false'), nullable=False),
42+
sa.Column('image_type_mod', sa.Boolean(), server_default=sa.text('false'), nullable=False),
43+
sa.Column('original_file_name_mod', sa.Boolean(), server_default=sa.text('false'), nullable=False),
44+
sa.Column('date_taken_mod', sa.Boolean(), server_default=sa.text('false'), nullable=False),
45+
sa.Column('taken_by_id_mod', sa.Boolean(), server_default=sa.text('false'), nullable=False),
46+
sa.Column('caption_mod', sa.Boolean(), server_default=sa.text('false'), nullable=False),
47+
sa.Column('url_mod', sa.Boolean(), server_default=sa.text('false'), nullable=False),
48+
sa.Column('created_date_mod', sa.Boolean(), server_default=sa.text('false'), nullable=False),
49+
sa.Column('updated_date_mod', sa.Boolean(), server_default=sa.text('false'), nullable=False),
50+
sa.Column('created_by_mod', sa.Boolean(), server_default=sa.text('false'), nullable=False),
51+
sa.Column('updated_by_mod', sa.Boolean(), server_default=sa.text('false'), nullable=False),
52+
sa.Column('is_active_mod', sa.Boolean(), server_default=sa.text('false'), nullable=False),
53+
sa.Column('is_deleted_mod', sa.Boolean(), server_default=sa.text('false'), nullable=False),
54+
sa.PrimaryKeyConstraint('id', 'transaction_id')
55+
)
56+
with op.batch_alter_table('inspection_req_images_version', schema=None) as batch_op:
57+
batch_op.create_index(batch_op.f('ix_inspection_req_images_version_end_transaction_id'), ['end_transaction_id'], unique=False)
58+
batch_op.create_index(batch_op.f('ix_inspection_req_images_version_operation_type'), ['operation_type'], unique=False)
59+
batch_op.create_index(batch_op.f('ix_inspection_req_images_version_requirement_id'), ['requirement_id'], unique=False)
60+
batch_op.create_index(batch_op.f('ix_inspection_req_images_version_transaction_id'), ['transaction_id'], unique=False)
61+
62+
op.create_table('inspection_req_images',
63+
sa.Column('id', sa.Integer(), autoincrement=True, nullable=False, comment='The unique identifier'),
64+
sa.Column('requirement_id', sa.Integer(), nullable=False, comment='The requirement id'),
65+
sa.Column('sort_order', sa.Integer(), nullable=False, comment='The order of images. grouped by the type.'),
66+
sa.Column('image_type', sa.Enum('PHOTO', 'FIGURE', name='imagetype'), nullable=False),
67+
sa.Column('original_file_name', sa.String(), nullable=False, comment='The original filename of the uploaded image'),
68+
sa.Column('date_taken', sa.DateTime(timezone=True), nullable=False, comment='The time of the image when it is captured'),
69+
sa.Column('taken_by_id', sa.Integer(), nullable=False, comment='The unique identifier of the staff who captured the image'),
70+
sa.Column('caption', sa.String(), nullable=True, comment='The caption of the image'),
71+
sa.Column('url', sa.String(), nullable=False, comment='The actual url of the final uploaded image'),
72+
sa.Column('created_date', sa.DateTime(), nullable=False),
73+
sa.Column('updated_date', sa.DateTime(), nullable=True),
74+
sa.Column('created_by', sa.String(length=100), nullable=False),
75+
sa.Column('updated_by', sa.String(length=100), nullable=True),
76+
sa.Column('is_active', sa.Boolean(), server_default='t', nullable=False),
77+
sa.Column('is_deleted', sa.Boolean(), server_default='f', nullable=False),
78+
sa.ForeignKeyConstraint(['requirement_id'], ['inspection_requirements.id'], name='inspection_req_images_req_id_fkey'),
79+
sa.ForeignKeyConstraint(['taken_by_id'], ['staff_users.id'], name='inspection_images_taken_by_fkey'),
80+
sa.PrimaryKeyConstraint('id')
81+
)
82+
with op.batch_alter_table('inspection_req_images', schema=None) as batch_op:
83+
batch_op.create_index(batch_op.f('ix_inspection_req_images_requirement_id'), ['requirement_id'], unique=False)
84+
85+
# ### end Alembic commands ###
86+
87+
88+
def downgrade():
89+
# ### commands auto generated by Alembic - please adjust! ###
90+
with op.batch_alter_table('inspection_req_images', schema=None) as batch_op:
91+
batch_op.drop_index(batch_op.f('ix_inspection_req_images_requirement_id'))
92+
93+
op.drop_table('inspection_req_images')
94+
with op.batch_alter_table('inspection_req_images_version', schema=None) as batch_op:
95+
batch_op.drop_index(batch_op.f('ix_inspection_req_images_version_transaction_id'))
96+
batch_op.drop_index(batch_op.f('ix_inspection_req_images_version_requirement_id'))
97+
batch_op.drop_index(batch_op.f('ix_inspection_req_images_version_operation_type'))
98+
batch_op.drop_index(batch_op.f('ix_inspection_req_images_version_end_transaction_id'))
99+
100+
op.drop_table('inspection_req_images_version')
101+
# ### end Alembic commands ###
Lines changed: 123 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,123 @@
1+
"""column change in inspection requirement images
2+
3+
Revision ID: 231cb1f8b9e7
4+
Revises: 199147664d8e
5+
Create Date: 2025-02-19 13:45:32.082113
6+
7+
"""
8+
9+
from alembic import op
10+
import sqlalchemy as sa
11+
12+
13+
# revision identifiers, used by Alembic.
14+
revision = "231cb1f8b9e7"
15+
down_revision = "199147664d8e"
16+
branch_labels = None
17+
depends_on = None
18+
19+
20+
def upgrade():
21+
# ### commands auto generated by Alembic - please adjust! ###
22+
with op.batch_alter_table("inspection_req_images", schema=None) as batch_op:
23+
batch_op.add_column(
24+
sa.Column(
25+
"relative_url",
26+
sa.String(),
27+
nullable=False,
28+
comment="The actual url of the final uploaded image",
29+
)
30+
)
31+
batch_op.drop_column("url")
32+
33+
with op.batch_alter_table("inspection_req_images_version", schema=None) as batch_op:
34+
batch_op.add_column(
35+
sa.Column(
36+
"relative_url",
37+
sa.String(),
38+
autoincrement=False,
39+
nullable=True,
40+
comment="The actual url of the final uploaded image",
41+
)
42+
)
43+
batch_op.add_column(
44+
sa.Column(
45+
"relative_url_mod",
46+
sa.Boolean(),
47+
server_default=sa.text("false"),
48+
nullable=False,
49+
)
50+
)
51+
batch_op.drop_column("url")
52+
batch_op.drop_column("url_mod")
53+
op.execute("CREATE TYPE imagetypeenum as ENUM('PHOTO', 'FIGURE')")
54+
op.execute(
55+
"""
56+
ALTER TABLE inspection_req_images
57+
ALTER COLUMN image_type TYPE imagetypeenum
58+
USING image_type::text::imagetypeenum
59+
"""
60+
)
61+
op.execute(
62+
"""
63+
ALTER TABLE inspection_req_images_version
64+
ALTER COLUMN image_type TYPE imagetypeenum
65+
USING image_type::text::imagetypeenum
66+
"""
67+
)
68+
op.execute("DROP TYPE imagetype")
69+
# ### end Alembic commands ###
70+
71+
72+
def downgrade():
73+
# ### commands auto generated by Alembic - please adjust! ###
74+
with op.batch_alter_table("inspection_req_images_version", schema=None) as batch_op:
75+
batch_op.add_column(
76+
sa.Column(
77+
"url_mod",
78+
sa.BOOLEAN(),
79+
server_default=sa.text("false"),
80+
autoincrement=False,
81+
nullable=False,
82+
)
83+
)
84+
batch_op.add_column(
85+
sa.Column(
86+
"url",
87+
sa.VARCHAR(),
88+
autoincrement=False,
89+
nullable=True,
90+
comment="The actual url of the final uploaded image",
91+
)
92+
)
93+
batch_op.drop_column("relative_url_mod")
94+
batch_op.drop_column("relative_url")
95+
96+
with op.batch_alter_table("inspection_req_images", schema=None) as batch_op:
97+
batch_op.add_column(
98+
sa.Column(
99+
"url",
100+
sa.VARCHAR(),
101+
autoincrement=False,
102+
nullable=False,
103+
comment="The actual url of the final uploaded image",
104+
)
105+
)
106+
batch_op.drop_column("relative_url")
107+
op.execute("CREATE TYPE imagetype as ENUM('PHOTO', 'FIGURE')")
108+
op.execute(
109+
"""
110+
ALTER TABLE inspection_req_images
111+
ALTER COLUMN image_type TYPE imagetype
112+
USING image_type::text::imagetype
113+
"""
114+
)
115+
op.execute(
116+
"""
117+
ALTER TABLE inspection_req_images_version
118+
ALTER COLUMN image_type TYPE imagetype
119+
USING image_type::text::imagetype
120+
"""
121+
)
122+
op.execute("DROP TYPE imagetypeenum")
123+
# ### end Alembic commands ###

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

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -26,10 +26,11 @@
2626
from .document_type import DocumentType
2727
from .enforcement_action import EnforcementActionOption, EnforcementActionOptionEnum
2828
from .inspection import (
29-
Inspection, InspectionAgency, InspectionAttendance, InspectionAttendanceOption, InspectionAttendanceOptionEnum,
30-
InspectionFirstnation, InspectionInitiationOption, InspectionOfficer, InspectionOtherAttendance,
31-
InspectionReqDetailDocument, InspectionReqEnforcementMap, InspectionReqSourceDetail, InspectionRequirement,
32-
InspectionRequirementTypeEnum, InspectionStatusEnum, InspectionType, InspectionTypeOption, IRStatusOption)
29+
ImageTypeEnum, Inspection, InspectionAgency, InspectionAttendance, InspectionAttendanceOption,
30+
InspectionAttendanceOptionEnum, InspectionFirstnation, InspectionInitiationOption, InspectionOfficer,
31+
InspectionOtherAttendance, InspectionReqDetailDocument, InspectionReqEnforcementMap, InspectionReqSourceDetail,
32+
InspectionRequirement, InspectionRequirementImage, InspectionRequirementTypeEnum, InspectionStatusEnum,
33+
InspectionType, InspectionTypeOption, IRStatusOption)
3334
from .position import Position
3435
from .project import Project
3536
from .req_source_document_map import RequirementSourceDocumentMap

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

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,14 +3,15 @@
33
from .inspection import Inspection
44
from .inspection_agency import InspectionAgency
55
from .inspection_attendance import InspectionAttendance
6-
from .inspection_enum import InspectionAttendanceOptionEnum, InspectionStatusEnum
6+
from .inspection_enum import ImageTypeEnum, InspectionAttendanceOptionEnum, InspectionStatusEnum
77
from .inspection_firstnation import InspectionFirstnation
88
from .inspection_officer import InspectionOfficer
99
from .inspection_option import (
1010
InspectionAttendanceOption, InspectionInitiationOption, InspectionTypeOption, IRStatusOption)
1111
from .inspection_other_attendance import InspectionOtherAttendance
1212
from .inspection_req_detail_doc import InspectionReqDetailDocument
1313
from .inspection_req_enforcement_map import InspectionReqEnforcementMap
14+
from .inspection_req_image import InspectionRequirementImage
1415
from .inspection_req_source_detail import InspectionReqSourceDetail
1516
from .inspection_requirement import InspectionRequirement, InspectionRequirementTypeEnum
1617
from .inspection_type import InspectionType

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

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,3 +22,10 @@ class InspectionStatusEnum(enum.Enum):
2222
OPEN = "Open"
2323
CLOSED = "Closed"
2424
CANCELED = "Canceled"
25+
26+
27+
class ImageTypeEnum(enum.Enum):
28+
"""Type of images."""
29+
30+
PHOTO = "Photo"
31+
FIGURE = "Figure"
Lines changed: 93 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,93 @@
1+
"""Model to handle the image uploads in inspection requirements."""
2+
3+
from sqlalchemy import Column, DateTime, Enum, ForeignKey, Integer, String
4+
from sqlalchemy.orm import relationship
5+
6+
from ..base_model import BaseModelVersioned
7+
from ..utils import with_session
8+
from .inspection_enum import ImageTypeEnum
9+
10+
11+
class InspectionRequirementImage(BaseModelVersioned):
12+
"""InspectionRequirementImage."""
13+
14+
__tablename__ = "inspection_req_images"
15+
id = Column(
16+
Integer,
17+
primary_key=True,
18+
autoincrement=True,
19+
comment="The unique identifier",
20+
)
21+
requirement_id = Column(
22+
Integer,
23+
ForeignKey(
24+
"inspection_requirements.id", name="inspection_req_images_req_id_fkey"
25+
),
26+
nullable=False,
27+
index=True,
28+
comment="The requirement id",
29+
)
30+
sort_order = Column(
31+
Integer, nullable=False, comment="The order of images. grouped by the type."
32+
)
33+
image_type = Column(Enum(ImageTypeEnum), nullable=False)
34+
original_file_name = Column(
35+
String, nullable=False, comment="The original filename of the uploaded image"
36+
)
37+
date_taken = Column(
38+
DateTime(timezone=True),
39+
nullable=False,
40+
comment="The time of the image when it is captured",
41+
)
42+
taken_by_id = Column(
43+
Integer,
44+
ForeignKey("staff_users.id", name="inspection_images_taken_by_fkey"),
45+
nullable=False,
46+
comment="The unique identifier of the staff who captured the image",
47+
)
48+
caption = Column(String, nullable=True, comment="The caption of the image")
49+
relative_url = Column(
50+
String, nullable=False, comment="The actual url of the final uploaded image"
51+
)
52+
taken_by = relationship("StaffUser", foreign_keys=[taken_by_id], lazy="joined")
53+
inspection_requirement = relationship(
54+
"InspectionRequirement", foreign_keys=[requirement_id], lazy="select"
55+
)
56+
57+
@classmethod
58+
@with_session
59+
def bulk_insert(cls, images, session=None):
60+
"""Insert images."""
61+
session.add_all(images)
62+
session.flush()
63+
64+
@classmethod
65+
@with_session
66+
def create_image(cls, image_obj, session=None):
67+
"""Persist the image object."""
68+
img_obj = InspectionRequirementImage(**image_obj)
69+
session.add(img_obj)
70+
session.flush()
71+
return img_obj
72+
73+
@classmethod
74+
@with_session
75+
def update_image(cls, image_id, image_data, session=None):
76+
"""Update image details."""
77+
query = cls.query.filter_by(id=image_id)
78+
image_detail: InspectionRequirementImage = query.first()
79+
if not image_detail or image_detail.is_deleted:
80+
return None
81+
image_detail.update(image_data, commit=False)
82+
session.flush()
83+
return image_detail
84+
85+
@classmethod
86+
def find_all_images(cls, requirement_id, image_type: ImageTypeEnum):
87+
"""Get all images by requirement_id."""
88+
return cls.query.filter_by(
89+
requirement_id=requirement_id,
90+
image_type=image_type,
91+
is_active=True,
92+
is_deleted=False,
93+
).all()

0 commit comments

Comments
 (0)