From bb7916d693182a57b38f38434c7ae67dd157d9b8 Mon Sep 17 00:00:00 2001 From: Sampo Tawast Date: Thu, 7 Nov 2024 11:42:15 +0200 Subject: [PATCH 01/10] fix: decision maker validation for decision proposal --- .../applications/api/v1/serializers/decision_proposal.py | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/backend/benefit/applications/api/v1/serializers/decision_proposal.py b/backend/benefit/applications/api/v1/serializers/decision_proposal.py index ae6f0c9207..41d79a292c 100644 --- a/backend/benefit/applications/api/v1/serializers/decision_proposal.py +++ b/backend/benefit/applications/api/v1/serializers/decision_proposal.py @@ -78,11 +78,8 @@ def validate(self, data): errors.append( ValidationError("Decision or justification texts cannot be empty") ) - if (data.get("handler_role", None)) not in [ - HandlerRole.HANDLER, - HandlerRole.MANAGER, - ]: - errors.append(ValidationError("Handler role must be specified")) + if len(data.get("decision_maker_id", "None")) <= 0: + errors.append(ValidationError("Decision maker id must be specified")) if len(errors) > 0: raise ValidationError(errors) From d4fbbdd8ccb9e80fa23feed2f902545288edac47 Mon Sep 17 00:00:00 2001 From: Sampo Tawast Date: Thu, 7 Nov 2024 11:47:05 +0200 Subject: [PATCH 02/10] refactor: deprecate handler_role from proposals in favor of decision_maker --- .../api/v1/serializers/decision_proposal.py | 4 +--- ...r_ahjodecisionproposaldraft_handler_role.py | 18 ++++++++++++++++++ backend/benefit/applications/models.py | 4 +++- .../services/ahjo_decision_service.py | 4 ++-- 4 files changed, 24 insertions(+), 6 deletions(-) create mode 100644 backend/benefit/applications/migrations/0086_alter_ahjodecisionproposaldraft_handler_role.py diff --git a/backend/benefit/applications/api/v1/serializers/decision_proposal.py b/backend/benefit/applications/api/v1/serializers/decision_proposal.py index 41d79a292c..3fb31deaa4 100644 --- a/backend/benefit/applications/api/v1/serializers/decision_proposal.py +++ b/backend/benefit/applications/api/v1/serializers/decision_proposal.py @@ -1,7 +1,7 @@ from django.core.exceptions import ValidationError from rest_framework import serializers -from applications.enums import ApplicationStatus, HandlerRole +from applications.enums import ApplicationStatus from applications.models import AhjoDecisionProposalDraft @@ -14,7 +14,6 @@ class Meta: "decision_text", "justification_text", "review_step", - "handler_role", "log_entry_comment", "decision_maker_id", "decision_maker_name", @@ -35,7 +34,6 @@ class Meta: "decision_text", "justification_text", "review_step", - "handler_role", "log_entry_comment", "decision_maker_id", "decision_maker_name", diff --git a/backend/benefit/applications/migrations/0086_alter_ahjodecisionproposaldraft_handler_role.py b/backend/benefit/applications/migrations/0086_alter_ahjodecisionproposaldraft_handler_role.py new file mode 100644 index 0000000000..9d8c274a7e --- /dev/null +++ b/backend/benefit/applications/migrations/0086_alter_ahjodecisionproposaldraft_handler_role.py @@ -0,0 +1,18 @@ +# Generated by Django 4.2.11 on 2024-11-07 07:12 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('applications', '0085_alter_ahjostatus_status'), + ] + + operations = [ + migrations.AlterField( + model_name='ahjodecisionproposaldraft', + name='handler_role', + field=models.CharField(blank=True, choices=[('handler', 'Helsinki-benefit handler'), ('manager', 'Team manager')], max_length=64, null=True, verbose_name='Handler role (deprecated, was used before dynamic fetch of decision makers)'), + ), + ] diff --git a/backend/benefit/applications/models.py b/backend/benefit/applications/models.py index aaeffc9aca..a4cdad24fc 100755 --- a/backend/benefit/applications/models.py +++ b/backend/benefit/applications/models.py @@ -1510,7 +1510,9 @@ class Meta: handler_role = models.CharField( max_length=64, - verbose_name=_("Handler role"), + verbose_name=_( + "Handler role (DEPRECATED, was used before dynamic fetch of decision makers)" + ), blank=True, null=True, choices=HandlerRole.choices, diff --git a/backend/benefit/applications/services/ahjo_decision_service.py b/backend/benefit/applications/services/ahjo_decision_service.py index bd28a024b7..9cdc3d6201 100644 --- a/backend/benefit/applications/services/ahjo_decision_service.py +++ b/backend/benefit/applications/services/ahjo_decision_service.py @@ -5,7 +5,7 @@ from django.conf import settings -from applications.enums import AhjoDecisionDetails, DecisionType, HandlerRole +from applications.enums import AhjoDecisionDetails, DecisionType from applications.models import ( AhjoDecisionText, Application, @@ -25,7 +25,7 @@ def replace_decision_template_placeholders( text_to_replace: str, decision_type: DecisionType, application: Application, - decision_maker: HandlerRole = HandlerRole.HANDLER, + decision_maker, ) -> str: """Replace the placeholders starting with $ in the decision template with real data""" text_to_replace = Template(text_to_replace) From c6d3b19fc554cab30c7fe8ed9f0e32e6434c5ba9 Mon Sep 17 00:00:00 2001 From: Sampo Tawast Date: Thu, 7 Nov 2024 11:47:47 +0200 Subject: [PATCH 03/10] refactor: remove unused api view --- .../api/v1/decision_proposal_draft_views.py | 129 ------------------ 1 file changed, 129 deletions(-) delete mode 100755 backend/benefit/applications/api/v1/decision_proposal_draft_views.py diff --git a/backend/benefit/applications/api/v1/decision_proposal_draft_views.py b/backend/benefit/applications/api/v1/decision_proposal_draft_views.py deleted file mode 100755 index 6a0006ee9e..0000000000 --- a/backend/benefit/applications/api/v1/decision_proposal_draft_views.py +++ /dev/null @@ -1,129 +0,0 @@ -from django.db import transaction -from django.shortcuts import get_object_or_404 -from django_filters import rest_framework as filters -from drf_spectacular.utils import extend_schema -from rest_framework import filters as drf_filters, status, viewsets -from rest_framework.decorators import action -from rest_framework.response import Response - -from applications.api.v1.serializers.decision_proposal import ( - AhjoDecisionProposalReadOnlySerializer, - AhjoDecisionProposalSerializer, -) -from applications.enums import ApplicationStatus, DecisionType -from applications.models import AhjoDecisionProposalDraft, AhjoDecisionText, Application -from common.permissions import BFIsHandler - - -class AhjoDecisionProposalDraftFilter(filters.FilterSet): - class Meta: - model = AhjoDecisionProposalDraft - fields = { - "status": ["exact"], - } - - -@extend_schema( - description=( - "API for create/read/update/delete/export operations on Helsinki benefit" - " application batches" - ) -) -class AhjoDecisionProposalDraftViewSet(viewsets.ViewSet): - queryset = AhjoDecisionProposalDraft.objects.all() - serializer_class = AhjoDecisionProposalSerializer - permission_classes = [BFIsHandler] - filter_backends = [ - drf_filters.OrderingFilter, - filters.DjangoFilterBackend, - drf_filters.SearchFilter, - ] - filterset_class = AhjoDecisionProposalDraftFilter - - def get_queryset(self): - order_by = self.request.query_params.get("order_by") or None - - if order_by: - self.queryset = self.queryset.order_by(order_by) - - return self.queryset - - def get_serializer_class(self): - """ - ApplicationBatchSerializer for default behaviour on mutation functions, - ApplicationBatchListSerializer for listing applications on a batch - """ - if self.action in ["create", "update", "partial_update", "destroy"]: - return AhjoDecisionProposalReadOnlySerializer - - return AhjoDecisionProposalSerializer - - @action(methods=["PATCH"], detail=False) - @transaction.atomic - def modify(self, request, pk=None): - """ - Override default destroy(), batch can only be deleted if it's status is "draft" - """ - app_id = request.data["application_id"] - application = get_object_or_404(Application, id=app_id) - - proposal_object = AhjoDecisionProposalDraft.objects.filter( - application=application - ).first() - - proposal = AhjoDecisionProposalSerializer( - proposal_object, data=request.data, partial=True - ) - - if not proposal.is_valid(): - return Response(proposal.errors, status=status.HTTP_400_BAD_REQUEST) - - data = proposal.validated_data - proposal.save() - - if data.get("decision_text") and data.get("justification_text"): - ahjo_text = AhjoDecisionText.objects.filter(application=application) - if ahjo_text: - ahjo_text.update( - language=application.applicant_language, - decision_type=( - DecisionType.ACCEPTED - if data["status"] == ApplicationStatus.ACCEPTED - else DecisionType.DENIED - ), - decision_text=data["decision_text"] - + "\n\n" - + data["justification_text"], - decision_maker_id=data["decision_maker_id"], - decision_maker_name=data["decision_maker_name"], - ) - else: - AhjoDecisionText.objects.create( - application=application, - language=application.applicant_language, - decision_type=( - DecisionType.ACCEPTED - if data["status"] == ApplicationStatus.ACCEPTED - else DecisionType.DENIED - ), - decision_text=data["decision_text"] - + "\n\n" - + data["justification_text"], - decision_maker_id=data["decision_maker_id"], - decision_maker_name=data["decision_maker_name"], - ) - - if data["review_step"] >= 4: - # Ensure GUI has a page that exists - proposal.review_step = 3 - proposal.save() - - application.status = data["status"] - application.save() - - application.calculation.granted_as_de_minimis_aid = data[ - "granted_as_de_minimis_aid" - ] - application.calculation.save() - - return Response(proposal.data, status=status.HTTP_200_OK) From 622a291ab192acee703f8a280fd26a7647d2a299 Mon Sep 17 00:00:00 2001 From: Sampo Tawast Date: Thu, 7 Nov 2024 11:52:51 +0200 Subject: [PATCH 04/10] fix: rather than trusting frontend on input, fetch the decision maker from backend using id --- .../api/v1/ahjo_decision_views.py | 26 ++++++++++++++++--- .../api/v1/serializers/decision_proposal.py | 7 +++-- .../services/ahjo_decision_service.py | 2 +- 3 files changed, 26 insertions(+), 9 deletions(-) diff --git a/backend/benefit/applications/api/v1/ahjo_decision_views.py b/backend/benefit/applications/api/v1/ahjo_decision_views.py index 5c93841f96..f2f1b8dbd3 100644 --- a/backend/benefit/applications/api/v1/ahjo_decision_views.py +++ b/backend/benefit/applications/api/v1/ahjo_decision_views.py @@ -18,6 +18,7 @@ from applications.models import ( AhjoDecisionProposalDraft, AhjoDecisionText, + AhjoSetting, Application, ApplicationLogEntry, DecisionProposalTemplateSection, @@ -182,6 +183,23 @@ def patch(self, request): decision_text = f'

{_("Päätös")}

{decision_part}
\

{_("Päätöksen perustelut")}

{justification_part}
' + available_decision_makers = AhjoSetting.objects.get( + name="ahjo_decision_maker" + ).data + + decision_maker_id = request.data.get("decision_maker_id") + decision_maker = next( + ( + item + for item in available_decision_makers + if item["ID"] == decision_maker_id + ), + None, + ) + + if decision_maker is None: + decision_maker = {"ID": None, "Name": None} + if ahjo_text: ahjo_text.update( language=application.applicant_language, @@ -191,8 +209,8 @@ def patch(self, request): else DecisionType.DENIED ), decision_text=decision_text, - decision_maker_id=data.get("decision_maker_id"), - decision_maker_name=data.get("decision_maker_name"), + decision_maker_id=decision_maker["ID"], + decision_maker_name=decision_maker["Name"], ) else: AhjoDecisionText.objects.create( @@ -204,8 +222,8 @@ def patch(self, request): else DecisionType.DENIED ), decision_text=decision_text, - decision_maker_id=data.get("decision_maker_id"), - decision_maker_name=data.get("decision_maker_name"), + decision_maker_id=decision_maker["ID"], + decision_maker_name=decision_maker["Name"], ) if data["review_step"] >= 4: diff --git a/backend/benefit/applications/api/v1/serializers/decision_proposal.py b/backend/benefit/applications/api/v1/serializers/decision_proposal.py index 3fb31deaa4..4748fa783e 100644 --- a/backend/benefit/applications/api/v1/serializers/decision_proposal.py +++ b/backend/benefit/applications/api/v1/serializers/decision_proposal.py @@ -6,6 +6,8 @@ class AhjoDecisionProposalReadOnlySerializer(serializers.ModelSerializer): + """Used to get the draft listed in Application serializer""" + class Meta: model = AhjoDecisionProposalDraft fields = [ @@ -21,10 +23,7 @@ class Meta: class AhjoDecisionProposalSerializer(serializers.ModelSerializer): - """ - # TODO: Add description - - """ + """Used for manipulating the decision proposal draft on PATCH requests""" class Meta: model = AhjoDecisionProposalDraft diff --git a/backend/benefit/applications/services/ahjo_decision_service.py b/backend/benefit/applications/services/ahjo_decision_service.py index 9cdc3d6201..6cf3385a8b 100644 --- a/backend/benefit/applications/services/ahjo_decision_service.py +++ b/backend/benefit/applications/services/ahjo_decision_service.py @@ -25,7 +25,7 @@ def replace_decision_template_placeholders( text_to_replace: str, decision_type: DecisionType, application: Application, - decision_maker, + decision_maker=None, ) -> str: """Replace the placeholders starting with $ in the decision template with real data""" text_to_replace = Template(text_to_replace) From 8fa8d68773d6eb3c60cdd2a33ee4ed573a56ad50 Mon Sep 17 00:00:00 2001 From: Sampo Tawast Date: Thu, 7 Nov 2024 12:48:08 +0200 Subject: [PATCH 05/10] chore: update translations --- frontend/benefit/handler/public/locales/en/common.json | 5 +++-- frontend/benefit/handler/public/locales/fi/common.json | 5 +++-- frontend/benefit/handler/public/locales/sv/common.json | 5 +++-- 3 files changed, 9 insertions(+), 6 deletions(-) diff --git a/frontend/benefit/handler/public/locales/en/common.json b/frontend/benefit/handler/public/locales/en/common.json index 66affecac7..69fc666ea3 100644 --- a/frontend/benefit/handler/public/locales/en/common.json +++ b/frontend/benefit/handler/public/locales/en/common.json @@ -1197,7 +1197,7 @@ "calculation": "Tarkista laskelma", "status": "Puoltotieto puuttuu", "logEntry": "Päätöksen perustelu puuttuu", - "handler": "Päättäjän rooli puuttuu", + "decisionMakerId": "Päättäjän rooli puuttuu", "decisionText": "Päätös ei voi olla tyhjä", "justificationText": "Päätöksen perustelu ei voi olla tyhjä" } @@ -1216,7 +1216,8 @@ "employerName": "Hakija", "employeeName": "Työllistettävä", "totalAmount": "Myönnettävä tuki yhteensä", - "grantedAsDeMinimisAid": "Myönnetään de minimis -tukena" + "grantedAsDeMinimisAid": "Myönnetään de minimis -tukena", + "decisionMaker": "Päättäjän rooli" }, "calculationReview": { "tableCaption": "Tukijaksot", diff --git a/frontend/benefit/handler/public/locales/fi/common.json b/frontend/benefit/handler/public/locales/fi/common.json index c0fc8382a9..2cd53a2f24 100644 --- a/frontend/benefit/handler/public/locales/fi/common.json +++ b/frontend/benefit/handler/public/locales/fi/common.json @@ -1197,7 +1197,7 @@ "calculation": "Tarkista laskelma", "status": "Puoltotieto puuttuu", "logEntry": "Päätöksen perustelu puuttuu", - "handler": "Päättäjän rooli puuttuu", + "decisionMakerId": "Päättäjän rooli puuttuu", "decisionText": "Päätös ei voi olla tyhjä", "justificationText": "Päätöksen perustelu ei voi olla tyhjä" } @@ -1216,7 +1216,8 @@ "employerName": "Hakija", "employeeName": "Työllistettävä", "totalAmount": "Myönnettävä tuki yhteensä", - "grantedAsDeMinimisAid": "Myönnetään de minimis -tukena" + "grantedAsDeMinimisAid": "Myönnetään de minimis -tukena", + "decisionMaker": "Päättäjän rooli" }, "calculationReview": { "tableCaption": "Tukijaksot", diff --git a/frontend/benefit/handler/public/locales/sv/common.json b/frontend/benefit/handler/public/locales/sv/common.json index 66affecac7..69fc666ea3 100644 --- a/frontend/benefit/handler/public/locales/sv/common.json +++ b/frontend/benefit/handler/public/locales/sv/common.json @@ -1197,7 +1197,7 @@ "calculation": "Tarkista laskelma", "status": "Puoltotieto puuttuu", "logEntry": "Päätöksen perustelu puuttuu", - "handler": "Päättäjän rooli puuttuu", + "decisionMakerId": "Päättäjän rooli puuttuu", "decisionText": "Päätös ei voi olla tyhjä", "justificationText": "Päätöksen perustelu ei voi olla tyhjä" } @@ -1216,7 +1216,8 @@ "employerName": "Hakija", "employeeName": "Työllistettävä", "totalAmount": "Myönnettävä tuki yhteensä", - "grantedAsDeMinimisAid": "Myönnetään de minimis -tukena" + "grantedAsDeMinimisAid": "Myönnetään de minimis -tukena", + "decisionMaker": "Päättäjän rooli" }, "calculationReview": { "tableCaption": "Tukijaksot", From 5fbc386367360dcdbcec4b4bd541b176b27731b5 Mon Sep 17 00:00:00 2001 From: Sampo Tawast Date: Thu, 7 Nov 2024 12:50:29 +0200 Subject: [PATCH 06/10] fix: deprecate handlerRole from frontend --- .../HandlingApplicationActionsAhjo.tsx | 5 ----- .../applicationProcessingView/ApplicationProcessingView.tsx | 1 - .../applicationReview/handlingView/HandlingStep2.tsx | 5 +++-- frontend/benefit/handler/src/types/application.d.ts | 1 - frontend/benefit/shared/src/types/application.d.ts | 5 ++--- 5 files changed, 5 insertions(+), 12 deletions(-) diff --git a/frontend/benefit/handler/src/components/applicationReview/actions/handlingApplicationActions/HandlingApplicationActionsAhjo.tsx b/frontend/benefit/handler/src/components/applicationReview/actions/handlingApplicationActions/HandlingApplicationActionsAhjo.tsx index 5773f78926..44f5f3e5da 100644 --- a/frontend/benefit/handler/src/components/applicationReview/actions/handlingApplicationActions/HandlingApplicationActionsAhjo.tsx +++ b/frontend/benefit/handler/src/components/applicationReview/actions/handlingApplicationActions/HandlingApplicationActionsAhjo.tsx @@ -175,7 +175,6 @@ const HandlingApplicationActions: React.FC = ({ logEntry: handledApplication?.logEntryComment?.length <= 0 && handledApplication?.status === APPLICATION_STATUSES.REJECTED, - handler: false, // Use longer length to take HTML tags into account decisionText: handledApplication?.decisionText?.length <= 10, justificationText: handledApplication?.justificationText?.length <= 10, @@ -184,7 +183,6 @@ const HandlingApplicationActions: React.FC = ({ status: '#proccessRejectedRadio', calculation: '#endDate', logEntry: '#proccessRejectedRadio', - handler: '#radio-decision-maker-handler', decisionText: '[data-testid="decisionText"]', justificationText: '[data-testid="justificationText"]', }, @@ -197,9 +195,6 @@ const HandlingApplicationActions: React.FC = ({ let errorStep2 = false; if (currentStepIndex > 0) { - fields.missing.handler = !['handler', 'manager'].includes( - handledApplication?.handlerRole - ); errorStep2 = fields.missing.decisionText || diff --git a/frontend/benefit/handler/src/components/applicationReview/applicationProcessingView/ApplicationProcessingView.tsx b/frontend/benefit/handler/src/components/applicationReview/applicationProcessingView/ApplicationProcessingView.tsx index 7a27321c46..1918c858cc 100644 --- a/frontend/benefit/handler/src/components/applicationReview/applicationProcessingView/ApplicationProcessingView.tsx +++ b/frontend/benefit/handler/src/components/applicationReview/applicationProcessingView/ApplicationProcessingView.tsx @@ -52,7 +52,6 @@ const ApplicationProcessingView: React.FC<{ data: Application }> = ({ grantedAsDeMinimisAid: !!data?.decisionProposalDraft?.grantedAsDeMinimisAid, logEntryComment: data?.decisionProposalDraft?.logEntryComment, - handlerRole: data?.decisionProposalDraft?.handlerRole, justificationText: data?.decisionProposalDraft?.justificationText, decisionText: data?.decisionProposalDraft?.decisionText, }); diff --git a/frontend/benefit/handler/src/components/applicationReview/handlingView/HandlingStep2.tsx b/frontend/benefit/handler/src/components/applicationReview/handlingView/HandlingStep2.tsx index aadad7f35d..38b112fc2c 100644 --- a/frontend/benefit/handler/src/components/applicationReview/handlingView/HandlingStep2.tsx +++ b/frontend/benefit/handler/src/components/applicationReview/handlingView/HandlingStep2.tsx @@ -165,7 +165,8 @@ const ApplicationReviewStep2: React.FC = ({ setHandledApplication({ ...handledApplication, - handlerRole: 'handler', + decisionMakerId: option.id, + decisionMakerName: option.name, decisionText: replaceDecisionTemplatePlaceholders( handledApplication?.decisionText || '', option.name @@ -182,7 +183,7 @@ const ApplicationReviewStep2: React.FC = ({ - {handledApplication?.handlerRole && ( + {selectedDecisionMaker?.id && ( <$ReviewGrid bgColor={theme.colors.silverLight}> <$GridCell $colSpan={12}> Date: Thu, 7 Nov 2024 13:03:35 +0200 Subject: [PATCH 07/10] fix: select decision maker if previously chosen and display it in review box --- .../applicationReview/CalculationReview.tsx | 7 ++++++ .../HandlingApplicationActionsAhjo.tsx | 9 ++++++- .../handlingView/HandlingStep2.tsx | 24 ++++++++++++++++--- 3 files changed, 36 insertions(+), 4 deletions(-) diff --git a/frontend/benefit/handler/src/components/applicationReview/CalculationReview.tsx b/frontend/benefit/handler/src/components/applicationReview/CalculationReview.tsx index 12f9e5f857..cec29256d1 100644 --- a/frontend/benefit/handler/src/components/applicationReview/CalculationReview.tsx +++ b/frontend/benefit/handler/src/components/applicationReview/CalculationReview.tsx @@ -109,6 +109,13 @@ const CalculationReview: React.FC = ({ )} +
+
{t('common:review.decisionProposal.list.decisionMaker')}
+
+ {handledApplication.decisionMakerName || + decisionProposalDraft.decisionMakerName} +
+
{handledApplication.status === APPLICATION_STATUSES.ACCEPTED && ( diff --git a/frontend/benefit/handler/src/components/applicationReview/actions/handlingApplicationActions/HandlingApplicationActionsAhjo.tsx b/frontend/benefit/handler/src/components/applicationReview/actions/handlingApplicationActions/HandlingApplicationActionsAhjo.tsx index 44f5f3e5da..9f959a69af 100644 --- a/frontend/benefit/handler/src/components/applicationReview/actions/handlingApplicationActions/HandlingApplicationActionsAhjo.tsx +++ b/frontend/benefit/handler/src/components/applicationReview/actions/handlingApplicationActions/HandlingApplicationActionsAhjo.tsx @@ -175,6 +175,9 @@ const HandlingApplicationActions: React.FC = ({ logEntry: handledApplication?.logEntryComment?.length <= 0 && handledApplication?.status === APPLICATION_STATUSES.REJECTED, + decisionMakerId: + !handledApplication?.decisionMakerId || + handledApplication?.decisionMakerId?.length <= 0, // Use longer length to take HTML tags into account decisionText: handledApplication?.decisionText?.length <= 10, justificationText: handledApplication?.justificationText?.length <= 10, @@ -183,6 +186,7 @@ const HandlingApplicationActions: React.FC = ({ status: '#proccessRejectedRadio', calculation: '#endDate', logEntry: '#proccessRejectedRadio', + decisionMakerId: '#radio-decision-maker-0', decisionText: '[data-testid="decisionText"]', justificationText: '[data-testid="justificationText"]', }, @@ -195,11 +199,14 @@ const HandlingApplicationActions: React.FC = ({ let errorStep2 = false; if (currentStepIndex > 0) { + fields.missing.decisionMakerId = + !handledApplication?.decisionMakerId || + handledApplication?.decisionMakerId?.length <= 0; errorStep2 = fields.missing.decisionText || fields.missing.justificationText || - fields.missing.handler; + fields.missing.decisionMakerId; } if (errorStep1 || errorStep2) { diff --git a/frontend/benefit/handler/src/components/applicationReview/handlingView/HandlingStep2.tsx b/frontend/benefit/handler/src/components/applicationReview/handlingView/HandlingStep2.tsx index 38b112fc2c..26aa65890c 100644 --- a/frontend/benefit/handler/src/components/applicationReview/handlingView/HandlingStep2.tsx +++ b/frontend/benefit/handler/src/components/applicationReview/handlingView/HandlingStep2.tsx @@ -35,7 +35,7 @@ const replaceDecisionTemplatePlaceholders = ( const ApplicationReviewStep2: React.FC = ({ application, }) => { - const { applicantLanguage, id } = application; + const { applicantLanguage, id, decisionProposalDraft } = application; const { t } = useTranslation(); const translationBase = 'common:review.decisionProposal'; @@ -92,6 +92,24 @@ const ApplicationReviewStep2: React.FC = ({ }); }; + React.useEffect(() => { + if (decisionMakerOptions && decisionMakerOptions.length > 0) { + setSelectedDecisionMaker({ + id: + handledApplication?.decisionMakerId || + decisionProposalDraft.decisionMakerId, + name: + handledApplication?.decisionMakerName || + decisionProposalDraft.decisionMakerName, + }); + } + }, [ + decisionMakerOptions, + decisionProposalDraft, + handledApplication?.decisionMakerId, + handledApplication?.decisionMakerName, + ]); + if (isLoading) { return ( @@ -136,10 +154,10 @@ const ApplicationReviewStep2: React.FC = ({ `${translationBase}.role.fields.decisionMaker.tooltipText` )} > - {decisionMakerOptions?.map((option) => ( + {decisionMakerOptions?.map((option, index) => ( <$RadioButton key={`radio-decision-maker-${option.id}`} - id={`radio-decision-maker-${option.id}`} + id={`radio-decision-maker-${index}`} value={option.id} label={option.name} checked={selectedDecisionMaker?.id === option?.id} From 270d056be2c689d15cbab946cea74b267362e859 Mon Sep 17 00:00:00 2001 From: Sampo Tawast Date: Thu, 7 Nov 2024 13:04:28 +0200 Subject: [PATCH 08/10] fix: crashing bug when hitting cancel when cancelling application in modal prompt --- .../handlingApplicationActions/useHandlingApplicationActions.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/frontend/benefit/handler/src/components/applicationReview/actions/handlingApplicationActions/useHandlingApplicationActions.ts b/frontend/benefit/handler/src/components/applicationReview/actions/handlingApplicationActions/useHandlingApplicationActions.ts index 1a02d8700f..a8800234a4 100644 --- a/frontend/benefit/handler/src/components/applicationReview/actions/handlingApplicationActions/useHandlingApplicationActions.ts +++ b/frontend/benefit/handler/src/components/applicationReview/actions/handlingApplicationActions/useHandlingApplicationActions.ts @@ -72,7 +72,6 @@ const useHandlingApplicationActions = ( const closeDialog = (): void => { setIsConfirmationModalOpen(false); - setHandledApplication(null); }; const closeDoneDialog = (): void => { From 7dc416d7c66520db728f52e03f85d329f9afe2c5 Mon Sep 17 00:00:00 2001 From: Sampo Tawast Date: Thu, 7 Nov 2024 13:39:29 +0200 Subject: [PATCH 09/10] chore: migration for handler_role --- ...r_ahjodecisionproposaldraft_handler_role.py | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) create mode 100644 backend/benefit/applications/migrations/0087_alter_ahjodecisionproposaldraft_handler_role.py diff --git a/backend/benefit/applications/migrations/0087_alter_ahjodecisionproposaldraft_handler_role.py b/backend/benefit/applications/migrations/0087_alter_ahjodecisionproposaldraft_handler_role.py new file mode 100644 index 0000000000..403f8853a6 --- /dev/null +++ b/backend/benefit/applications/migrations/0087_alter_ahjodecisionproposaldraft_handler_role.py @@ -0,0 +1,18 @@ +# Generated by Django 4.2.11 on 2024-11-07 11:38 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('applications', '0086_alter_ahjodecisionproposaldraft_handler_role'), + ] + + operations = [ + migrations.AlterField( + model_name='ahjodecisionproposaldraft', + name='handler_role', + field=models.CharField(blank=True, choices=[('handler', 'Helsinki-benefit handler'), ('manager', 'Team manager')], max_length=64, null=True, verbose_name='Handler role (DEPRECATED, was used before dynamic fetch of decision makers)'), + ), + ] From 32b937b0ea141244c8b21fdebec1b75d18e07ca2 Mon Sep 17 00:00:00 2001 From: Sampo Tawast Date: Thu, 7 Nov 2024 14:11:51 +0200 Subject: [PATCH 10/10] test: add ahjo settings to test --- .../applications/tests/test_ahjo_decision_proposal_drafts.py | 1 + 1 file changed, 1 insertion(+) diff --git a/backend/benefit/applications/tests/test_ahjo_decision_proposal_drafts.py b/backend/benefit/applications/tests/test_ahjo_decision_proposal_drafts.py index abb2d61add..be548f2377 100644 --- a/backend/benefit/applications/tests/test_ahjo_decision_proposal_drafts.py +++ b/backend/benefit/applications/tests/test_ahjo_decision_proposal_drafts.py @@ -118,6 +118,7 @@ def test_decision_proposal_drafting( decision_text, justification_text, fake_decisionmakers, + decision_maker_settings, ): if review_step == 4: _prepare_calculation(application=application)