diff --git a/bricktracker/individual_part.py b/bricktracker/individual_part.py index 657e01e..4905674 100644 --- a/bricktracker/individual_part.py +++ b/bricktracker/individual_part.py @@ -803,6 +803,19 @@ class IndividualPart(BrickRecord): } ) + # Download part image if available + image_url = color_info.get('part_img_url', '') + if image_url: + try: + self.download_image(image_url) + except Exception as e: + # Don't fail the whole operation if image download fails + logger.warning('Could not download image for part {part_num} color {color_id}: {error}'.format( + part_num=part_num, + color_id=color_id, + error=e + )) + parts_added += 1 # Commit all changes @@ -816,7 +829,7 @@ class IndividualPart(BrickRecord): # Generate link to individual parts list from flask import url_for - parts_url = url_for('individual_part.list_all') + parts_url = url_for('individual_part.list') # Send completion with message and link socket.complete( diff --git a/bricktracker/set_storage.py b/bricktracker/set_storage.py index 08c2429..41f3494 100644 --- a/bricktracker/set_storage.py +++ b/bricktracker/set_storage.py @@ -1,4 +1,6 @@ from .metadata import BrickMetadata +from .exceptions import ErrorException +from .sql import BrickSQL from flask import url_for @@ -13,6 +15,7 @@ class BrickSetStorage(BrickMetadata): select_query: str = 'set/metadata/storage/select' update_field_query: str = 'set/metadata/storage/update/field' update_set_value_query: str = 'set/metadata/storage/update/value' + count_usage_query: str = 'set/metadata/storage/count_usage' # Self url def url(self, /) -> str: @@ -20,3 +23,52 @@ class BrickSetStorage(BrickMetadata): 'storage.details', id=self.fields.id, ) + + # Delete from database - check if storage is in use first + def delete(self, /) -> None: + # Check if storage is being used + sql = BrickSQL() + result = sql.fetchone(self.count_usage_query, parameters={'id': self.fields.id}) + + if result: + sets_count = result[0] + minifigures_count = result[1] + parts_count = result[2] + lots_count = result[3] + + total_count = sets_count + minifigures_count + parts_count + lots_count + + if total_count > 0: + # Build error message with counts and link + error_parts = [] + if sets_count > 0: + error_parts.append('{count} set{plural}'.format( + count=sets_count, + plural='s' if sets_count != 1 else '' + )) + if minifigures_count > 0: + error_parts.append('{count} individual minifigure{plural}'.format( + count=minifigures_count, + plural='s' if minifigures_count != 1 else '' + )) + if parts_count > 0: + error_parts.append('{count} individual part{plural}'.format( + count=parts_count, + plural='s' if parts_count != 1 else '' + )) + if lots_count > 0: + error_parts.append('{count} part lot{plural}'.format( + count=lots_count, + plural='s' if lots_count != 1 else '' + )) + + error_message = 'Cannot delete storage location "{name}". You need to remove {items} from this storage before it can be deleted. View storage details'.format( + name=self.fields.name, + items=', '.join(error_parts), + url=self.url() + ) + + raise ErrorException(error_message) + + # If not in use, proceed with deletion + super().delete() diff --git a/bricktracker/sql/set/metadata/storage/count_usage.sql b/bricktracker/sql/set/metadata/storage/count_usage.sql new file mode 100644 index 0000000..4e5cbd2 --- /dev/null +++ b/bricktracker/sql/set/metadata/storage/count_usage.sql @@ -0,0 +1,6 @@ +-- Count how many items are using this storage location +SELECT + (SELECT COUNT(*) FROM bricktracker_sets WHERE storage = :id) as sets_count, + (SELECT COUNT(*) FROM bricktracker_individual_minifigures WHERE storage = :id) as minifigures_count, + (SELECT COUNT(*) FROM bricktracker_individual_parts WHERE storage = :id) as parts_count, + (SELECT COUNT(*) FROM bricktracker_individual_part_lots WHERE storage = :id) as lots_count diff --git a/bricktracker/views/admin/storage.py b/bricktracker/views/admin/storage.py index 7c686bf..33f068c 100644 --- a/bricktracker/views/admin/storage.py +++ b/bricktracker/views/admin/storage.py @@ -45,7 +45,7 @@ def delete(*, id: str) -> str: 'admin.html', delete_storage=True, storage=BrickSetStorage().select_specific(id), - error=request.args.get('storage_error') + storage_error=request.args.get('storage_error') ) diff --git a/templates/admin/storage/delete.html b/templates/admin/storage/delete.html index b3eb990..9cc1deb 100644 --- a/templates/admin/storage/delete.html +++ b/templates/admin/storage/delete.html @@ -2,7 +2,7 @@ {{ accordion.header('Set storages danger zone', 'storage-danger', 'admin', expanded=true, danger=true, class='text-end') }}