import pytest from tests.conftest import auth_header, login async def _fehlbestand(client, token, objekt, material, istmenge: str, abschliessen=True): start = await client.post( f"/api/v1/objekte/{objekt.id}/kontrollen", json={"uebernehmen": False}, headers=auth_header(token) ) kontrolle_id = start.json()["id"] put_response = await client.put( f"/api/v1/kontrollen/{kontrolle_id}/positionen/{material.id}", json={"istmenge": istmenge}, headers=auth_header(token), ) if abschliessen: await client.post(f"/api/v1/kontrollen/{kontrolle_id}/abschliessen", headers=auth_header(token)) return put_response.json()["fehlbestand_id"] @pytest.mark.asyncio async def test_offene_stati_werden_gemeinsam_gezaehlt( client, objekt_mit_position, mitarbeiter_user, materialverantwortlicher_user ): """Prompt 12.2: offen + in_bearbeitung + nachgefuellt_teilweise = "offen".""" objekt, material = objekt_mit_position mitarbeiter_token = await login(client, "mitarbeiter1") fehlbestand_id = await _fehlbestand(client, mitarbeiter_token, objekt, material, "6") # Teilnachfüllung -> Status nachgefuellt_teilweise, zählt trotzdem als offen await client.post( f"/api/v1/fehlbestaende/{fehlbestand_id}/nachfuellungen", json={"menge": "1"}, headers=auth_header(mitarbeiter_token), ) verantwortlicher_token = await login(client, "materialverantwortlicher1") response = await client.get("/api/v1/dashboard/kennzahlen", headers=auth_header(verantwortlicher_token)) assert response.status_code == 200 assert response.json()["anzahl_offener_fehlbestaende"] == 1 @pytest.mark.asyncio async def test_genehmigte_mindermenge_zaehlt_als_offen_und_separat( client, objekt_mit_position, mitarbeiter_user, materialverantwortlicher_user ): objekt, material = objekt_mit_position mitarbeiter_token = await login(client, "mitarbeiter1") fehlbestand_id = await _fehlbestand(client, mitarbeiter_token, objekt, material, "6") verantwortlicher_token = await login(client, "materialverantwortlicher1") await client.post( f"/api/v1/fehlbestaende/{fehlbestand_id}/mindermenge", json={"begruendung": "Lieferengpass"}, headers=auth_header(verantwortlicher_token), ) response = await client.get("/api/v1/dashboard/kennzahlen", headers=auth_header(verantwortlicher_token)) body = response.json() assert body["anzahl_genehmigter_mindermengen"] == 1 assert body["anzahl_offener_fehlbestaende"] == 1 # Genehmigung ist keine Erledigung @pytest.mark.asyncio async def test_kuerzlich_erledigt_wird_gezaehlt( client, objekt_mit_position, mitarbeiter_user, materialverantwortlicher_user ): objekt, material = objekt_mit_position mitarbeiter_token = await login(client, "mitarbeiter1") fehlbestand_id = await _fehlbestand(client, mitarbeiter_token, objekt, material, "6") await client.post( f"/api/v1/fehlbestaende/{fehlbestand_id}/nachfuellungen", json={"menge": "4"}, headers=auth_header(mitarbeiter_token), ) verantwortlicher_token = await login(client, "materialverantwortlicher1") response = await client.get("/api/v1/dashboard/kennzahlen", headers=auth_header(verantwortlicher_token)) body = response.json() assert body["anzahl_kuerzlich_erledigter_fehlbestaende"] == 1 assert body["anzahl_offener_fehlbestaende"] == 0 @pytest.mark.asyncio async def test_mitarbeiter_darf_dashboard_nicht_sehen(client, mitarbeiter_user): token = await login(client, "mitarbeiter1") response = await client.get("/api/v1/dashboard/kennzahlen", headers=auth_header(token)) assert response.status_code == 403 @pytest.mark.asyncio async def test_ablaufdaten_liste_sortiert_und_gefiltert( client, db_session, objekt_mit_position, materialverantwortlicher_user ): """Prompt 14: nur bald_ablaufend/abgelaufen, sortiert nach verbleibenden Tagen aufsteigend.""" from datetime import date, timedelta objekt, material = objekt_mit_position verantwortlicher_token = await login(client, "materialverantwortlicher1") positionen = ( await client.get(f"/api/v1/objekte/{objekt.id}/positionen", headers=auth_header(verantwortlicher_token)) ).json() position_id = positionen[0]["id"] # weit in der Zukunft -> "gueltig", darf NICHT in der Liste auftauchen await client.patch( f"/api/v1/objekte/{objekt.id}/positionen/{position_id}", json={"ablaufdatum": (date.today() + timedelta(days=365)).isoformat()}, headers=auth_header(verantwortlicher_token), ) response = await client.get("/api/v1/dashboard/ablaufdaten", headers=auth_header(verantwortlicher_token)) assert response.json() == [] # bald ablaufend (Standard-Warnzeitraum 30 Tage, kein warnzeitraum_tage auf Material gesetzt) await client.patch( f"/api/v1/objekte/{objekt.id}/positionen/{position_id}", json={"ablaufdatum": (date.today() + timedelta(days=5)).isoformat()}, headers=auth_header(verantwortlicher_token), ) response = await client.get("/api/v1/dashboard/ablaufdaten", headers=auth_header(verantwortlicher_token)) body = response.json() assert len(body) == 1 assert body[0]["status"] == "bald_ablaufend" @pytest.mark.asyncio async def test_abgelaufenes_material_wird_als_abgelaufen_markiert( client, objekt_mit_position, materialverantwortlicher_user ): from datetime import date, timedelta objekt, material = objekt_mit_position token = await login(client, "materialverantwortlicher1") positionen = (await client.get(f"/api/v1/objekte/{objekt.id}/positionen", headers=auth_header(token))).json() position_id = positionen[0]["id"] await client.patch( f"/api/v1/objekte/{objekt.id}/positionen/{position_id}", json={"ablaufdatum": (date.today() - timedelta(days=3)).isoformat()}, headers=auth_header(token), ) response = await client.get("/api/v1/dashboard/ablaufdaten", headers=auth_header(token)) body = response.json() assert len(body) == 1 assert body[0]["status"] == "abgelaufen" assert body[0]["verbleibende_tage"] == -3