mirror of
https://gitea.baerentsen.space/FrederikBaerentsen/BrickTracker.git
synced 2026-05-02 21:20:17 -05:00
fix(individual-parts): bulk add image download and storage deletion validation
This commit is contained in:
@@ -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(
|
||||
|
||||
@@ -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. <a href="{url}">View storage details</a>'.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()
|
||||
|
||||
@@ -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
|
||||
@@ -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')
|
||||
)
|
||||
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
{{ accordion.header('Set storages danger zone', 'storage-danger', 'admin', expanded=true, danger=true, class='text-end') }}
|
||||
<form action="{{ url_for('admin_storage.do_delete', id=storage.fields.id) }}" method="post">
|
||||
{% if storage_error %}<div class="alert alert-danger text-start" role="alert"><strong>Error:</strong> {{ storage_error }}.</div>{% endif %}
|
||||
{% if storage_error %}<div class="alert alert-danger text-start" role="alert"><strong>Error:</strong> {{ storage_error|safe }}</div>{% endif %}
|
||||
<div class="alert alert-danger text-center" role="alert">You are about to <strong>delete a set storage</strong>. This action is irreversible.</div>
|
||||
<div class="row row-cols-lg-auto g-3 align-items-center">
|
||||
<div class="col-12 flex-grow-1">
|
||||
|
||||
Reference in New Issue
Block a user