11"""InspectionRequirementService."""
22
3+ import requests
34from flask import g
45
56from compliance_api .auth import auth
6- from compliance_api .exceptions import BadRequestError , PermissionDeniedError , ResourceNotFoundError
7+ from compliance_api .exceptions import (
8+ BadRequestError , PermissionDeniedError , ResourceNotFoundError , UnprocessableEntityError )
79from compliance_api .models import ImageTypeEnum
810from compliance_api .models import Inspection as InspectionModel
911from compliance_api .models import InspectionReqDetailDocument as InspectionReqDetailDocumentModel
1214from compliance_api .models import InspectionRequirement as InspectionRequirementModel
1315from compliance_api .models import InspectionRequirementImage as InspectionRequirementImageModel
1416from compliance_api .models .db import session_scope
17+ from compliance_api .services .document_service .doc_service import DocService
18+ from compliance_api .services .document_service .doc_service_enum import ActionOnFileEnum
1519from compliance_api .utils .enum import PermissionEnum
1620
1721
@@ -49,13 +53,13 @@ def create(cls, inspection_id, requirement_data):
4953 session ,
5054 )
5155 # inserting photos
52- _insert_images (
56+ _insert_or_update_images (
5357 requirement_id = created_requirement .id ,
5458 images = requirement_data .get ("photos" , []),
5559 image_type = ImageTypeEnum .PHOTO ,
5660 session = session ,
5761 )
58- _insert_images (
62+ _insert_or_update_images (
5963 requirement_id = created_requirement .id ,
6064 images = requirement_data .get ("figures" , []),
6165 image_type = ImageTypeEnum .FIGURE ,
@@ -85,13 +89,13 @@ def update(cls, inspection_id, requirement_id, requirement_data):
8589 requirement_data .get ("enforcement_action_ids" , []),
8690 session ,
8791 )
88- _update_images (
92+ _insert_or_update_images (
8993 requirement_id = requirement_id ,
9094 images = requirement_data .get ("photos" , []),
9195 image_type = ImageTypeEnum .PHOTO ,
9296 session = session ,
9397 )
94- _update_images (
98+ _insert_or_update_images (
9599 requirement_id = requirement_id ,
96100 images = requirement_data .get ("figures" , []),
97101 image_type = ImageTypeEnum .FIGURE ,
@@ -167,12 +171,40 @@ def insert_or_update_enforcements(
167171 )
168172
169173 @classmethod
170- def get_all_images (cls , requirement_id , image_type : ImageTypeEnum ):
174+ def get_all_images (cls , inspection_id , requirement_id , image_type : ImageTypeEnum ):
171175 """Get all photos."""
176+ _inspection_check (inspection_id )
177+ _requirement_check (requirement_id )
172178 return InspectionRequirementImageModel .find_all_images (
173179 requirement_id = requirement_id , image_type = image_type
174180 )
175181
182+ @classmethod
183+ def delete_image (cls , inspection_id , requirement_id , relative_url , image_type ):
184+ """Delete image."""
185+ _inspection_check (inspection_id )
186+ _requirement_check (requirement_id )
187+ image = InspectionRequirementImageModel .find_image_by_url (
188+ requirement_id , relative_url , image_type
189+ )
190+ if not image :
191+ raise UnprocessableEntityError (
192+ f"No { image_type .value } found for the given relative url"
193+ )
194+ # Get the presigned delete url for the file
195+ presigned_url_response = DocService .get_presigned_url (
196+ {
197+ "relative_url" : image .relative_url ,
198+ "action" : ActionOnFileEnum .DELETE .value ,
199+ }
200+ )
201+ presigned_delete_url = presigned_url_response .get ("presigned_url" )
202+ # Delete the actual file from cloud storage
203+ delete_response = requests .delete (presigned_delete_url , timeout = 120 )
204+ # Mark the deletion in the inspection_req_images table
205+ InspectionRequirementImageModel .delete_image (image .id )
206+ return delete_response
207+
176208
177209def _create_image_obj (requirement_id , index , img : dict , image_type ):
178210 """Prepare the image object."""
@@ -188,26 +220,33 @@ def _create_image_obj(requirement_id, index, img: dict, image_type):
188220 }
189221
190222
191- def _insert_images (
223+ def _insert_or_update_images (
192224 requirement_id , images : list [dict ], image_type : ImageTypeEnum , session = None
193225):
194- """Insert the images."""
195- if images and len (images ) > 0 :
196- images = [
197- InspectionRequirementImageModel (
198- ** _create_image_obj (requirement_id , index , img , image_type )
199- )
200- for index , img in enumerate (images )
201- ]
202- InspectionRequirementImageModel .bulk_insert (images , session = session )
226+ """Update the images."""
227+ # Fetch existing images from the database
228+ existing_images = InspectionRequirementImageModel .find_all_images (
229+ requirement_id = requirement_id , image_type = image_type
230+ )
231+ existing_image_ids = {img .id for img in existing_images }
203232
233+ # Track incoming image IDs (existing ones)
234+ incoming_image_ids = {img ["id" ] for img in images if "id" in img }
204235
205- def _update_images (
206- requirement_id , images : list [dict ], image_type : ImageTypeEnum , session = None
207- ):
208- """Update the images."""
236+ # DELETE: Remove images that exist in DB but are not in the new list
237+ images_to_delete = existing_image_ids - incoming_image_ids
238+ for image_id in images_to_delete :
239+ InspectionRequirementImageModel .delete_image (image_id , session = session )
240+
241+ # INSERT or UPDATE images while maintaining order
209242 for index , img in enumerate (images ):
210- if not img .get ("id" , None ):
243+ img ["sort_order" ] = index + 1 # Maintain order
244+
245+ if "id" in img : # Update existing image
246+ InspectionRequirementImageModel .update_image (
247+ img ["id" ], img , session = session
248+ )
249+ else : # Insert new image
211250 image_obj = _create_image_obj (
212251 requirement_id = requirement_id ,
213252 index = index ,
@@ -217,11 +256,6 @@ def _update_images(
217256 InspectionRequirementImageModel .create_image (
218257 image_obj = image_obj , session = session
219258 )
220- if img .get ("id" , None ):
221- img ["sort_order" ] = index + 1
222- InspectionRequirementImageModel .update_image (
223- img .get ("id" ), img , session = session
224- )
225259
226260
227261def _update_sort_order_subsequent (requirements , commit = False ):
0 commit comments