"""Test ows-payment requests.""" from decimal import Decimal import random from unittest import mock from faker import Faker import httpx from owsclient import OwsClient from owsclient.test import OwsClientMock import pytest from src.connectors.exceptions import OwsPaymentException from src.connectors.ows_payment import ( bulk_create_contract_payable_details, bulk_create_worksheet_contract_balance_after_tax, bulk_update_worksheet_contract_balance_after_tax, delete_balance_entries_after_tax, delete_payable_details_entries, delete_payable_details_wht_vat_corrections, get_contract_balance_after_tax_entries, get_contract_closing_balance_entries, get_contract_closing_balance_entries_bulk, get_flowthrough_allocation_entries, get_payable_details_entries, get_payment_group, get_payment_group_payment, get_tax_corrections, get_tax_corrections_vat, ) from src.constants import ( AbacusStateActionStatuses, BATCH_SIZE, BATCH_SIZE_REFRESH, CORRECTION_DETAIL_GROUPS, PAYABLE_PAYMENT_ALLOCATION_FLOWTHROUGH_STATUSES, TaxCorrectionStatuses, TaxCorrectionTypes, ) from src.models import ( ContractCloseBalance, FlowthroughAllocation, PaginatedContractCloseBalances, PaginatedPayableDetailEntries, PayableBalanceAfterTaxBulkUpdate, PayableBalanceAfterTaxEntry, PaymentGroup, PaymentGroupPayment, PaymentGroupPaymentAccount, TaxCorrection, TaxCorrectionVAT, ) from tests.unit.factories import ( AccountFactory, ContractCloseBalanceFactory, ContractPayableDetailsFactory, FlowthroughAllocationFactory, PayableBalanceAfterTaxEntryFactory, PayableBalanceAfterTaxFactory, PayableDetailEntryFactory, PaymentGroupFactory, PaymentGroupPaymentFactory, TaxCorrectionFactory, TaxCorrectionVATFactory, ) def test_get_payment_group_success(ows_client_mock: OwsClientMock) -> None: """Test successfully getting payment_group detail.""" payment_group = PaymentGroupFactory.build() ows_client_mock.get( 'ows-payment', f'/payment-group/{payment_group.payment_group_id}/' ).mock( return_value=httpx.Response( status_code=200, json=PaymentGroup.model_dump(payment_group) ) ) res = get_payment_group(payment_group.payment_group_id) assert res is not None assert res.payment_group_id == payment_group.payment_group_id assert res.group_name == payment_group.group_name assert res.group_criteria == payment_group.group_criteria def test_get_payment_group_failure(ows_client_mock: OwsClientMock) -> None: """Test failure getting payment_group detail.""" payment_group_id = 22 ows_client_mock.get('ows-payment', f'/payment-group/{payment_group_id}/').mock( return_value=httpx.Response(status_code=400, json='error') ) with pytest.raises( OwsPaymentException, match=f'ERROR in GET /payment-group/{payment_group_id}/', ): get_payment_group(payment_group_id) def test_get_payment_group_payment_success(ows_client_mock: OwsClientMock) -> None: """Test successfully getting payment_group_payment detail.""" payment_group_payment_id = 22 payment_group_id = 11 payment_group_payment = PaymentGroupPaymentFactory.build( payment_group_id=payment_group_id ) ows_client_mock.get( 'ows-payment', f'/payment-group-payment/{payment_group_payment_id}/' ).mock( return_value=httpx.Response( status_code=200, json=PaymentGroupPayment.model_dump(payment_group_payment), ) ) res = get_payment_group_payment(payment_group_payment_id) assert res is not None assert res.payment_group_id == payment_group_id assert res.payment_name def test_get_payment_group_payment_failure(ows_client_mock: OwsClientMock) -> None: """Test failure getting payment_group_payment detail.""" payment_group_payment_id = 22 ows_client_mock.get( 'ows-payment', f'/payment-group-payment/{payment_group_payment_id}/' ).mock(return_value=httpx.Response(status_code=400, json='error')) with pytest.raises( OwsPaymentException, match=f'ERROR in GET /payment-group-payment/{payment_group_payment_id}/', ): get_payment_group_payment(payment_group_payment_id) def test_get_contract_closing_balance_entries_success( ows_client_mock: OwsClientMock, ) -> None: """Test successfully getting contract close balance entries.""" limit = 100 offset = 0 statement_period_id = 22 account_id = 11 accounts = [AccountFactory.build(account_id=account_id)] contract_close_balance = ContractCloseBalanceFactory.build(account_id=account_id) ows_client_mock.get( 'ows-payment', f'/worksheet-account-contract-closing-balance/statement-period/{statement_period_id}/', # noqa: E501 ).mock( return_value=httpx.Response( status_code=200, json={ 'items': [ ContractCloseBalance.model_dump(contract_close_balance, mode='json') ], 'total_count': 1, }, ) ) res = get_contract_closing_balance_entries( statement_period_id, accounts, limit, offset ) assert res is not None assert res.total_count == 1 assert res.items[0].account_id == account_id assert res.items[0].contract_id == contract_close_balance.contract_id assert res.items[0].currency_code == contract_close_balance.currency_code assert ( res.items[0].reference_payment_entity_id == contract_close_balance.reference_payment_entity_id ) # noqa: E501 assert ( res.items[0].worksheet_account_contract_closing_balance_id == contract_close_balance.worksheet_account_contract_closing_balance_id ) # noqa: E501 def test_get_contract_closing_balance_entries_payment_failure( ows_client_mock: OwsClientMock, ) -> None: """Test failure getting contract close balance entries.""" limit = 100 offset = 0 statement_period_id = 22 account_id = 11 accounts = [AccountFactory.build(account_id=account_id)] ows_client_mock.get( 'ows-payment', f'/worksheet-account-contract-closing-balance/statement-period/{statement_period_id}/', # noqa: E501 ).mock(return_value=httpx.Response(status_code=400, json='error')) with pytest.raises( OwsPaymentException, match=f'ERROR in GET /worksheet-account-contract-closing-balance/statement-period/{statement_period_id}/\?account_ids={account_id}&limit={limit}&offset={offset}', # noqa ): get_contract_closing_balance_entries( statement_period_id, accounts, limit, offset ) def test_get_payable_balance_after_tax_entries_success( ows_client_mock: OwsClientMock, ) -> None: """Test successfully getting payable_balance_after_tax_entries detail.""" limit = 100 offset = 0 event_id = 22 payable_balance: PayableBalanceAfterTaxEntry = ( PayableBalanceAfterTaxEntryFactory.build() ) # noqa: E501 ows_client_mock.get( 'ows-payment', f'/worksheet-payable-balance-after-tax/event/{event_id}/' ).mock( return_value=httpx.Response( status_code=200, json={'items': [payable_balance.model_dump(mode='json')], 'total_count': 1}, ) ) res = get_contract_balance_after_tax_entries(event_id, limit, offset) assert res is not None assert res.items == [payable_balance] assert res.total_count == 1 def test_get_payable_balance_after_tax_entries_contract_ids_filter( ows_client_mock: OwsClientMock, ) -> None: """Test successfully getting payable_balance_after_tax_entries detail.""" limit = 100 offset = 0 event_id = 22 contract_ids = [25, 26] payable_balance: PayableBalanceAfterTaxEntry = ( PayableBalanceAfterTaxEntryFactory.build() ) # noqa: E501 query_string = f'?limit={limit}&offset={offset}&contract_ids=25&contract_ids=26' ows_client_mock.get( 'ows-payment', f'/worksheet-payable-balance-after-tax/event/{event_id}/{query_string}', ).mock( return_value=httpx.Response( status_code=200, json={'items': [payable_balance.model_dump(mode='json')], 'total_count': 1}, ) ) res = get_contract_balance_after_tax_entries(event_id, limit, offset, contract_ids) assert res is not None assert res.items == [payable_balance] assert res.total_count == 1 def test_get_payable_balance_after_tax_entries_failure( ows_client_mock: OwsClientMock, ) -> None: """Test failure getting payable_balance_after_tax_entries detail.""" limit = 100 offset = 0 event_id = 22 ows_client_mock.get( 'ows-payment', f'/worksheet-payable-balance-after-tax/event/{event_id}/' ).mock(return_value=httpx.Response(status_code=400, json='error')) with pytest.raises( OwsPaymentException, match=f'ERROR in GET /worksheet-payable-balance-after-tax/event/{event_id}/\?limit={limit}&offset={offset}', # noqa ): get_contract_balance_after_tax_entries(event_id, limit, offset) def test_bulk_create_worksheet_contract_balance_after_tax_success( ows_client_mock: OwsClientMock, ) -> None: """Test successfully creating contract balance after tax entities.""" statement_period_id = 1 event_id = 2 payable_balance = PayableBalanceAfterTaxFactory.build() close_balance_entries_after_tax = [payable_balance] ows_client_mock.post( 'ows-payment', f'/worksheet-payable-balance-after-tax/event/{event_id}/statement-period/{statement_period_id}/bulk', # noqa: E501 json=[ { 'worksheet_account_contract_closing_balance_id': payable_balance.worksheet_account_contract_closing_balance_id, 'contract_id': payable_balance.contract_id, 'account_id': payable_balance.account_id, 'payable_amount_pre_tax': str(payable_balance.payable_amount_pre_tax), 'tax_withholding_amount': str(payable_balance.tax_withholding_amount) if payable_balance.tax_withholding_amount is not None else None, 'payable_amount_post_tax': str(payable_balance.payable_amount_post_tax), 'currency_code': payable_balance.currency_code, 'country_of_tax_residence': payable_balance.country_of_tax_residence, 'country_of_tax_policy': payable_balance.country_of_tax_policy, 'vat_amount': str(payable_balance.vat_amount) if payable_balance.vat_amount else None, } ], ).mock(return_value=httpx.Response(status_code=201, json=[])) bulk_create_worksheet_contract_balance_after_tax( event_id, statement_period_id, close_balance_entries_after_tax ) def test_bulk_create_worksheet_contract_balance_after_tax_failure( ows_client_mock: OwsClientMock, ) -> None: """Test failure bulk creating worksheet_contract_balance_after_tax entries.""" statement_period_id = 1 event_id = 2 close_balance_entries_after_tax = [PayableBalanceAfterTaxFactory.build()] ows_client_mock.post( 'ows-payment', f'/worksheet-payable-balance-after-tax/event/{event_id}/statement-period/{statement_period_id}/bulk', # noqa: E501 ).mock(return_value=httpx.Response(status_code=400, json='error')) with pytest.raises( OwsPaymentException, match=f'ERROR from POST /worksheet-payable-balance-after-tax/event/{event_id}/statement-period/{statement_period_id}/bulk', # noqa: E501 ): bulk_create_worksheet_contract_balance_after_tax( event_id, statement_period_id, close_balance_entries_after_tax ) def test_bulk_create_worksheet_payable_details_success( ows_client_mock: OwsClientMock, ) -> None: """Test successfully creating payable details entities.""" statement_period_id = 1 event_id = 2 payable_details_entry = ContractPayableDetailsFactory.build() payable_details_entries = [payable_details_entry] ows_client_mock.post( 'ows-payment', f'/worksheet-account-contract-payable-details/event/{event_id}/statement-period/{statement_period_id}/bulk', # noqa: E501 json=[ { 'worksheet_account_contract_payable_after_tax_id': payable_details_entry.worksheet_account_contract_payable_after_tax_id, 'contract_id': payable_details_entry.contract_id, 'account_id': payable_details_entry.account_id, 'amount_payable': str(payable_details_entry.amount_payable), 'currency': payable_details_entry.currency, 'target_table': payable_details_entry.target_table, 'target_id': payable_details_entry.target_id, 'reference_target_table': payable_details_entry.reference_target_table, 'reference_target_id': payable_details_entry.reference_target_id, 'payable_detail_type_id': payable_details_entry.payable_detail_type_id, } ], ).mock(return_value=httpx.Response(status_code=201, json=[])) bulk_create_contract_payable_details( event_id, statement_period_id, payable_details_entries ) def test_bulk_create_worksheet_payable_details_failure( ows_client_mock: OwsClientMock, ) -> None: """Test failure bulk creating payable details entries.""" statement_period_id = 1 event_id = 2 payable_details = [ContractPayableDetailsFactory.build()] ows_client_mock.post( 'ows-payment', f'/worksheet-account-contract-payable-details/event/{event_id}/statement-period/{statement_period_id}/bulk', # noqa: E501 ).mock(return_value=httpx.Response(status_code=400, json='error')) with pytest.raises( OwsPaymentException, match=f'ERROR from POST /worksheet-account-contract-payable-details/event/{event_id}/statement-period/{statement_period_id}/bulk', # noqa: E501 ): bulk_create_contract_payable_details( event_id, statement_period_id, payable_details ) def test_delete_balance_entries_after_tax(ows_client_mock: OwsClientMock) -> None: """Test failure deleting the payable balance after tax entries.""" event_id = 1 ows_client_mock.delete( 'ows-payment', f'/worksheet-payable-balance-after-tax/event/{event_id}/bulk' ).mock(return_value=httpx.Response(status_code=400, json='error')) with pytest.raises( OwsPaymentException, match=f'ERROR in DELETE /worksheet-payable-balance-after-tax/event/{event_id}/bulk', # noqa: E501 ): delete_balance_entries_after_tax(event_id) def test_delete_payable_details_entries(ows_client_mock: OwsClientMock) -> None: """Test failure deleting the payable balance payable details entries.""" event_id = 1 ows_client_mock.delete( 'ows-payment', f'/worksheet-account-contract-payable-details/event/{event_id}' ).mock(return_value=httpx.Response(status_code=400, json='error')) with pytest.raises( OwsPaymentException, match=f'ERROR in DELETE /worksheet-account-contract-payable-details/event/{event_id}', # noqa: E501 ): delete_payable_details_entries(event_id) def test_get_tax_corrections_success( ows_client_mock: OwsClientMock, faker: Faker ) -> None: """Test get_tax_corrections success.""" correction_type: TaxCorrectionTypes = random.choice( # type: ignore list(TaxCorrectionTypes) ) correction_status: TaxCorrectionStatuses = random.choice( # type: ignore list(TaxCorrectionStatuses) ) limit = faker.pyint() offset = faker.pyint() tax_correction: TaxCorrection = TaxCorrectionFactory.build() path_pattern = ( f'/tax-corrections/{correction_type.value}/{correction_status.value}' f'/?limit={limit}&offset={offset}' # noqa ) ows_client_mock.post( 'ows-payment', path_pattern, json={ 'filters': { 'correction_statement_period_id': tax_correction.correction_statement_period_id, 'contract_ids': [tax_correction.contract_id], } }, ).mock( return_value=httpx.Response( status_code=200, json={ 'items': [tax_correction.model_dump(mode='json')], 'total_count': 1, }, ) ) res = get_tax_corrections( correction_type, correction_status, tax_correction.correction_statement_period_id, [tax_correction.contract_id], limit, offset, ) assert res.items == [tax_correction] assert res.total_count == 1 def test_get_tax_corrections_failure( ows_client_mock: OwsClientMock, faker: Faker ) -> None: """Test get_tax_corrections failure.""" correction_type: TaxCorrectionTypes = random.choice( # type: ignore list(TaxCorrectionTypes) ) correction_status: TaxCorrectionStatuses = random.choice( # type: ignore list(TaxCorrectionStatuses) ) limit = faker.pyint() offset = faker.pyint() tax_correction: TaxCorrection = TaxCorrectionFactory.build() path_pattern = ( f'/tax-corrections/{correction_type.value}/{correction_status.value}' f'/?limit={limit}&offset={offset}' # noqa ) ows_client_mock.post('ows-payment', path_pattern).mock( return_value=httpx.Response(status_code=400, json='error') ) with pytest.raises(OwsPaymentException, match='ERROR in POST /tax-corrections/'): get_tax_corrections( correction_type, correction_status, tax_correction.correction_statement_period_id, [tax_correction.contract_id], limit, offset, ) def test_get_tax_corrections_vat_success( ows_client_mock: OwsClientMock, faker: Faker ) -> None: """Test get_tax_corrections_vat success.""" correction_status: TaxCorrectionStatuses = random.choice( # type: ignore list(TaxCorrectionStatuses) ) limit = faker.pyint() offset = faker.pyint() tax_correction_vat: TaxCorrectionVAT = TaxCorrectionVATFactory.build() path_pattern = ( f'/tax-corrections/vat/{correction_status.value}' f'/?limit={limit}&offset={offset}' # noqa ) ows_client_mock.post( 'ows-payment', path_pattern, json={ 'filters': { 'correction_statement_period_id': tax_correction_vat.correction_statement_period_id, 'contract_ids': [tax_correction_vat.contract_id], } }, ).mock( return_value=httpx.Response( status_code=200, json={ 'items': [tax_correction_vat.model_dump(mode='json')], 'total_count': 1, }, ) ) res = get_tax_corrections_vat( correction_status, tax_correction_vat.correction_statement_period_id, [tax_correction_vat.contract_id], limit, offset, ) assert res.items == [tax_correction_vat] assert res.total_count == 1 def test_get_tax_corrections_vat_failure( ows_client_mock: OwsClientMock, faker: Faker ) -> None: """Test get_tax_corrections_vat failure.""" correction_status: TaxCorrectionStatuses = random.choice( # type: ignore list(TaxCorrectionStatuses) ) limit = faker.pyint() offset = faker.pyint() tax_correction_vat: TaxCorrectionVAT = TaxCorrectionVATFactory.build() path_pattern = ( f'/tax-corrections/vat/{correction_status.value}' f'/?limit={limit}&offset={offset}' # noqa ) ows_client_mock.post('ows-payment', path_pattern).mock( return_value=httpx.Response(status_code=400, json='error') ) with pytest.raises( OwsPaymentException, match='ERROR in POST /tax-corrections/vat/' ): get_tax_corrections_vat( correction_status, tax_correction_vat.correction_statement_period_id, [tax_correction_vat.contract_id], limit, offset, ) def test_get_flowthrough_allocation_entries_success( ows_client_mock: OwsClientMock, faker: Faker ) -> None: """Test get_flowthrough_allocation_entries success.""" flowthrough_allocation = FlowthroughAllocationFactory.build() contract_ids = {faker.pyint(), faker.pyint()} limit = faker.pyint() offset = faker.pyint() path_pattern = ( f'/payment-allocations/flowthrough/bulk?limit={limit}&offset={offset}' # noqa ) ows_client_mock.post( 'ows-payment', path_pattern, json={ 'payment_statuses': PAYABLE_PAYMENT_ALLOCATION_FLOWTHROUGH_STATUSES, 'contract_ids': list(contract_ids), }, ).mock( return_value=httpx.Response( status_code=200, json={ 'items': [flowthrough_allocation.model_dump(mode='json')], 'total_count': 1, }, ) ) res = get_flowthrough_allocation_entries( contract_ids, limit, offset, ) assert res.items == [flowthrough_allocation] assert res.total_count == 1 def test_get_flowthrough_allocation_entries_failure( ows_client_mock: OwsClientMock, faker: Faker ) -> None: """Test get_flowthrough_allocation_entries failure.""" contract_ids = {faker.pyint(), faker.pyint()} limit = faker.pyint() offset = faker.pyint() path_pattern = ( f'/payment-allocations/flowthrough/bulk?limit={limit}&offset={offset}' # noqa ) ows_client_mock.post('ows-payment', path_pattern).mock( return_value=httpx.Response(status_code=400, json='error') ) with pytest.raises( OwsPaymentException, match='ERROR in POST /payment-allocations/flowthrough/bulk', ): get_flowthrough_allocation_entries( contract_ids, limit, offset, ) def test_get_contract_closing_balance_entries_bulk_success( ows_client_mock: OwsClientMock, ) -> None: """Test successfully getting closing balance entries by closing balance ids.""" closing_balance_ids = [11, 22] contract_close_balance = ContractCloseBalanceFactory.build() path = ( f'/worksheet-account-contract-closing-balance/bulk' f'?limit={BATCH_SIZE_REFRESH}&offset=0' ) ows_client_mock.post( 'ows-payment', path, json={'filters': {'worksheet_closing_balance_ids': closing_balance_ids}}, ).mock( return_value=httpx.Response( status_code=200, json={ 'items': [contract_close_balance.model_dump(mode='json')], 'total_count': 1, }, ) ) res = get_contract_closing_balance_entries_bulk(closing_balance_ids) assert isinstance(res, PaginatedContractCloseBalances) assert res.total_count == 1 assert res.items[0].contract_id == contract_close_balance.contract_id def test_get_contract_closing_balance_entries_bulk_failure( ows_client_mock: OwsClientMock, ) -> None: """Test failure getting closing balance entries by closing balance ids.""" closing_balance_ids = [11, 22] path = ( f'/worksheet-account-contract-closing-balance/bulk' f'?limit={BATCH_SIZE_REFRESH}&offset=0' ) ows_client_mock.post('ows-payment', path).mock( return_value=httpx.Response(status_code=400, json='error') ) with pytest.raises( OwsPaymentException, match='ERROR in POST /worksheet-account-contract-closing-balance/bulk', ): get_contract_closing_balance_entries_bulk(closing_balance_ids) def test_get_payable_details_entries_success(ows_client_mock: OwsClientMock) -> None: """Test successfully getting payable details by after-tax ids and detail groups.""" statement_period_id = 5 after_tax_ids = [1, 2] detail = PayableDetailEntryFactory.build() path = ( f'/worksheet-account-contract-payable-details/statement-period' f'/{statement_period_id}/?limit={BATCH_SIZE}&offset=0' ) ows_client_mock.post( 'ows-payment', path, json={ 'filters': { 'worksheet_payable_after_tax_ids': after_tax_ids, 'detail_groups': CORRECTION_DETAIL_GROUPS, } }, ).mock( return_value=httpx.Response( status_code=200, json={'items': [detail.model_dump(mode='json')], 'total_count': 1}, ) ) res = get_payable_details_entries( statement_period_id, after_tax_ids, CORRECTION_DETAIL_GROUPS ) assert isinstance(res, PaginatedPayableDetailEntries) assert res.items == [detail] assert res.total_count == 1 def test_get_payable_details_entries_failure(ows_client_mock: OwsClientMock) -> None: """Test failure getting payable details by after-tax ids and detail groups.""" statement_period_id = 5 after_tax_ids = [1, 2] path = ( f'/worksheet-account-contract-payable-details/statement-period' f'/{statement_period_id}/?limit={BATCH_SIZE}&offset=0' ) ows_client_mock.post('ows-payment', path).mock( return_value=httpx.Response(status_code=400, json='error') ) with pytest.raises( OwsPaymentException, match='ERROR in POST /worksheet-account-contract-payable-details/statement-period', # noqa: E501 ): get_payable_details_entries( statement_period_id, after_tax_ids, CORRECTION_DETAIL_GROUPS ) def test_bulk_update_worksheet_contract_balance_after_tax_success( ows_client_mock: OwsClientMock, ) -> None: """Test successfully bulk updating worksheet payable balance after tax.""" entry = PayableBalanceAfterTaxBulkUpdate( worksheet_account_contract_payable_after_tax_id=1, tax_withholding_amount=Decimal('-10'), vat_amount=None, payable_amount_post_tax=Decimal('990'), ) ows_client_mock.put( 'ows-payment', '/worksheet-payable-balance-after-tax/bulk' ).mock(return_value=httpx.Response(status_code=200, json=[])) bulk_update_worksheet_contract_balance_after_tax([entry]) def test_bulk_update_worksheet_contract_balance_after_tax_failure( ows_client_mock: OwsClientMock, ) -> None: """Test failure bulk updating worksheet payable balance after tax.""" entry = PayableBalanceAfterTaxBulkUpdate( worksheet_account_contract_payable_after_tax_id=1, payable_amount_post_tax=Decimal('990'), ) ows_client_mock.put( 'ows-payment', '/worksheet-payable-balance-after-tax/bulk' ).mock(return_value=httpx.Response(status_code=400, json='error')) with pytest.raises( OwsPaymentException, match='ERROR from PUT /worksheet-payable-balance-after-tax/bulk', ): bulk_update_worksheet_contract_balance_after_tax([entry]) def test_delete_payable_details_wht_vat_corrections_success( ows_client_mock: OwsClientMock, ) -> None: """Test successfully soft deleting wht/vat correction payable details.""" after_tax_ids = [1, 2] ows_client_mock.delete( 'ows-payment', '/worksheet-account-contract-payable-details/bulk' ).mock(return_value=httpx.Response(status_code=204)) delete_payable_details_wht_vat_corrections(after_tax_ids) def test_delete_payable_details_wht_vat_corrections_failure( ows_client_mock: OwsClientMock, ) -> None: """Test failure soft deleting wht/vat correction payable details.""" after_tax_ids = [1, 2] ows_client_mock.delete( 'ows-payment', '/worksheet-account-contract-payable-details/bulk' ).mock(return_value=httpx.Response(status_code=400, json='error')) with pytest.raises( OwsPaymentException, match='ERROR in DELETE /worksheet-account-contract-payable-details/bulk', ): delete_payable_details_wht_vat_corrections(after_tax_ids)