Skip to content

Commit

Permalink
feat: HL 1426 ahjo signer (#3540)
Browse files Browse the repository at this point in the history
* feat: handler api endpoint for querying settings

* chore: seed signer data

* feat: add signer to DecisionText

* feat: save signer to decisionText

* feat: ahjo signer frontend radio inputs

* feat: send signer to Ahjo with decisionProposal

* chore: add missing signer fixture for tests

* test: select signer for ddecision proposal

* chore: add missing validation for signer

* fix: lint file and add check for existing property

---------

Co-authored-by: Sampo Tawast <[email protected]>
  • Loading branch information
rikuke and sirtawast authored Nov 18, 2024
1 parent c6c9a3c commit a4479bf
Show file tree
Hide file tree
Showing 26 changed files with 359 additions and 23 deletions.
15 changes: 15 additions & 0 deletions backend/benefit/applications/api/v1/ahjo_decision_views.py
Original file line number Diff line number Diff line change
Expand Up @@ -187,6 +187,8 @@ def patch(self, request):
name="ahjo_decision_maker"
).data

available_signers = AhjoSetting.objects.get(name="ahjo_signer").data

decision_maker_id = request.data.get("decision_maker_id")
decision_maker = next(
(
Expand All @@ -197,9 +199,18 @@ def patch(self, request):
None,
)

signer_id = request.data.get("signer_id")
signer = next(
(item for item in available_signers if item["ID"] == signer_id),
None,
)

if decision_maker is None:
decision_maker = {"ID": None, "Name": None}

if signer_id is None:
signer = {"ID": None, "Name": None}

if ahjo_text:
ahjo_text.update(
language=application.applicant_language,
Expand All @@ -211,6 +222,8 @@ def patch(self, request):
decision_text=decision_text,
decision_maker_id=decision_maker["ID"],
decision_maker_name=decision_maker["Name"],
signer_id=signer["ID"],
signer_name=signer["Name"],
)
else:
AhjoDecisionText.objects.create(
Expand All @@ -224,6 +237,8 @@ def patch(self, request):
decision_text=decision_text,
decision_maker_id=decision_maker["ID"],
decision_maker_name=decision_maker["Name"],
signer_id=signer["ID"],
signer_name=signer["Name"],
)

if data["review_step"] >= 4:
Expand Down
3 changes: 2 additions & 1 deletion backend/benefit/applications/api/v1/ahjo_setting_views.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ class AhjoSettingDetailView(generics.RetrieveAPIView):
serializer_class = AhjoSettingSerializer

def get_object(self):
name = self.kwargs.get("name")
queryset = AhjoSetting.objects.all()
setting = get_object_or_404(queryset, name="ahjo_decision_maker")
setting = get_object_or_404(queryset, name=name)
return setting
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@ class Meta:
"log_entry_comment",
"decision_maker_id",
"decision_maker_name",
"signer_id",
"signer_name",
]


Expand All @@ -36,6 +38,8 @@ class Meta:
"log_entry_comment",
"decision_maker_id",
"decision_maker_name",
"signer_id",
"signer_name",
]

def validate(self, data):
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,14 @@ def validate(self, data):
if not decision_maker_id:
errors["decision_maker_id"] = "This field is required."

signer_name = data.get("signer_name")
if not signer_name:
errors["signer_name"] = "This field is required."

signer_id = data.get("signer_id")
if not signer_id:
errors["signer_id"] = "This field is required."

if errors:
raise serializers.ValidationError(errors)
return data
13 changes: 13 additions & 0 deletions backend/benefit/applications/fixtures/test_ahjo_settings.json
Original file line number Diff line number Diff line change
Expand Up @@ -51,5 +51,18 @@
{ "ID": "HIJKLMNOPQRSTUWXYZ", "Name": "Helsinki-lisä-suunnittelija" }
]
}
},
{
"model": "applications.ahjosetting",
"pk": 5,
"fields": {
"created_at": "2024-11-10T12:57:07.855Z",
"modified_at": "2024-11-10T12:57:07.855Z",
"name": "ahjo_signer",
"data": [
{ "ID": "ABCDEFGH12345678", "Name": "Testaaja, Timo" },
{ "ID": "ABCDEFGH87654321", "Name": "Testaaja, Tiina" }
]
}
}
]
13 changes: 13 additions & 0 deletions backend/benefit/applications/management/commands/seed.py
Original file line number Diff line number Diff line change
Expand Up @@ -265,3 +265,16 @@ def _create_dummy_ahjo_settings():
{"ID": "HIJKLMNOPQRSTUWXYZ", "Name": "Helsinki-lisä-suunnittelija"},
],
)
AhjoSetting.objects.create(
name="ahjo_signer",
data=[
{
"ID": "ABCDEFGH12345678",
"Name": "Testaaja, Timo",
},
{
"ID": "ABCDEFGH87654321",
"Name": "Testaaja, Tiina",
},
],
)
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
# Generated by Django 4.2.11 on 2024-11-11 12:39

from django.db import migrations, models


class Migration(migrations.Migration):
dependencies = [
("applications", "0087_alter_ahjodecisionproposaldraft_handler_role"),
]

operations = [
migrations.AddField(
model_name="ahjodecisiontext",
name="signer_id",
field=models.CharField(
blank=True,
max_length=64,
null=True,
verbose_name="the ID of the signer",
),
),
migrations.AddField(
model_name="ahjodecisiontext",
name="signer_name",
field=models.TextField(
blank=True, null=True, verbose_name="the name of the signer"
),
),
]
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
# Generated by Django 4.2.11 on 2024-11-13 08:21

from django.db import migrations, models


class Migration(migrations.Migration):
dependencies = [
("applications", "0088_ahjodecisiontext_signer_id_and_more"),
]

operations = [
migrations.AddField(
model_name="ahjodecisionproposaldraft",
name="signer_id",
field=models.CharField(
blank=True,
max_length=64,
null=True,
verbose_name="the ID of the signer",
),
),
migrations.AddField(
model_name="ahjodecisionproposaldraft",
name="signer_name",
field=models.TextField(
blank=True, null=True, verbose_name="the name of the signer"
),
),
]
26 changes: 26 additions & 0 deletions backend/benefit/applications/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -1337,6 +1337,19 @@ class AhjoDecisionText(UUIDModel, TimeStampedModel):
max_length=64,
)

signer_name = models.TextField(
verbose_name=_("the name of the signer"),
null=True,
blank=True,
)

signer_id = models.CharField(
verbose_name=_("the ID of the signer"),
null=True,
blank=True,
max_length=64,
)

def __str__(self):
return (
"Ahjo decision text for application %s"
Expand Down Expand Up @@ -1559,6 +1572,19 @@ class Meta:
max_length=64,
)

signer_name = models.TextField(
verbose_name=_("the name of the signer"),
null=True,
blank=True,
)

signer_id = models.CharField(
verbose_name=_("the ID of the signer"),
null=True,
blank=True,
max_length=64,
)


class ArchivalApplication(UUIDModel, TimeStampedModel):
class Meta:
Expand Down
7 changes: 7 additions & 0 deletions backend/benefit/applications/services/ahjo_payload.py
Original file line number Diff line number Diff line change
Expand Up @@ -477,6 +477,12 @@ def prepare_decision_proposal_payload(
"ID": handler.ad_username,
}

signer_dict = {
"Role": "signer",
"Name": decision_text.signer_name,
"ID": decision_text.signer_id,
}

proposal_dict = {
"records": [
{
Expand All @@ -489,6 +495,7 @@ def prepare_decision_proposal_payload(
"Agents": [
main_creator_dict,
decision_maker_dict,
signer_dict,
],
},
{
Expand Down
22 changes: 22 additions & 0 deletions backend/benefit/applications/tests/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -1105,6 +1105,20 @@ def fake_decisionmakers():
]


@pytest.fixture
def fake_signers():
return [
{
"ID": "ABCDEFGH12345678",
"Name": "Testaaja, Timo",
},
{
"ID": "HIJKLMNOPQRSTUWXYZ",
"Name": "Testaaja, Tiina",
},
]


@pytest.fixture
def decision_maker_settings(fake_decisionmakers):
return AhjoSetting.objects.create(
Expand All @@ -1113,6 +1127,14 @@ def decision_maker_settings(fake_decisionmakers):
)


@pytest.fixture
def signer_settings(fake_signers):
return AhjoSetting.objects.create(
name="ahjo_signer",
data=fake_signers,
)


@pytest.fixture
def non_expired_token():
return AhjoToken(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,8 @@ def test_decision_proposal_drafting(
justification_text,
fake_decisionmakers,
decision_maker_settings,
fake_signers,
signer_settings,
):
if review_step == 4:
_prepare_calculation(application=application)
Expand All @@ -137,6 +139,8 @@ def test_decision_proposal_drafting(
"justification_text": justification_text,
"decision_maker_id": fake_decisionmakers[0]["ID"],
"decision_maker_name": fake_decisionmakers[0]["Name"],
"signer_id": fake_signers[0]["ID"],
"signer_name": fake_signers[0]["Name"],
},
)
assert response.status_code == response_status
Expand All @@ -151,3 +155,5 @@ def test_decision_proposal_drafting(

assert final_ahjo_text.decision_maker_id == fake_decisionmakers[0]["ID"]
assert final_ahjo_text.decision_maker_name == fake_decisionmakers[0]["Name"]
assert final_ahjo_text.signer_id == fake_signers[0]["ID"]
assert final_ahjo_text.signer_name == fake_signers[0]["Name"]
11 changes: 10 additions & 1 deletion backend/benefit/applications/tests/test_ahjo_decisions.py
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,7 @@ def test_decision_text_api_post(
language,
fake_decisionmakers,
status_code,
fake_signers,
):
url = get_decisions_list_url(decided_application.id)
data = {
Expand All @@ -115,6 +116,8 @@ def test_decision_text_api_post(
"language": language,
"decision_maker_id": fake_decisionmakers[0]["ID"],
"decision_maker_name": fake_decisionmakers[0]["Name"],
"signer_id": fake_signers[0]["ID"],
"signer_name": fake_signers[0]["Name"],
}
response = handler_api_client.post(url, data)
assert response.status_code == status_code
Expand Down Expand Up @@ -226,7 +229,7 @@ def test_decision_text_api_get(decided_application, handler_api_client):


def test_decision_text_api_put(
decided_application, handler_api_client, fake_decisionmakers
decided_application, handler_api_client, fake_decisionmakers, fake_signers
):
decision_text = AhjoDecisionText.objects.create(
application=decided_application,
Expand All @@ -235,6 +238,8 @@ def test_decision_text_api_put(
language="fi",
decision_maker_id=fake_decisionmakers[0]["ID"],
decision_maker_name=fake_decisionmakers[0]["Name"],
signer_id=fake_signers[0]["ID"],
signer_name=fake_signers[0]["Name"],
)
url = get_decisions_detail_url(decided_application.id, decision_text.id)
data = {
Expand All @@ -243,6 +248,8 @@ def test_decision_text_api_put(
"language": "sv",
"decision_maker_id": fake_decisionmakers[1]["ID"],
"decision_maker_name": fake_decisionmakers[1]["Name"],
"signer_id": fake_signers[1]["ID"],
"signer_name": fake_signers[1]["Name"],
}
response = handler_api_client.put(url, data)
assert response.status_code == 200
Expand All @@ -252,6 +259,8 @@ def test_decision_text_api_put(
assert decision_text.decision_text == data["decision_text"]
assert decision_text.decision_maker_id == data["decision_maker_id"]
assert decision_text.decision_maker_name == data["decision_maker_name"]
assert decision_text.signer_id == data["signer_id"]
assert decision_text.signer_name == data["signer_name"]


def test_parse_details_from_decision_response(
Expand Down
5 changes: 5 additions & 0 deletions backend/benefit/applications/tests/test_ahjo_payload.py
Original file line number Diff line number Diff line change
Expand Up @@ -478,6 +478,11 @@ def test_prepare_decision_proposal_payload(application_with_ahjo_decision):
"Role": "decisionMaker",
"ID": decision.decision_maker_id,
},
{
"Role": "signer",
"ID": decision.signer_id,
"Name": decision.signer_name,
},
],
},
{
Expand Down
Loading

0 comments on commit a4479bf

Please sign in to comment.