From 30a13644cef111024f3035616a1c35fb2a2a0309 Mon Sep 17 00:00:00 2001 From: Ian Roddis <31021769+iroddis@users.noreply.github.com> Date: Fri, 31 Jul 2026 09:02:24 -0300 Subject: [PATCH] Adding fit note at manual fit creation --- app/templates/admin/_augmented_part_fits.html | 3 + app/web/admin.py | 4 + tests/test_augmented_part_detail.py | 76 ++++++++++++++++++- 3 files changed, 82 insertions(+), 1 deletion(-) diff --git a/app/templates/admin/_augmented_part_fits.html b/app/templates/admin/_augmented_part_fits.html index c5c870a..5c20fbd 100644 --- a/app/templates/admin/_augmented_part_fits.html +++ b/app/templates/admin/_augmented_part_fits.html @@ -52,6 +52,9 @@ + {% endif %} diff --git a/app/web/admin.py b/app/web/admin.py index a5daca5..0785630 100644 --- a/app/web/admin.py +++ b/app/web/admin.py @@ -2271,6 +2271,7 @@ async def create_augmented_part_fit( other_augmented_part_id: str = Form(""), other_attachment_point_id: str = Form(""), label: FitLabel = Form(FitLabel.EXACT), + note: str = Form(""), db: AsyncSession = Depends(get_db), actor: User = Depends(web_require("fits:write")), ): @@ -2335,6 +2336,9 @@ async def create_augmented_part_fit( "Fit", fit.id, f"attachment points {ap_a.id}↔{ap_b.id} ({label.value})" ), ) + if note.strip(): + await fit_note_crud.create(db, fit=fit, author=actor, body=note.strip()) + await db.refresh(fit, attribute_names=["notes"]) ctx = await _augmented_part_fits_ctx( db, augmented_part_id, can_write=_can_write_fits(actor), error=error ) diff --git a/tests/test_augmented_part_detail.py b/tests/test_augmented_part_detail.py index f958711..c4c227e 100644 --- a/tests/test_augmented_part_detail.py +++ b/tests/test_augmented_part_detail.py @@ -4,7 +4,7 @@ from app.crud import role as role_crud from app.models.attachment_point import AttachmentPoint from app.models.attachment_point_name import AttachmentPointName from app.models.augmented_part import AugmentedPart -from app.models.fit import Fit, FitLabel +from app.models.fit import Fit, FitLabel, FitNote from app.models.iso_thread import IsoThread from app.models.part_type import PartType from app.models.scope_info import ScopeInfo @@ -236,6 +236,80 @@ async def test_create_fit_auto_creates_matching_attachment_point( assert fits[0].label == FitLabel.POSSIBLE +@pytest.mark.asyncio +async def test_create_fit_with_note_creates_fit_note( + client, seeded, make_user, db_sessionmaker +): + async with db_sessionmaker() as db: + apn = AttachmentPointName(name="Objective") + scope_t = PartType(name="Scope") + cover_t = PartType(name="Flip Cover") + db.add_all([apn, scope_t, cover_t]) + await db.flush() + + scope = AugmentedPart( + description="Alpha 3-18x50", + sku="ALP-318", + colour_id=1, + manufacturer_id=1, + part_type_id=scope_t.id, + ) + cover = AugmentedPart( + description="Flip cover 50mm", + colour_id=1, + manufacturer_id=1, + part_type_id=cover_t.id, + ) + db.add_all([scope, cover]) + await db.flush() + + own_ap = AttachmentPoint( + augmented_part_id=scope.id, attachment_point_name_id=apn.id + ) + other_ap = AttachmentPoint( + augmented_part_id=cover.id, attachment_point_name_id=apn.id + ) + db.add_all([own_ap, other_ap]) + await db.commit() + + scope_id, own_ap_id, other_ap_id = scope.id, own_ap.id, other_ap.id + + perms = seeded["perms"] + editor = await role_crud.create( + db, + name="fit-editor3", + permission_ids=[ + perms["augmented_parts:read"].id, + perms["fits:read"].id, + perms["fits:write"].id, + ], + ) + editor_id = editor.id + await make_user("editor3@example.com", role_ids=[editor_id]) + await _web_login(client, "editor3@example.com") + + resp = await client.post( + f"/admin/augmented-parts/{scope_id}/fits", + data={ + "own_attachment_point_id": own_ap_id, + "other_attachment_point_id": other_ap_id, + "label": "exact", + "note": "Confirmed fit on the bench.", + }, + ) + assert resp.status_code == 200 + body = resp.text + assert "Confirmed fit on the bench." in body + + async with db_sessionmaker() as db: + fits = (await db.execute(Fit.__table__.select())).all() + assert len(fits) == 1 + notes = (await db.execute(FitNote.__table__.select())).all() + assert len(notes) == 1 + assert notes[0].fit_id == fits[0].id + assert notes[0].body == "Confirmed fit on the bench." + + @pytest.mark.asyncio async def test_detail_404_for_missing_part(client, seeded, make_user): await make_user("reader2@example.com", role_ids=[seeded["roles"]["user"].id])