From 7c207b4f740096b94044b11855589ac2f931467a Mon Sep 17 00:00:00 2001 From: Odysseus Chiu Date: Thu, 22 Aug 2024 10:45:56 -0700 Subject: [PATCH] 21597 - Invoice Refund Short name history (#1701) --- pay-api/src/pay_api/services/eft_service.py | 26 ++++++++++++++++++- pay-api/src/pay_api/version.py | 2 +- .../tests/unit/services/test_eft_service.py | 21 ++++++++++++++- 3 files changed, 46 insertions(+), 3 deletions(-) diff --git a/pay-api/src/pay_api/services/eft_service.py b/pay-api/src/pay_api/services/eft_service.py index 9d2cbe7b3..778fca681 100644 --- a/pay-api/src/pay_api/services/eft_service.py +++ b/pay-api/src/pay_api/services/eft_service.py @@ -21,6 +21,8 @@ from pay_api.exceptions import BusinessException from pay_api.models import CfsAccount as CfsAccountModel from pay_api.models import EFTCreditInvoiceLink as EFTCreditInvoiceLinkModel +from pay_api.models import EFTCredit as EFTCreditModel +from pay_api.models import EFTShortnamesHistorical as EFTHistoryModel from pay_api.models import EFTRefund as EFTRefundModel from pay_api.models import Invoice as InvoiceModel from pay_api.models import InvoiceReference as InvoiceReferenceModel @@ -30,6 +32,8 @@ from pay_api.models import RefundPartialLine from pay_api.models.eft_refund_email_list import EFTRefundEmailList from pay_api.services.eft_short_names import EFTShortnames +from pay_api.services.eft_short_name_historical import EFTShortnameHistorical as EFTHistoryService +from pay_api.services.eft_short_name_historical import EFTShortnameHistory as EFTHistory from pay_api.services.email_service import _render_shortname_details_body, send_email from pay_api.utils.enums import ( CfsAccountStatus, EFTCreditInvoiceStatus, InvoiceReferenceStatus, InvoiceStatus, PaymentMethod, PaymentStatus, @@ -112,12 +116,18 @@ def process_cfs_refund(self, invoice: InvoiceModel, latest_link = cils[0] sibling_cils = [cil for cil in cils if cil.link_group_id == latest_link.link_group_id] + latest_eft_credit = EFTCreditModel.find_by_id(latest_link.eft_credit_id) + link_group_id = EFTCreditInvoiceLinkModel.get_next_group_link_seq() + existing_balance = EFTShortnames.get_eft_credit_balance(latest_eft_credit.short_name_id) + match latest_link.status_code: case EFTCreditInvoiceStatus.PENDING.value: # 3. EFT Credit Link - PENDING, CANCEL that link - restore balance to EFT credit existing call # (Invoice needs to be reversed, receipt doesn't exist.) for cil in sibling_cils: EFTShortnames.return_eft_credit(cil, EFTCreditInvoiceStatus.CANCELLED.value) + cil.link_group_id = link_group_id + cil.flush() case EFTCreditInvoiceStatus.COMPLETED.value: # 4. EFT Credit Link - COMPLETED # (Invoice needs to be reversed and receipt needs to be reversed.) @@ -129,7 +139,21 @@ def process_cfs_refund(self, invoice: InvoiceModel, amount=cil.amount, receipt_number=cil.receipt_number, invoice_id=invoice.id, - link_group_id=cil.link_group_id).flush() + link_group_id=link_group_id).flush() + + current_balance = EFTShortnames.get_eft_credit_balance(latest_eft_credit.short_name_id) + if existing_balance != current_balance: + short_name_history = EFTHistoryModel.find_by_related_group_link_id(latest_link.link_group_id) + EFTHistoryService.create_invoice_refund( + EFTHistory(short_name_id=latest_eft_credit.short_name_id, + amount=invoice.total, + credit_balance=current_balance, + payment_account_id=payment_account.id, + related_group_link_id=link_group_id, + statement_number=short_name_history.statement_number if short_name_history else None, + invoice_id=invoice.id, + is_processing=True, + hidden=False)).flush() return InvoiceStatus.REFUND_REQUESTED.value diff --git a/pay-api/src/pay_api/version.py b/pay-api/src/pay_api/version.py index c3b74cf86..dc03001c3 100644 --- a/pay-api/src/pay_api/version.py +++ b/pay-api/src/pay_api/version.py @@ -22,4 +22,4 @@ Development release segment: .devN """ -__version__ = '1.21.9' # pylint: disable=invalid-name +__version__ = '1.21.10' # pylint: disable=invalid-name diff --git a/pay-api/tests/unit/services/test_eft_service.py b/pay-api/tests/unit/services/test_eft_service.py index 416ef4ab0..707d32a52 100644 --- a/pay-api/tests/unit/services/test_eft_service.py +++ b/pay-api/tests/unit/services/test_eft_service.py @@ -19,11 +19,14 @@ from datetime import datetime, timezone from unittest.mock import MagicMock, patch + import pytest + from pay_api.exceptions import BusinessException from pay_api.models import EFTCreditInvoiceLink as EFTCreditInvoiceLinkModel +from pay_api.models import EFTShortnamesHistorical as EFTHistoryModel from pay_api.services.eft_service import EftService -from pay_api.utils.enums import EFTCreditInvoiceStatus, InvoiceStatus, PaymentMethod +from pay_api.utils.enums import EFTCreditInvoiceStatus, EFTHistoricalTypes, InvoiceStatus, PaymentMethod from pay_api.utils.errors import Error from tests.utilities.base_test import ( factory_eft_credit, factory_eft_credit_invoice_link, factory_eft_file, factory_eft_shortname, factory_invoice, @@ -195,12 +198,16 @@ def test_eft_invoice_refund(session, test_name): assert invoice assert invoice.invoice_status_code == InvoiceStatus.REFUND_REQUESTED.value assert cil_1.status_code == EFTCreditInvoiceStatus.CANCELLED.value + eft_history = session.query(EFTHistoryModel).one() + assert_shortname_refund_history(eft_credit, eft_history, invoice) case '1_invoice_non_exist': assert invoice assert invoice.invoice_status_code == InvoiceStatus.CANCELLED.value + assert session.query(EFTHistoryModel).one_or_none() is None case '2_no_eft_credit_link': assert invoice assert invoice.invoice_status_code == InvoiceStatus.REFUND_REQUESTED.value + assert session.query(EFTHistoryModel).one_or_none() is None case '3_pending_credit_link': assert invoice assert invoice.invoice_status_code == InvoiceStatus.REFUND_REQUESTED.value @@ -209,6 +216,8 @@ def test_eft_invoice_refund(session, test_name): assert cil_3.status_code == EFTCreditInvoiceStatus.CANCELLED.value assert cil_4.status_code == EFTCreditInvoiceStatus.CANCELLED.value assert eft_credit.remaining_amount == 3 + eft_history = session.query(EFTHistoryModel).one() + assert_shortname_refund_history(eft_credit, eft_history, invoice) case '4_completed_credit_link': assert invoice assert invoice.invoice_status_code == InvoiceStatus.REFUND_REQUESTED.value @@ -224,5 +233,15 @@ def test_eft_invoice_refund(session, test_name): if cil.status_code == EFTCreditInvoiceStatus.PENDING_REFUND.value: pending_refund_count += 1 assert pending_refund_count == 3 + eft_history = session.query(EFTHistoryModel).one() + assert_shortname_refund_history(eft_credit, eft_history, invoice) case _: raise NotImplementedError + + +def assert_shortname_refund_history(eft_credit, eft_history, invoice): + """Assert EFT Short name record for invoice refund.""" + assert eft_history.credit_balance == eft_credit.remaining_amount + assert eft_history.is_processing is True + assert eft_history.amount == invoice.total + assert eft_history.transaction_type == EFTHistoricalTypes.INVOICE_REFUND.value