Compute and display number of parts for minifigures

This commit is contained in:
Gregoo 2025-02-03 10:35:42 +01:00
parent 34408a1bff
commit 4cf91a6edd
10 changed files with 62 additions and 9 deletions

View File

@ -24,6 +24,7 @@
- Minifigure
- Deduplicate
- Compute number of parts
Parts
- Damaged parts
@ -57,6 +58,9 @@ Parts
- Add a clear button for dynamic text inputs
- Add error message in a tooltip for dynamic inputs
- Minifigure
- Display number of parts
- Parts
- Use Rebrickable URL if stored (+ color code)
- Display color and transparency

View File

@ -37,9 +37,6 @@ class BrickMinifigure(RebrickableMinifigure):
# Insert into database
self.insert(commit=False)
# Insert the rebrickable set into database
self.insert_rebrickable()
# Load the inventory
if not BrickPartList.download(
socket,
@ -49,6 +46,9 @@ class BrickMinifigure(RebrickableMinifigure):
):
return False
# Insert the rebrickable set into database (after counting parts)
self.insert_rebrickable()
except Exception as e:
socket.fail(
message='Error while importing minifigure {figure} from {set}: {error}'.format( # noqa: E501

View File

@ -239,10 +239,18 @@ class BrickPartList(BrickRecordList[BrickPart]):
).list()
# Process each part
number_of_parts: int = 0
for part in inventory:
# Count the number of parts for minifigures
if minifigure is not None:
number_of_parts += part.fields.quantity
if not part.download(socket, refresh=refresh):
return False
if minifigure is not None:
minifigure.fields.number_of_parts = number_of_parts
except Exception as e:
socket.fail(
message='Error while importing {kind} {identifier} parts list: {error}'.format( # noqa: E501

View File

@ -0,0 +1,32 @@
-- description: Add number of parts for minifigures
BEGIN TRANSACTION;
-- Add the number_of_parts column to the minifigures
ALTER TABLE "rebrickable_minifigures"
ADD COLUMN "number_of_parts" INTEGER NOT NULL DEFAULT 0;
-- Update the number of parts for each minifigure
UPDATE "rebrickable_minifigures"
SET "number_of_parts" = "parts_sum"."number_of_parts"
FROM (
SELECT
"parts"."figure",
SUM("parts"."quantity") as "number_of_parts"
FROM (
SELECT
"bricktracker_parts"."figure",
"bricktracker_parts"."quantity"
FROM "bricktracker_parts"
WHERE "bricktracker_parts"."figure" IS NOT NULL
GROUP BY
"bricktracker_parts"."figure",
"bricktracker_parts"."part",
"bricktracker_parts"."color",
"bricktracker_parts"."spare"
) "parts"
GROUP BY "parts"."figure"
) "parts_sum"
WHERE "rebrickable_minifigures"."figure" = "parts_sum"."figure";
COMMIT;

View File

@ -2,6 +2,7 @@ SELECT
"bricktracker_minifigures"."quantity",
"rebrickable_minifigures"."figure",
"rebrickable_minifigures"."number",
"rebrickable_minifigures"."number_of_parts",
"rebrickable_minifigures"."name",
"rebrickable_minifigures"."image",
{% block total_missing %}

View File

@ -2,16 +2,19 @@ INSERT OR IGNORE INTO "rebrickable_minifigures" (
"figure",
"number",
"name",
"image"
"image",
"number_of_parts"
) VALUES (
:figure,
:number,
:name,
:image
:image,
:number_of_parts
)
ON CONFLICT("figure")
DO UPDATE SET
"number" = :number,
"name" = :name,
"image" = :image
"image" = :image,
"number_of_parts" = :number_of_parts
WHERE "rebrickable_minifigures"."figure" IS NOT DISTINCT FROM :figure

View File

@ -1,4 +1,4 @@
from typing import Final
__version__: Final[str] = '1.2.0'
__database_version__: Final[int] = 14
__database_version__: Final[int] = 15

View File

@ -1,4 +1,4 @@
{% macro header(color=false, quantity=false, missing_parts=false, damaged_parts=false, sets=false, minifigures=false) %}
{% macro header(color=false, parts=false, quantity=false, missing_parts=false, damaged_parts=false, sets=false, minifigures=false) %}
<thead>
<tr>
<th data-table-no-sort="true" class="no-sort" scope="col"><i class="ri-image-line fw-normal"></i> Image</th>
@ -6,6 +6,9 @@
{% if color %}
<th scope="col"><i class="ri-palette-line fw-normal"></i> Color</th>
{% endif %}
{% if parts %}
<th data-table-number="true" scope="col"><i class="ri-shapes-line fw-normal"></i> Parts</th>
{% endif %}
{% if quantity %}
<th data-table-number="true" scope="col"><i class="ri-functions fw-normal"></i> Quantity</th>
{% endif %}

View File

@ -6,6 +6,7 @@
{{ card.header(item, item.fields.name, solo=solo, identifier=item.fields.figure, icon='user-line') }}
{{ card.image(item, solo=solo, last=last, caption=item.fields.name, alt=item.fields.figure, medium=true) }}
<div class="card-body border-bottom {% if not solo %}p-1{% endif %}">
{{ badge.parts(item.fields.number_of_parts, solo=solo, last=last) }}
{% if last %}
{{ badge.set(item.fields.set, solo=solo, last=last, id=item.fields.rebrickable_set_id) }}
{{ badge.quantity(item.fields.quantity, solo=solo, last=last) }}

View File

@ -2,7 +2,7 @@
<div class="table-responsive-sm">
<table data-table="{% if all %}true{% endif %}" class="table table-striped align-middle" id="minifigures">
{{ table.header(quantity=true, missing_parts=true, damaged_parts=true, sets=true) }}
{{ table.header(parts=true, quantity=true, missing_parts=true, damaged_parts=true, sets=true) }}
<tbody>
{% for item in table_collection %}
<tr>
@ -13,6 +13,7 @@
{{ table.rebrickable(item) }}
{% endif %}
</td>
<td>{{ item.fields.number_of_parts }}</td>
<td>{{ item.fields.total_quantity }}</td>
<td>{{ item.fields.total_missing }}</td>
<td>{{ item.fields.total_damaged }}</td>