Match a location job's trays on the printer it gets (#3239)

A job kept the AMS mapping of the printer it was made for. Moved to a
location and picked by another printer, a tray of the same material in
another colour passed the fit check, so the job printed in that colour.
The scheduler now drops a stored mapping when it assigns a job by model
or location and matches the trays on the chosen printer, by type and
colour. Moving a job from a printer to a model or location clears its
mapping and the "Print Anyway" given for that printer.

A printer without an AMS whose external spool has no filament set gave
the matcher nothing to match, so such a job went out without a mapping
and the firmware rejected it with 0700_8012. Every filament now goes to
the external spool there.
This commit is contained in:
maziggy
2026-10-05 11:16:41 +02:00
parent 0054875d18
commit 57dd8651d8
6 changed files with 317 additions and 4 deletions
@@ -2113,6 +2113,38 @@ class TestTargetLocationFeature:
result = response.json()
assert result["target_location"] == "Basement"
@pytest.mark.asyncio
@pytest.mark.integration
async def test_moving_a_job_to_a_location_drops_the_old_printers_mapping(
self, async_client: AsyncClient, queue_item_factory, printer_factory, db_session
):
"""#3239: the tray IDs were resolved against A1-003, and the scheduler may
pick another printer, so they must not travel with the job. Neither does
a "Print Anyway" given for A1-003's trays."""
a1_003 = await printer_factory(model="A1", location="Farm")
item = await queue_item_factory(printer_id=a1_003.id, ams_mapping="[3]", skip_filament_check=True)
# What the edit dialog sends: ams_mapping omitted, not null.
response = await async_client.patch(
f"/api/v1/queue/{item.id}",
json={"printer_id": None, "target_model": "A1", "target_location": "Farm"},
)
assert response.status_code == 200
result = response.json()
assert result["ams_mapping"] is None
assert result["skip_filament_check"] is False
@pytest.mark.asyncio
@pytest.mark.integration
async def test_a_job_on_a_printer_keeps_its_mapping(
self, async_client: AsyncClient, queue_item_factory, db_session
):
item = await queue_item_factory(ams_mapping="[3]")
response = await async_client.patch(f"/api/v1/queue/{item.id}", json={"plate_id": 2})
assert response.status_code == 200
assert response.json()["ams_mapping"] == [3]
@pytest.mark.asyncio
@pytest.mark.integration
async def test_clear_target_location(self, async_client: AsyncClient, queue_item_factory, db_session):