From 314fd5fb5954017bdb3caec63fd82f066a6574c6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Riku=20Kestila=CC=88?= Date: Mon, 21 Oct 2024 18:18:22 +0300 Subject: [PATCH] fix: modified_at date for ahjo update request --- .../applications/services/ahjo_payload.py | 224 +++++++++++++----- .../applications/tests/test_ahjo_payload.py | 118 +++++++-- 2 files changed, 256 insertions(+), 86 deletions(-) diff --git a/backend/benefit/applications/services/ahjo_payload.py b/backend/benefit/applications/services/ahjo_payload.py index f08848517a..867422e2d6 100644 --- a/backend/benefit/applications/services/ahjo_payload.py +++ b/backend/benefit/applications/services/ahjo_payload.py @@ -1,15 +1,11 @@ +from dataclasses import dataclass, field from datetime import datetime from typing import List from django.conf import settings from django.urls import reverse -from applications.enums import ( - AhjoRecordTitle, - AhjoRecordType, - AhjoRequestType, - AttachmentType, -) +from applications.enums import AhjoRecordTitle, AhjoRecordType, AttachmentType from applications.models import ( AhjoDecisionText, Application, @@ -22,40 +18,164 @@ MANNER_OF_RECEIPT = "sähköinen asiointi" -def _prepare_record_title( - application: Application, - record_type: AhjoRecordType, - request_type: AhjoRequestType, - current: int = 0, - total: int = 0, -) -> str: - """Prepare the title for the application record in Ahjo in the required format: - If the request type is an update or adding new records, add the word "täydennys" to the title. - For example: - for open case: - Hakemus 22.8.2024, 125xxx - for adding new records: - Hakemus, täydennys (päivämäärä jolloin täydennys saapunut), 125xxx - and for attachments in the open case request: - Hakemus 26.3.2024, liite 1/1, 123xxx +@dataclass +class AhjoTitle: + """ + Base class for creating title strings for various record types related to an application. + + Attributes: + application (Application): The application object that contains details + like created or modified date, and application number. + prefix (str): A string to be added before the date in the title. + suffix (str): A string to be added after the date in the title. + """ + + application: Application = None + prefix: str = "" + suffix: str = "" + + def format_title_string(self, formatted_date: str, application_number: str) -> str: + """ + Formats the title string using the provided date and application number. + + Args: + formatted_date (str): A formatted string representing the date. + application_number (str): The application number as a string. + + Returns: + str: A formatted title string that includes the prefix, date, suffix, and application number. + """ + return f"{AhjoRecordTitle.APPLICATION}{self.prefix} {formatted_date},{self.suffix} {application_number}" + + +@dataclass +class OpenCaseRecordTitle(AhjoTitle): + """ + A class for creating the title of an open case record. + + Inherits from AhjoTitle. Uses the application's creation date and application number to format the title. + + Methods: + __str__(): Returns the formatted string representation of the open case title. + """ + + def __str__(self): + """ + Returns a formatted title string for an open case, using the application's creation date and application number. + + Returns: + str: The formatted title string. + """ + formatted_date = self.application.created_at.strftime("%d.%m.%Y") + return self.format_title_string( + formatted_date, self.application.application_number + ) + + +@dataclass +class UpdateRecordsRecordTitle(AhjoTitle): + """ + A class for creating the title of an update record. + + Inherits from AhjoTitle. Uses the application's modification date and application number to format the title. + The prefix is set to ", täydennys," by default. + + Attributes: + prefix (str): A default string ", täydennys," that is used in the title of update records. + + Methods: + __str__(): Returns the formatted string representation of the update record title. + """ + + prefix: str = field(default=", täydennys,") + + def __str__(self): + """ + Returns a formatted title string for an update record, + using the application's modification date and application number. + + Returns: + str: The formatted title string. + """ + modified_at = self.application.modified_at + formatted_date = modified_at.strftime("%d.%m.%Y") + return self.format_title_string( + formatted_date, self.application.application_number + ) + + +@dataclass +class AddRecordsRecordTitle(AhjoTitle): + """ + A class for creating the title of an additional record sent after the initial open case request. + + Inherits from AhjoTitle. Uses the application's creation date and application number to format the title. + The prefix is set to ", täydennys," by default. + + Attributes: + prefix (str): A default string ", täydennys," that is used in the title of additional records. + + Methods: + __str__(): Returns the formatted string representation of the additional record title. + """ + + prefix: str = field(default=", täydennys,") + + def __str__(self): + """ + Returns a formatted title string for an additional record, + using the application's creation date and application number. + + Returns: + str: The formatted title string. + """ + formatted_date = self.application.created_at.strftime("%d.%m.%Y") + return self.format_title_string( + formatted_date, self.application.application_number + ) + + +@dataclass +class AhjoBaseRecordTitle(AhjoTitle): """ - formatted_date = application.created_at.strftime("%d.%m.%Y") + A class for creating the title of a basic attachment/record + with a suffix indicating the current item and total items. - if ( - request_type == AhjoRequestType.OPEN_CASE - and record_type == AhjoRecordType.APPLICATION - ): - return f"{AhjoRecordTitle.APPLICATION} {formatted_date}, {application.application_number}" - elif ( - request_type == AhjoRequestType.UPDATE_APPLICATION - and record_type == AhjoRecordType.APPLICATION - ) or ( - request_type == AhjoRequestType.ADD_RECORDS - and record_type == AhjoRecordType.ATTACHMENT - ): - return f"{AhjoRecordTitle.APPLICATION}, täydennys {formatted_date}, {application.application_number}" + Inherits from AhjoTitle. + This class adds a suffix that indicates how many parts (e.g., "liite 1/5") are in the document. - return f"{AhjoRecordTitle.APPLICATION} {formatted_date}, liite {current}/{total}, {application.application_number}" + Attributes: + current (int): The current item number in the list of records. + total (int): The total number of items. + + Methods: + set_suffix(): Updates the suffix to include the current and total numbers. + __str__(): Returns the formatted string representation of the base record title. + """ + + current: int = 0 + total: int = 0 + + def set_suffix(self): + """ + Updates the suffix with the current and total items, forming a string like "liite 1/5". + """ + self.suffix = f" liite {self.current}/{self.total}," + + def __str__(self): + """ + Returns a formatted title string for a base record, + using the application's modification date and application number. + The suffix includes the current and total items. + + Returns: + str: The formatted title string. + """ + self.set_suffix() + formatted_date = self.application.modified_at.strftime("%d.%m.%Y") + return self.format_title_string( + formatted_date, self.application.application_number + ) def prepare_case_title(application: Application, company_name: str) -> str: @@ -222,9 +342,7 @@ def _prepare_case_records( ) main_document_record = _prepare_record( - record_title=_prepare_record_title( - application, AhjoRecordType.APPLICATION, AhjoRequestType.OPEN_CASE - ), + record_title=f"{OpenCaseRecordTitle(application)}", record_type=AhjoRecordType.APPLICATION, acquired=application.created_at.isoformat("T", "seconds"), documents=[_prepare_record_document_dict(pdf_summary)], @@ -250,13 +368,7 @@ def _prepare_case_records( ) document_record = _prepare_record( - record_title=_prepare_record_title( - application, - AhjoRecordType.ATTACHMENT, - AhjoRequestType.OPEN_CASE, - position, - total_attachments, - ), + record_title=f"{AhjoBaseRecordTitle(application=application, current=position, total=total_attachments)}", record_type=AhjoRecordType.ATTACHMENT, acquired=attachment.created_at.isoformat("T", "seconds"), documents=[_prepare_record_document_dict(attachment)], @@ -288,18 +400,11 @@ def prepare_attachment_records_payload( language = resolve_payload_language(application) attachment_list = [] - position = 1 - total_attachments = len(attachments) + for attachment in attachments: attachment_list.append( _prepare_record( - record_title=_prepare_record_title( - application, - AhjoRecordType.ATTACHMENT, - AhjoRequestType.ADD_RECORDS, - position, - total_attachments, - ), + record_title=f"{AddRecordsRecordTitle(application)}", record_type=AhjoRecordType.ATTACHMENT, acquired=attachment.created_at.isoformat("T", "seconds"), documents=[_prepare_record_document_dict(attachment)], @@ -307,7 +412,6 @@ def prepare_attachment_records_payload( language=language, ) ) - position += 1 return {"records": attachment_list} @@ -325,11 +429,7 @@ def prepare_update_application_payload( return { "records": [ _prepare_record( - record_title=_prepare_record_title( - application, - AhjoRecordType.APPLICATION, - AhjoRequestType.UPDATE_APPLICATION, - ), + record_title=f"{UpdateRecordsRecordTitle(application)}", record_type=AhjoRecordType.APPLICATION, acquired=pdf_summary.created_at.isoformat("T", "seconds"), documents=[_prepare_record_document_dict(pdf_summary)], diff --git a/backend/benefit/applications/tests/test_ahjo_payload.py b/backend/benefit/applications/tests/test_ahjo_payload.py index d5f773a5de..9cc5ca26fc 100644 --- a/backend/benefit/applications/tests/test_ahjo_payload.py +++ b/backend/benefit/applications/tests/test_ahjo_payload.py @@ -1,4 +1,6 @@ import uuid +from datetime import datetime +from unittest.mock import Mock import pytest from django.core.files.base import ContentFile @@ -10,23 +12,94 @@ AhjoRequestType, AttachmentType, ) -from applications.models import AhjoDecisionText, Attachment +from applications.models import AhjoDecisionText, Application, Attachment from applications.services.ahjo_payload import ( _prepare_case_records, _prepare_record, _prepare_record_document_dict, - _prepare_record_title, _prepare_top_level_dict, + AddRecordsRecordTitle, + AhjoBaseRecordTitle, + AhjoTitle, + OpenCaseRecordTitle, prepare_case_title, prepare_decision_proposal_payload, prepare_final_case_title, prepare_update_application_payload, resolve_payload_language, truncate_string_to_limit, + UpdateRecordsRecordTitle, ) from common.utils import hash_file +# Test the AhjoTitle format_title_string method +def test_format_title_string(): + mock_app = Mock(spec=Application) + mock_app.created_at = datetime(2023, 1, 15) + mock_app.application_number = "12345" + + ahjo_title = AhjoTitle( + application=mock_app, prefix=" Test Prefix", suffix=" Test Suffix" + ) + formatted_date = "15.01.2023" + application_number = "12345" + + result = ahjo_title.format_title_string(formatted_date, application_number) + expected = ( + f"{AhjoRecordTitle.APPLICATION} Test Prefix 15.01.2023, Test Suffix 12345" + ) + assert result == expected + + +# Test OpenCaseRecordTitle class +def test_open_case_record_title_str(): + mock_app = Mock(spec=Application) + mock_app.created_at = datetime(2023, 1, 15) + mock_app.application_number = "12345" + + open_case_title = OpenCaseRecordTitle(application=mock_app) + result = str(open_case_title) + expected = f"{AhjoRecordTitle.APPLICATION} 15.01.2023, 12345" + assert result == expected + + +# Test UpdateRecordsRecordTitle class +def test_update_records_record_title_str(): + mock_app = Mock(spec=Application) + mock_app.modified_at = datetime(2023, 2, 25) + mock_app.application_number = "67890" + + update_records_title = UpdateRecordsRecordTitle(application=mock_app) + result = str(update_records_title) + expected = f"{AhjoRecordTitle.APPLICATION}, täydennys, 25.02.2023, 67890" + assert result == expected + + +# Test AddRecordsRecordTitle class +def test_add_records_record_title_str(): + mock_app = Mock(spec=Application) + mock_app.created_at = datetime(2023, 3, 10) + mock_app.application_number = "54321" + + add_records_title = AddRecordsRecordTitle(application=mock_app) + result = str(add_records_title) + expected = f"{AhjoRecordTitle.APPLICATION}, täydennys, 10.03.2023, 54321" + assert result == expected + + +# Test AhjoBaseRecordTitle class +def test_ahjo_base_record_title_str(): + mock_app = Mock(spec=Application) + mock_app.modified_at = datetime(2023, 4, 5) + mock_app.application_number = "98765" + + base_record_title = AhjoBaseRecordTitle(application=mock_app, current=1, total=5) + result = str(base_record_title) + expected = f"{AhjoRecordTitle.APPLICATION} 05.04.2023, liite 1/5, 98765" + assert result == expected + + def test_prepare_case_title(decided_application): application = decided_application wanted_title = f"Avustukset työnantajille, työllisyyspalvelut, \ @@ -74,9 +147,10 @@ def test_prepare_final_case_title_truncate( @pytest.mark.parametrize( - "record_title, record_type, request_type, wanted_title_addition, part, total", + "title_class, record_title, record_type, request_type, wanted_title_addition, part, total", [ ( + OpenCaseRecordTitle, AhjoRecordTitle.APPLICATION, AhjoRecordType.APPLICATION, AhjoRequestType.OPEN_CASE, @@ -85,22 +159,25 @@ def test_prepare_final_case_title_truncate( 0, ), ( + UpdateRecordsRecordTitle, AhjoRecordTitle.APPLICATION, AhjoRecordType.APPLICATION, AhjoRequestType.UPDATE_APPLICATION, - ", täydennys", + ", täydennys,", 0, 0, ), ( + AddRecordsRecordTitle, AhjoRecordTitle.APPLICATION, AhjoRecordType.ATTACHMENT, AhjoRequestType.ADD_RECORDS, - ", täydennys", + ", täydennys,", 0, 0, ), ( + AhjoBaseRecordTitle, AhjoRecordTitle.APPLICATION, AhjoRecordType.ATTACHMENT, AhjoRequestType.OPEN_CASE, @@ -111,6 +188,7 @@ def test_prepare_final_case_title_truncate( ], ) def test_prepare_record_title( + title_class, decided_application, record_title, record_type, @@ -127,7 +205,13 @@ def test_prepare_record_title( liite {part}/{total}, {application.application_number}" else: wanted_title = f"{record_title}{wanted_title_addition} {formatted_date}, {application.application_number}" - got = _prepare_record_title(application, record_type, request_type, part, total) + if ( + record_type == AhjoRecordType.ATTACHMENT + and request_type == AhjoRequestType.OPEN_CASE + ): + got = f"{title_class(application, current=part, total=total)}" + else: + got = f"{title_class(application=application)}" assert wanted_title == got @@ -135,9 +219,7 @@ def test_prepare_record_title_for_attachment(decided_application): application = decided_application formatted_date = application.created_at.strftime("%d.%m.%Y") wanted_title = f"{AhjoRecordTitle.APPLICATION} {formatted_date}, liite 1/3, {application.application_number}" - got = _prepare_record_title( - application, AhjoRecordType.ATTACHMENT, AhjoRequestType.OPEN_CASE, 1, 3 - ) + got = f"{AhjoBaseRecordTitle(application=application, current=1, total=3)}" assert wanted_title == got @@ -231,9 +313,7 @@ def test_prepare_case_records(decided_application, settings): handler_name = f"{handler.last_name}, {handler.first_name}" want = [ { - "Title": _prepare_record_title( - application, AhjoRecordType.APPLICATION, AhjoRequestType.OPEN_CASE - ), + "Title": f"{OpenCaseRecordTitle(application=application)}", "Type": AhjoRecordType.APPLICATION, "Acquired": application.created_at.isoformat("T", "seconds"), "PublicityClass": "Salassa pidettävä", @@ -263,13 +343,7 @@ def test_prepare_case_records(decided_application, settings): for attachment in open_case_attachments: document_record = _prepare_record( - _prepare_record_title( - application, - AhjoRecordType.ATTACHMENT, - AhjoRequestType.OPEN_CASE, - pos, - total_attachments, - ), + f"{AhjoBaseRecordTitle(application=application,current=pos,total=total_attachments,)}", AhjoRecordType.ATTACHMENT, attachment.created_at.isoformat("T", "seconds"), [_prepare_record_document_dict(attachment)], @@ -314,11 +388,7 @@ def test_prepare_update_application_payload(decided_application): want = { "records": [ { - "Title": _prepare_record_title( - application, - AhjoRecordType.APPLICATION, - AhjoRequestType.UPDATE_APPLICATION, - ), + "Title": f"{UpdateRecordsRecordTitle(application=application,)}", "Type": AhjoRecordType.APPLICATION, "Acquired": application.created_at.isoformat(), "PublicityClass": "Salassa pidettävä",