Fix spool weight tracking when auto-archive is disabled (#839)

When auto-archive was off, archive_id was None at print completion so
  the entire 3MF tracking path was skipped. AMS remain% fallback also
  failed on printers reporting remain=-1. Now searches library files and
  previous archives by filename to locate the 3MF without an archive,
  and captures the AMS slot-to-tray mapping at print start so it's
  available at completion regardless of archive state.
This commit is contained in:
maziggy
2026-04-07 08:31:14 +02:00
parent af8f7a01d9
commit 4df0349310
5 changed files with 370 additions and 30 deletions
@@ -143,9 +143,12 @@ class TestOnPrintCompleteAMSDelta:
assignment = _make_assignment()
db = AsyncMock()
# First execute → assignment, second → spool
# First 2 executes → _find_3mf_by_filename (library + archive search, uses scalars().all()),
# then assignment, then spool for the AMS fallback path
db.execute = AsyncMock(
side_effect=[
MagicMock(), # _find_3mf_by_filename: library search
MagicMock(), # _find_3mf_by_filename: archive search
MagicMock(scalar_one_or_none=MagicMock(return_value=assignment)),
MagicMock(scalar_one_or_none=MagicMock(return_value=spool)),
]
@@ -571,11 +574,14 @@ class TestSpoolAssignmentSnapshot:
ams_data = [{"id": 0, "tray": [{"id": 0, "remain": 70}]}]
pm = _make_printer_manager(_make_printer_state(ams_data))
# db returns no live assignment, then spool from snapshot spool_id
# First 2 executes → _find_3mf_by_filename (library + archive search),
# then live assignment check (returns None), then spool lookup by snapshot spool_id
db = AsyncMock()
db.execute = AsyncMock(
side_effect=[
MagicMock(scalar_one_or_none=MagicMock(return_value=None)),
MagicMock(), # _find_3mf_by_filename: library search
MagicMock(), # _find_3mf_by_filename: archive search
MagicMock(scalar_one_or_none=MagicMock(return_value=None)), # live assignment
MagicMock(scalar_one_or_none=MagicMock(return_value=spool)),
]
)
@@ -609,10 +615,13 @@ class TestSpoolAssignmentSnapshot:
ams_data = [{"id": 0, "tray": [{"id": 0, "remain": 70}]}]
pm = _make_printer_manager(_make_printer_state(ams_data))
# db returns assignment then spool
# First 2 executes → _find_3mf_by_filename (library + archive search),
# then assignment and spool for the AMS fallback path
db = AsyncMock()
db.execute = AsyncMock(
side_effect=[
MagicMock(), # _find_3mf_by_filename: library search
MagicMock(), # _find_3mf_by_filename: archive search
MagicMock(scalar_one_or_none=MagicMock(return_value=assignment)),
MagicMock(scalar_one_or_none=MagicMock(return_value=spool)),
]