diff --git a/pay-api/src/pay_api/services/payment.py b/pay-api/src/pay_api/services/payment.py index 6b15d06b4..4a7565667 100644 --- a/pay-api/src/pay_api/services/payment.py +++ b/pay-api/src/pay_api/services/payment.py @@ -381,7 +381,7 @@ def search_purchase_history( # pylint: disable=too-many-locals, too-many-argume return data @classmethod - def create_payment_report_details(cls, purchases: Tuple, data: Dict): # pylint:disable=too-many-locals + def create_payment_report_details(cls, purchases: Tuple, data: Dict) -> dict: # pylint:disable=too-many-locals """Return payment report details by fetching the line items. purchases is tuple of payment and invoice model records. @@ -415,30 +415,49 @@ def create_payment_report(auth_account_id: str, search_filter: Dict, content_typ return report_response @staticmethod - def get_invoices_totals(invoices): + def get_invoices_totals(invoices: dict, statement: dict) -> dict: """Tally up totals for a list of invoices.""" - total_stat_fees = 0 - total_service_fees = 0 - total = 0 - total_paid = 0 + totals = { + "statutoryFees": 0, + "serviceFees": 0, + "fees": 0, + "paid": 0, + "due": 0, + } for invoice in invoices: - total += invoice.get("total", 0) - total_stat_fees += invoice.get("total", 0) - invoice.get("service_fees", 0) - - total_service_fees += invoice.get("service_fees", 0) - total_paid += invoice.get("paid", 0) - - # Format date to local invoice["created_on"] = get_local_formatted_date(parser.parse(invoice["created_on"])) + total = invoice.get("total", 0) + service_fees = invoice.get("service_fees", 0) + paid = invoice.get("paid", 0) + refund = invoice.get("refund", 0) + payment_method = invoice.get("payment_method") + payment_date = invoice.get("payment_date") + refund_date = invoice.get("refund_date") + + totals["fees"] += total + totals["statutoryFees"] += total - service_fees + totals["serviceFees"] += service_fees + totals["due"] += total + if not statement or payment_method != PaymentMethod.EFT.value: + totals["due"] -= paid + totals["paid"] += paid + if paid == 0 and refund > 0: + totals["due"] -= refund + elif payment_method == PaymentMethod.EFT.value: + if payment_date and parser.parse(payment_date) <= parser.parse(statement.get("to_date", "")): + totals["due"] -= paid + totals["paid"] += paid + # Scenario where payment was refunded, paid $0, refund = invoice total + if ( + paid == 0 + and refund > 0 + and refund_date + and parser.parse(refund_date) <= parser.parse(statement.get("to_date", "")) + ): + totals["due"] -= refund - return { - "statutoryFees": total_stat_fees, - "serviceFees": total_service_fees, - "fees": total, - "paid": total_paid, - "due": total - total_paid, - } + return totals @staticmethod @user_context @@ -479,7 +498,8 @@ def generate_payment_report(report_inputs: PaymentReportInput, **kwargs): # pyl } else: invoices = results.get("items", None) - totals = Payment.get_invoices_totals(invoices) + statement = kwargs.get("statement", {}) + totals = Payment.get_invoices_totals(invoices, statement) account_info = None if kwargs.get("auth", None): diff --git a/pay-api/src/pay_api/services/statement.py b/pay-api/src/pay_api/services/statement.py index f1f9b7612..1ede766f4 100644 --- a/pay-api/src/pay_api/services/statement.py +++ b/pay-api/src/pay_api/services/statement.py @@ -348,12 +348,13 @@ def get_statement_eft_transactions( @classmethod def _populate_statement_summary(cls, statement: StatementModel, statement_invoices: List[InvoiceModel]) -> dict: """Populate statement summary with additional information.""" - previous_statement: StatementModel = Statement.get_previous_statement(statement) + previous_statement = Statement.get_previous_statement(statement) previous_totals = None if previous_statement: previous_invoices = StatementModel.find_all_payments_and_invoices_for_statement(previous_statement.id) - previous_items: dict = PaymentService.create_payment_report_details(purchases=previous_invoices, data=None) - previous_totals = PaymentService.get_invoices_totals(previous_items.get("items", None)) + previous_items = PaymentService.create_payment_report_details(purchases=previous_invoices, data=None) + # Skip passing statement, we need the totals independent of the statement/payment date. + previous_totals = PaymentService.get_invoices_totals(previous_items.get("items", None), None) latest_payment_date = None for invoice in statement_invoices: @@ -384,7 +385,7 @@ def get_statement_report(statement_id: str, content_type: str, **kwargs): from_date_string: str = statement_svc.from_date.strftime(DT_SHORT_FORMAT) to_date_string: str = statement_svc.to_date.strftime(DT_SHORT_FORMAT) - extension: str = "pdf" if content_type == ContentType.PDF.value else "csv" + extension = "pdf" if content_type == ContentType.PDF.value else "csv" if statement_svc.frequency == StatementFrequency.DAILY.value: report_name = f"{report_name}-{from_date_string}.{extension}" @@ -393,7 +394,7 @@ def get_statement_report(statement_id: str, content_type: str, **kwargs): statement_purchases = StatementModel.find_all_payments_and_invoices_for_statement(statement_id) - result_items: dict = PaymentService.create_payment_report_details(purchases=statement_purchases, data=None) + result_items = PaymentService.create_payment_report_details(purchases=statement_purchases, data=None) statement = statement_svc.asdict() statement["from_date"] = from_date_string statement["to_date"] = to_date_string diff --git a/pay-api/tests/unit/services/test_payment.py b/pay-api/tests/unit/services/test_payment.py index 4f7fbd3fe..16806fdfc 100644 --- a/pay-api/tests/unit/services/test_payment.py +++ b/pay-api/tests/unit/services/test_payment.py @@ -16,13 +16,13 @@ Test-Suite to ensure that the FeeSchedule Service is working as expected. """ -from datetime import datetime, timezone +from datetime import datetime, timedelta, timezone import pytest import pytz from pay_api.models.payment_account import PaymentAccount -from pay_api.services.payment import Payment as Payment_service +from pay_api.services.payment import Payment as PaymentService from pay_api.utils.enums import InvoiceReferenceStatus, InvoiceStatus, PaymentMethod from pay_api.utils.util import current_local_time from tests.utilities.base_test import ( @@ -31,6 +31,7 @@ factory_payment, factory_payment_account, factory_payment_line_item, + factory_statement, factory_usd_payment, ) @@ -46,7 +47,7 @@ def test_payment_saved_from_new(session): invoice = factory_invoice(payment_account) invoice.save() factory_invoice_reference(invoice.id).save() - p = Payment_service.find_by_id(payment.id) + p = PaymentService.find_by_id(payment.id) assert p is not None assert p.id is not None @@ -57,7 +58,7 @@ def test_payment_saved_from_new(session): def test_payment_invalid_lookup(session): """Test invalid lookup.""" - p = Payment_service.find_by_id(999) + p = PaymentService.find_by_id(999) assert p is not None assert p.id is None @@ -72,7 +73,7 @@ def test_payment_with_no_active_invoice(session): invoice = factory_invoice(payment_account, InvoiceStatus.DELETED.value) invoice.save() factory_invoice_reference(invoice.id).save() - p = Payment_service.find_by_id(payment.id) + p = PaymentService.find_by_id(payment.id) assert p is not None assert p.id is not None @@ -273,7 +274,7 @@ def test_search_payment_history( else: return_all = False limit = 2 - results = Payment_service.search_purchase_history( + results = PaymentService.search_purchase_history( auth_account_id=auth_account_id, search_filter=search_filter, limit=limit, @@ -303,7 +304,7 @@ def test_search_payment_history_for_all(session): invoice.save() factory_invoice_reference(invoice.id).save() - results = Payment_service.search_all_purchase_history(auth_account_id=auth_account_id, search_filter={}) + results = PaymentService.search_all_purchase_history(auth_account_id=auth_account_id, search_filter={}) assert results is not None assert results.get("items") is not None # Returns only the default number if payload is empty @@ -323,7 +324,7 @@ def test_create_payment_report_csv(session, rest_call_mock): invoice.save() factory_invoice_reference(invoice.id).save() - Payment_service.create_payment_report( + PaymentService.create_payment_report( auth_account_id=auth_account_id, search_filter={}, content_type="text/csv", @@ -345,7 +346,7 @@ def test_create_payment_report_pdf(session, rest_call_mock): invoice.save() factory_invoice_reference(invoice.id).save() - Payment_service.create_payment_report( + PaymentService.create_payment_report( auth_account_id=auth_account_id, search_filter={}, content_type="application/pdf", @@ -367,9 +368,7 @@ def test_search_payment_history_with_tz(session): factory_invoice_reference(invoice.id).save() auth_account_id = PaymentAccount.find_by_id(payment_account.id).auth_account_id - results = Payment_service.search_purchase_history( - auth_account_id=auth_account_id, search_filter={}, limit=1, page=1 - ) + results = PaymentService.search_purchase_history(auth_account_id=auth_account_id, search_filter={}, limit=1, page=1) assert results is not None assert results.get("items") is not None assert results.get("total") == 1 @@ -384,9 +383,7 @@ def test_search_payment_history_with_tz(session): invoice.save() factory_invoice_reference(invoice.id).save() - results = Payment_service.search_purchase_history( - auth_account_id=auth_account_id, search_filter={}, limit=1, page=1 - ) + results = PaymentService.search_purchase_history(auth_account_id=auth_account_id, search_filter={}, limit=1, page=1) assert results is not None assert results.get("items") is not None assert results.get("total") == 2 @@ -411,7 +408,7 @@ def test_search_account_payments(session): auth_account_id = PaymentAccount.find_by_id(payment_account.id).auth_account_id - results = Payment_service.search_account_payments(auth_account_id=auth_account_id, status=None, limit=1, page=1) + results = PaymentService.search_account_payments(auth_account_id=auth_account_id, status=None, limit=1, page=1) assert results is not None assert results.get("items") is not None assert results.get("total") == 1 @@ -436,7 +433,7 @@ def test_search_account_failed_payments(session): auth_account_id = PaymentAccount.find_by_id(payment_account.id).auth_account_id - results = Payment_service.search_account_payments(auth_account_id=auth_account_id, status="FAILED", limit=1, page=1) + results = PaymentService.search_account_payments(auth_account_id=auth_account_id, status="FAILED", limit=1, page=1) assert results.get("items") assert results.get("total") == 1 @@ -456,7 +453,7 @@ def test_search_account_failed_payments(session): auth_account_id = PaymentAccount.find_by_id(payment_account.id).auth_account_id - results = Payment_service.search_account_payments(auth_account_id=auth_account_id, status="FAILED", limit=1, page=1) + results = PaymentService.search_account_payments(auth_account_id=auth_account_id, status="FAILED", limit=1, page=1) assert results.get("items") assert results.get("total") == 2 @@ -470,7 +467,7 @@ def test_search_account_failed_payments(session): inv_number_3 = "REG00003" factory_invoice_reference(invoice_1.id, invoice_number=inv_number_3).save() factory_invoice_reference(invoice_2.id, invoice_number=inv_number_3).save() - results = Payment_service.search_account_payments(auth_account_id=auth_account_id, status="FAILED", limit=1, page=1) + results = PaymentService.search_account_payments(auth_account_id=auth_account_id, status="FAILED", limit=1, page=1) # Now there are no active failed payments, so it should return zero records assert not results.get("items") assert results.get("total") == 0 @@ -493,11 +490,11 @@ def test_create_account_payments_for_one_failed_payment(session): auth_account_id = PaymentAccount.find_by_id(payment_account.id).auth_account_id - results = Payment_service.search_account_payments(auth_account_id=auth_account_id, status="FAILED", limit=1, page=1) + results = PaymentService.search_account_payments(auth_account_id=auth_account_id, status="FAILED", limit=1, page=1) assert results.get("total") == 1 - new_payment = Payment_service.create_account_payment(auth_account_id=auth_account_id, is_retry_payment=True) - old_payment = Payment_service.find_by_id(payment_1.id) + new_payment = PaymentService.create_account_payment(auth_account_id=auth_account_id, is_retry_payment=True) + old_payment = PaymentService.find_by_id(payment_1.id) # Assert new payment invoice number is same as old payment as there is only one failed payment. assert new_payment.invoice_number == old_payment.invoice_number @@ -537,14 +534,12 @@ def test_create_account_payments_for_multiple_failed_payments(session): auth_account_id = PaymentAccount.find_by_id(payment_account.id).auth_account_id - results = Payment_service.search_account_payments( - auth_account_id=auth_account_id, status="FAILED", limit=10, page=1 - ) + results = PaymentService.search_account_payments(auth_account_id=auth_account_id, status="FAILED", limit=10, page=1) assert results.get("total") == 2 - new_payment = Payment_service.create_account_payment(auth_account_id=auth_account_id, is_retry_payment=True) - payment_1 = Payment_service.find_by_id(payment_1.id) - payment_2 = Payment_service.find_by_id(payment_2.id) + new_payment = PaymentService.create_account_payment(auth_account_id=auth_account_id, is_retry_payment=True) + payment_1 = PaymentService.find_by_id(payment_1.id) + payment_2 = PaymentService.find_by_id(payment_2.id) # Assert new payment invoice number is different from old payment as there are more than one failed payments. assert new_payment.invoice_number != payment_1.invoice_number assert new_payment.invoice_number != payment_2.invoice_number @@ -587,14 +582,12 @@ def test_create_account_payments_after_consolidation(session): auth_account_id = PaymentAccount.find_by_id(payment_account.id).auth_account_id - results = Payment_service.search_account_payments( - auth_account_id=auth_account_id, status="FAILED", limit=10, page=1 - ) + results = PaymentService.search_account_payments(auth_account_id=auth_account_id, status="FAILED", limit=10, page=1) assert results.get("total") == 2 - new_payment_1 = Payment_service.create_account_payment(auth_account_id=auth_account_id, is_retry_payment=True) + new_payment_1 = PaymentService.create_account_payment(auth_account_id=auth_account_id, is_retry_payment=True) # Create account payment again and assert both payments returns same. - new_payment_2 = Payment_service.create_account_payment(auth_account_id=auth_account_id, is_retry_payment=True) + new_payment_2 = PaymentService.create_account_payment(auth_account_id=auth_account_id, is_retry_payment=True) assert new_payment_1.id == new_payment_2.id @@ -635,12 +628,10 @@ def test_failed_payment_after_consolidation(session): auth_account_id = PaymentAccount.find_by_id(payment_account.id).auth_account_id - results = Payment_service.search_account_payments( - auth_account_id=auth_account_id, status="FAILED", limit=10, page=1 - ) + results = PaymentService.search_account_payments(auth_account_id=auth_account_id, status="FAILED", limit=10, page=1) assert results.get("total") == 2 - new_payment_1 = Payment_service.create_account_payment(auth_account_id=auth_account_id, is_retry_payment=True) + new_payment_1 = PaymentService.create_account_payment(auth_account_id=auth_account_id, is_retry_payment=True) # Create another failed payment. inv_number_3 = "REG00003" @@ -657,7 +648,7 @@ def test_failed_payment_after_consolidation(session): ) payment_3.save() - new_payment_2 = Payment_service.create_account_payment(auth_account_id=auth_account_id, is_retry_payment=True) + new_payment_2 = PaymentService.create_account_payment(auth_account_id=auth_account_id, is_retry_payment=True) assert new_payment_1.id != new_payment_2.id assert ( new_payment_2.invoice_amount == payment_1.invoice_amount + payment_2.invoice_amount + payment_3.invoice_amount @@ -673,7 +664,7 @@ def test_payment_usd(session): invoice = factory_invoice(payment_account) invoice.save() factory_invoice_reference(invoice.id).save() - p = Payment_service.find_by_id(payment.id) + p = PaymentService.find_by_id(payment.id) assert p is not None assert p.id is not None @@ -681,3 +672,93 @@ def test_payment_usd(session): assert p.payment_method_code is not None assert p.payment_status_code is not None assert p.paid_usd_amount == 100 + + +def test_get_invoice_totals_for_statements(session): + """This tests the invoice totals that is used for generating the amount owing in the statements.""" + statement = factory_statement() + payment_account = factory_payment_account().save() + # Old flow there due = total - paid - for non EFT invoices. + data = PaymentService.create_payment_report_details( + [ + factory_invoice(payment_account, total=100, service_fees=50).save(), + factory_invoice(payment_account, paid=75, total=100, service_fees=50).save(), + # Refund on APPROVAL scenario - not paid + factory_invoice(payment_account, paid=0, refund=10, total=10).save(), + factory_invoice(payment_account, refund=100, paid=100, total=100, service_fees=20).save(), + ], + {"items": []}, + ) + totals = PaymentService.get_invoices_totals(data["items"], {"to_date": statement.to_date}) + assert totals["statutoryFees"] == 190 + assert totals["serviceFees"] == 120 + assert totals["fees"] == 310 + assert totals["paid"] == 175 + assert totals["due"] == 125 + + # EFT flow + statement.from_date = datetime.now(tz=timezone.utc) + statement.to_date = datetime.now(tz=timezone.utc) + timedelta(days=30) + statement.save() + + # FUTURE - Partial refunds? + data = PaymentService.create_payment_report_details( + [ + factory_invoice( + payment_account, paid=0, refund=0, total=100, payment_method_code=PaymentMethod.EFT.value + ).save(), + factory_invoice( + payment_account, paid=0, refund=0, total=50, payment_method_code=PaymentMethod.EFT.value + ).save(), + # Refund outside of range - These only get considered if PAID = 0 + factory_invoice( + payment_account, + paid=0, + refund=100, + total=100, + payment_method_code=PaymentMethod.EFT.value, + refund_date=statement.to_date + timedelta(days=1), + ).save(), + # Refund within range + factory_invoice( + payment_account, + paid=0, + refund=100, + total=100, + payment_method_code=PaymentMethod.EFT.value, + refund_date=statement.to_date, + ).save(), + # Payment Date outside of range + factory_invoice( + payment_account, + paid=100, + total=100, + payment_method_code=PaymentMethod.EFT.value, + payment_date=statement.to_date + timedelta(days=1), + ).save(), + # Payment Date within range + factory_invoice( + payment_account, + paid=100, + total=100, + payment_method_code=PaymentMethod.EFT.value, + payment_date=statement.to_date, + ).save(), + # Payment and Refund only consider payment + factory_invoice( + payment_account, + paid=100, + refund=100, + total=100, + payment_method_code=PaymentMethod.EFT.value, + payment_date=statement.to_date, + ).save(), + ], + {"items": []}, + ) + + totals = PaymentService.get_invoices_totals(data["items"], {"to_date": statement.to_date.strftime("%Y-%m-%d")}) + assert totals["fees"] == 650 + assert totals["paid"] == 200 + # fees - paid - refund + assert totals["due"] == 650 - 200 - 100 diff --git a/pay-api/tests/unit/services/test_payment_service.py b/pay-api/tests/unit/services/test_payment_service.py index c2470c57c..5689eb0fa 100644 --- a/pay-api/tests/unit/services/test_payment_service.py +++ b/pay-api/tests/unit/services/test_payment_service.py @@ -118,10 +118,6 @@ def test_create_payment_record_rollback(session, public_user_mock): PaymentService.create_invoice(get_payment_request(), get_auth_basic_user()) assert excinfo.type == Exception - # with patch('pay_api.services.invoice.InvoiceReference.create', side_effect=Exception('mocked error')): - # with pytest.raises(Exception) as excinfo: - # PaymentService.create_invoice(get_payment_request(), get_auth_basic_user()) - # assert excinfo.type == Exception with patch( "pay_api.services.direct_pay_service.DirectPayService.create_invoice", side_effect=Exception("mocked error"), diff --git a/pay-api/tests/unit/services/test_statement.py b/pay-api/tests/unit/services/test_statement.py index 59041e127..a4c88908b 100644 --- a/pay-api/tests/unit/services/test_statement.py +++ b/pay-api/tests/unit/services/test_statement.py @@ -31,7 +31,7 @@ from pay_api.services.statement import Statement as StatementService from pay_api.utils.constants import DT_SHORT_FORMAT from pay_api.utils.enums import ContentType, InvoiceStatus, PaymentMethod, StatementFrequency, StatementTemplate -from pay_api.utils.util import get_local_formatted_date +from pay_api.utils.util import get_local_formatted_date, get_local_formatted_date_time from tests.utilities.base_test import ( factory_eft_shortname, factory_eft_shortname_link, @@ -642,7 +642,6 @@ def test_get_eft_statement_with_invoices(session): paid=0, ).save() factory_payment_line_item(invoice_id=invoice_1.id, fee_schedule_id=1).save() - invoice_2 = factory_invoice( payment_account, payment_method_code=PaymentMethod.EFT.value, @@ -652,11 +651,35 @@ def test_get_eft_statement_with_invoices(session): ).save() factory_payment_line_item(invoice_id=invoice_2.id, fee_schedule_id=1).save() + invoice_3 = factory_invoice( + payment_account, + payment_method_code=PaymentMethod.EFT.value, + status_code=InvoiceStatus.PAID.value, + total=50, + paid=50, + payment_date=datetime.now(tz=timezone.utc) + timedelta(days=9000), + ).save() + factory_payment_line_item(invoice_id=invoice_3.id, fee_schedule_id=1).save() + + invoice_4 = factory_invoice( + payment_account, + payment_method_code=PaymentMethod.EFT.value, + status_code=InvoiceStatus.PAID.value, + total=50, + paid=50, + payment_date=statement_model.from_date + timedelta(days=1), + ).save() + factory_payment_line_item(invoice_id=invoice_4.id, fee_schedule_id=1).save() + factory_invoice_reference(invoice_1.id).save() factory_invoice_reference(invoice_2.id).save() + factory_invoice_reference(invoice_3.id).save() + factory_invoice_reference(invoice_4.id).save() + factory_statement_invoices(statement_id=statement_model.id, invoice_id=invoice_1.id) factory_statement_invoices(statement_id=statement_model.id, invoice_id=invoice_2.id) - + factory_statement_invoices(statement_id=statement_model.id, invoice_id=invoice_3.id) + factory_statement_invoices(statement_id=statement_model.id, invoice_id=invoice_4.id) expected_report_name = ( f"bcregistry-statements-{statement_from_date.strftime(DT_SHORT_FORMAT)}-" f"to-{statement_to_date.strftime(DT_SHORT_FORMAT)}.pdf" @@ -771,6 +794,84 @@ def test_get_eft_statement_with_invoices(session): "status_code": "Invoice Approved", "total": 50.0, }, + { + "bcol_account": "TEST", + "business_identifier": "CP0001234", + "corp_type_code": "CP", + "created_by": "test", + "created_name": "test name", + "created_on": get_local_formatted_date(invoice_3.created_on), + "details": [ + { + "label": "label", + "value": "value", + }, + ], + "folio_number": "1234567890", + "id": invoice_3.id, + "invoice_number": "10021", + "line_items": [ + { + "description": None, + "filing_type_code": "OTANN", + "gst": 0.0, + "pst": 0.0, + "service_fees": 0.0, + "total": 10.0, + }, + ], + "paid": 50.0, + "payment_account": { + "account_id": "1234", + "billable": True, + }, + "payment_date": datetime.strftime(invoice_3.payment_date, "%Y-%m-%dT%H:%M:%S.%f"), + "payment_method": "EFT", + "product": "BUSINESS", + "refund": 0.0, + "service_fees": 0.0, + "status_code": "COMPLETED", + "total": 50.0, + }, + { + "bcol_account": "TEST", + "business_identifier": "CP0001234", + "corp_type_code": "CP", + "created_by": "test", + "created_name": "test name", + "created_on": get_local_formatted_date(invoice_4.created_on), + "details": [ + { + "label": "label", + "value": "value", + }, + ], + "folio_number": "1234567890", + "id": invoice_4.id, + "invoice_number": "10021", + "line_items": [ + { + "description": None, + "filing_type_code": "OTANN", + "gst": 0.0, + "pst": 0.0, + "service_fees": 0.0, + "total": 10.0, + }, + ], + "paid": 50.0, + "payment_account": { + "account_id": "1234", + "billable": True, + }, + "payment_date": datetime.strftime(invoice_4.payment_date, "%Y-%m-%dT%H:%M:%S"), + "payment_method": "EFT", + "product": "BUSINESS", + "refund": 0.0, + "service_fees": 0.0, + "status_code": "COMPLETED", + "total": 50.0, + }, ], "statement": { "amount_owing": 250.0, @@ -791,14 +892,15 @@ def test_get_eft_statement_with_invoices(session): ), # pylint: disable=protected-access "lastStatementTotal": 0, "lastStatementPaidAmount": 0, - "latestStatementPaymentDate": None, + "latestStatementPaymentDate": get_local_formatted_date_time(invoice_3.payment_date, "%Y-%m-%d"), }, + # 2 are paid - looking with reference to the "statement", 1 is paid ($50) within the statement period "total": { - "due": 250.0, - "fees": 250.0, - "paid": 0.0, + "due": 300.0, + "fees": 350.0, + "paid": 50.0, "serviceFees": 0.0, - "statutoryFees": 250.0, + "statutoryFees": 350.0, }, } expected_report_inputs = ReportRequest( diff --git a/pay-api/tests/utilities/base_test.py b/pay-api/tests/utilities/base_test.py index 79930d613..d8b9b6d83 100644 --- a/pay-api/tests/utilities/base_test.py +++ b/pay-api/tests/utilities/base_test.py @@ -528,6 +528,9 @@ def factory_invoice( folio_number=1234567890, created_name="test name", details=[{"label": "label", "value": "value"}], + payment_date=None, + refund=None, + refund_date=None, ): """Return Factory.""" return Invoice( @@ -546,6 +549,9 @@ def factory_invoice( payment_method_code=payment_method_code, routing_slip=routing_slip, details=details, + payment_date=payment_date, + refund=refund, + refund_date=refund_date, )