"""payment_group_payment_account repository tests.""" from abacus_common_logic.connectors.database import db from sqlalchemy import func, select, update from payment.models.payment_group_payment_account import PaymentGroupPaymentAccount from payment.repository import payment_group_payment_account as repository from tests.utils.factories import ( PaymentGroupPaymentAccountDetailFactory, PaymentGroupPaymentAccountFactory, PaymentGroupPaymentBatchAccountFactory, PaymentGroupPaymentBatchFactory, PaymentGroupPaymentFactory, ) def test_get_last_payments_no_payments( mock_abacus_event, mock_statement_periods, mock_accounts, mock_contracts, mock_worksheet_account_contract_closing_balance, create_mock_payment_state, ): """Test get_last_payments function.""" payment_group_payment_1 = PaymentGroupPaymentFactory.create( # state - complete payment_group_payment_id=1, ) payment_group_payment_2 = PaymentGroupPaymentFactory.create( # state - init payment_group_payment_id=2, ) # state - rejected (account 1, payment 1) payment_group_payment_account_1 = PaymentGroupPaymentAccountFactory.create( account_id=1, current_statement_period_id=1, payment_group_payment_account_id=3, payment_group_payment=payment_group_payment_1, ) # state - init (account 1, payment 2) payment_group_payment_account_2 = PaymentGroupPaymentAccountFactory.create( account_id=1, current_statement_period_id=2, payment_group_payment_account_id=1, payment_group_payment=payment_group_payment_2, ) # state - init (account 2, payment 2) payment_group_payment_account_3 = PaymentGroupPaymentAccountFactory.create( account_id=2, current_statement_period_id=1, payment_group_payment_account_id=2, payment_group_payment=payment_group_payment_2, ) # state - complete payment_group_payment_batch = PaymentGroupPaymentBatchFactory.create( payment_group_payment_batch_id=2 ) PaymentGroupPaymentBatchAccountFactory.create( payment_group_payment_batch=payment_group_payment_batch, payment_group_payment_account=payment_group_payment_account_1, ) PaymentGroupPaymentBatchAccountFactory.create( payment_group_payment_batch=payment_group_payment_batch, payment_group_payment_account=payment_group_payment_account_2, ) PaymentGroupPaymentBatchAccountFactory.create( payment_group_payment_batch=payment_group_payment_batch, payment_group_payment_account=payment_group_payment_account_3, ) for account_id in [1, 2]: items, total_count = repository.get_last_payments(100, 0, [account_id]) assert items == [] assert total_count == 0 def test_get_last_payments_deleted_payment( mock_abacus_event, mock_statement_periods, mock_accounts, mock_contracts, mock_worksheet_account_contract_closing_balance, create_mock_payment_state, faker, ): """Test get_last_payments function.""" payment_group_payment = PaymentGroupPaymentFactory.create( # state - complete payment_group_payment_id=1, ) payment_group_payment_account = PaymentGroupPaymentAccountFactory.create( deleted_at=faker.past_datetime(), account_id=7, current_statement_period_id=2, payment_group_payment_account_id=7, payment_group_payment=payment_group_payment, ) payment_group_payment_batch = PaymentGroupPaymentBatchFactory.create( payment_group_payment_batch_id=3 ) PaymentGroupPaymentBatchAccountFactory.create( payment_group_payment_batch=payment_group_payment_batch, payment_group_payment_account=payment_group_payment_account, ) items, total_count = repository.get_last_payments(100, 0, [7]) assert items == [] assert total_count == 0 def test_get_last_payments_batch_has_not_completed_state( mock_abacus_event, mock_statement_periods, mock_accounts, mock_contracts, mock_worksheet_account_contract_closing_balance, create_mock_payment_state, ): """Test get_last_payments function.""" payment_group_payment = PaymentGroupPaymentFactory.create( # state - complete payment_group_payment_id=1, ) payment_group_payment_account = PaymentGroupPaymentAccountFactory.create( account_id=1, current_statement_period_id=2, payment_group_payment_account_id=1, payment_group_payment=payment_group_payment, ) payment_group_payment_batch = PaymentGroupPaymentBatchFactory.create( payment_group_payment_batch_id=1 ) PaymentGroupPaymentBatchAccountFactory.create( payment_group_payment_batch=payment_group_payment_batch, payment_group_payment_account=payment_group_payment_account, ) items, total_count = repository.get_last_payments(100, 0, [1]) assert items == [] assert total_count == 0 def test_get_last_payments_payment_account_last_statement_period_null( mock_abacus_event, mock_statement_periods, mock_accounts, mock_contracts, mock_worksheet_account_contract_closing_balance, create_mock_payment_state, ): """Test get_last_payments function.""" payment_group_payment_account = PaymentGroupPaymentAccountFactory.create( account_id=1, payment_group_payment_account_id=1, ) payment_group_payment_batch = PaymentGroupPaymentBatchFactory.create( payment_group_payment_batch_id=3 ) PaymentGroupPaymentBatchAccountFactory.create( payment_group_payment_batch=payment_group_payment_batch, payment_group_payment_account=payment_group_payment_account, ) items, total_count = repository.get_last_payments(100, 0, [1]) assert items == [] assert total_count == 0 def test_get_last_payments_deleted_payment_group_payment( mock_abacus_event, mock_statement_periods, mock_accounts, mock_contracts, mock_worksheet_account_contract_closing_balance, create_mock_payment_state, faker, ): """Test get_last_payments excludes deleted payment_group_payment.""" payment_group_payment = PaymentGroupPaymentFactory.create( payment_group_payment_id=1, deleted_at=faker.past_datetime(), ) payment_group_payment_account = PaymentGroupPaymentAccountFactory.create( account_id=7, current_statement_period_id=2, payment_group_payment_account_id=7, payment_group_payment=payment_group_payment, ) payment_group_payment_batch = PaymentGroupPaymentBatchFactory.create( payment_group_payment_batch_id=3 ) PaymentGroupPaymentBatchAccountFactory.create( payment_group_payment_batch=payment_group_payment_batch, payment_group_payment_account=payment_group_payment_account, ) items, total_count = repository.get_last_payments(100, 0, [7]) assert items == [] assert total_count == 0 def test_get_last_payments_payoneer_program_id_zero( mock_abacus_event, mock_statement_periods, mock_accounts, mock_contracts, mock_worksheet_account_contract_closing_balance, create_mock_payment_state, ): """Test get_last_payments excludes payoneer_program_id = 0.""" payment_group_payment = PaymentGroupPaymentFactory.create( payment_group_payment_id=1, ) payment_group_payment_account = PaymentGroupPaymentAccountFactory.create( account_id=7, current_statement_period_id=2, payment_group_payment_account_id=7, payment_group_payment=payment_group_payment, payoneer_program_id=0, ) payment_group_payment_batch = PaymentGroupPaymentBatchFactory.create( payment_group_payment_batch_id=3 ) PaymentGroupPaymentBatchAccountFactory.create( payment_group_payment_batch=payment_group_payment_batch, payment_group_payment_account=payment_group_payment_account, ) items, total_count = repository.get_last_payments(100, 0, [7]) assert items == [] assert total_count == 0 def test_get_last_payments_with_prior_payment( mock_abacus_event, mock_statement_periods, mock_accounts, mock_contracts, mock_worksheet_account_contract_closing_balance, create_mock_payment_state, ): """Test get_last_payments excludes payments with prior_payment_group_payment_id.""" payment_group_payment = PaymentGroupPaymentFactory.create( payment_group_payment_id=1, ) payment_group_payment_account = PaymentGroupPaymentAccountFactory.create( account_id=7, current_statement_period_id=2, payment_group_payment_account_id=7, payment_group_payment=payment_group_payment, prior_payment_group_payment_id=999, ) payment_group_payment_batch = PaymentGroupPaymentBatchFactory.create( payment_group_payment_batch_id=3 ) PaymentGroupPaymentBatchAccountFactory.create( payment_group_payment_batch=payment_group_payment_batch, payment_group_payment_account=payment_group_payment_account, ) items, total_count = repository.get_last_payments(100, 0, [7]) assert items == [] assert total_count == 0 def test_get_last_payments_payment_group_payment_not_complete( mock_abacus_event, mock_statement_periods, mock_accounts, mock_contracts, mock_worksheet_account_contract_closing_balance, create_mock_payment_state, ): """Test get_last_payments requires payment_group_payment state = complete.""" payment_group_payment = PaymentGroupPaymentFactory.create( # state - init (not complete) payment_group_payment_id=2, ) payment_group_payment_account = PaymentGroupPaymentAccountFactory.create( account_id=1, current_statement_period_id=2, payment_group_payment_account_id=1, payment_group_payment=payment_group_payment, ) payment_group_payment_batch = PaymentGroupPaymentBatchFactory.create( payment_group_payment_batch_id=3 ) PaymentGroupPaymentBatchAccountFactory.create( payment_group_payment_batch=payment_group_payment_batch, payment_group_payment_account=payment_group_payment_account, ) items, total_count = repository.get_last_payments(100, 0, [1]) assert items == [] assert total_count == 0 def test_get_last_payments_missing_batch_account( mock_abacus_event, mock_statement_periods, mock_accounts, mock_contracts, mock_worksheet_account_contract_closing_balance, create_mock_payment_state, ): """Test get_last_payments requires payment_group_payment_batch_account join.""" payment_group_payment = PaymentGroupPaymentFactory.create( payment_group_payment_id=1, ) payment_group_payment_account = PaymentGroupPaymentAccountFactory.create( account_id=7, current_statement_period_id=2, payment_group_payment_account_id=7, payment_group_payment=payment_group_payment, ) # No PaymentGroupPaymentBatchAccount created - missing join items, total_count = repository.get_last_payments(100, 0, [7]) assert items == [] assert total_count == 0 def test_get_last_payments_returns_max_statement_period( mock_abacus_event, mock_statement_periods, mock_accounts, mock_contracts, mock_worksheet_account_contract_closing_balance, create_mock_payment_state, ): """Test get_last_payments returns payment with MAX(current_statement_period_id) for each account.""" payment_group_payment_1 = PaymentGroupPaymentFactory.create( payment_group_payment_id=1, ) payment_group_payment_2 = PaymentGroupPaymentFactory.create( payment_group_payment_id=3, ) # Create two payments for account 9 with different statement periods payment_group_payment_account_old = PaymentGroupPaymentAccountFactory.create( account_id=9, current_statement_period_id=1, payment_group_payment_account_id=9, payment_group_payment=payment_group_payment_1, ) payment_group_payment_account_new = PaymentGroupPaymentAccountFactory.create( account_id=9, current_statement_period_id=2, payment_group_payment_account_id=10, payment_group_payment=payment_group_payment_2, ) payment_group_payment_batch_1 = PaymentGroupPaymentBatchFactory.create( payment_group_payment_batch_id=3 ) PaymentGroupPaymentBatchAccountFactory.create( payment_group_payment_batch=payment_group_payment_batch_1, payment_group_payment_account=payment_group_payment_account_old, ) payment_group_payment_batch_2 = PaymentGroupPaymentBatchFactory.create( payment_group_payment_batch_id=6 ) PaymentGroupPaymentBatchAccountFactory.create( payment_group_payment_batch=payment_group_payment_batch_2, payment_group_payment_account=payment_group_payment_account_new, ) items, total_count = repository.get_last_payments(100, 0, [9]) assert total_count == 1 assert len(items) == 1 # Should return the payment with period_id=2 (the newer one) assert items[0].payment_group_payment_account_id == 10 assert items[0].current_statement_period_id == 2 def test_get_last_payments_valid_last_payment( mock_abacus_event, mock_statement_periods, mock_accounts, mock_contracts, mock_worksheet_account_contract_closing_balance, create_mock_payment_state, faker, ): """Test get_last_payments function.""" payment_group_payment = PaymentGroupPaymentFactory.create( # state - complete payment_group_payment_id=1, ) payment_group_payment_account = PaymentGroupPaymentAccountFactory.create( # deleted_at=faker.past_datetime(), account_id=7, current_statement_period_id=2, payment_group_payment_account_id=7, payment_group_payment=payment_group_payment, ) payment_group_payment_batch = PaymentGroupPaymentBatchFactory.create( payment_group_payment_batch_id=3 ) PaymentGroupPaymentBatchAccountFactory.create( payment_group_payment_batch=payment_group_payment_batch, payment_group_payment_account=payment_group_payment_account, ) items, total_count = repository.get_last_payments(100, 0, [7]) assert items == [payment_group_payment_account] assert total_count == 1 def test_get_payment_group_payment_account_status_overviews(mock_payments): """Test to get payment_group_payment_account's payment status overview.""" payment_group_payment_id = 501 res = repository.get_payment_group_payment_account_status_overviews( [payment_group_payment_id] ) assert isinstance(res, list) assert len(res) == 1 res = res[0] assert int(res.payment_group_payment_id) == payment_group_payment_id assert int(res.number_of_canceled_payments) == 1 assert int(res.number_of_failed_payments) == 1 assert int(res.number_of_pending_payments) == 2 assert int(res.number_of_successful_payments) == 1 assert int(res.number_of_payments_failed_with_batch) == 2 def test_payments_search_no_filters(mock_payments): """Test payments search function.""" account_ids = [] contract_ids = [] payment_statuses = [] items, total_count = repository.payments_search( 300, 0, account_ids, contract_ids, payment_statuses, ) assert total_count == 8 assert len(items) == 8 items, total_count = repository.payments_search( 1, 0, account_ids, contract_ids, payment_statuses, ) assert total_count == 8 assert len(items) == 1 items, total_count = repository.payments_search( 300, 7, account_ids, contract_ids, payment_statuses, ) assert total_count == 8 assert len(items) == 1 def test_payments_search_with_filters(mock_payments): """Test payments search function with filters.""" # filter by payment_statuses account_ids = [] contract_ids = [] payment_statuses = ['complete', 'error'] items, total_count = repository.payments_search( 300, 0, account_ids, contract_ids, payment_statuses, ) assert total_count == 2 assert len(items) == 2 assert items[0].account_id == 6 assert items[1].account_id == 7 # filter by account_ids account_ids = [1] contract_ids = [] payment_statuses = [] items, total_count = repository.payments_search( 300, 0, account_ids, contract_ids, payment_statuses, ) assert total_count == 1 assert len(items) == 1 assert items[0].account_id == 1 # filter by contract_ids account_ids = [] contract_ids = [2] payment_statuses = [] items, total_count = repository.payments_search( 300, 0, account_ids, contract_ids, payment_statuses, ) assert total_count == 1 assert len(items) == 1 assert len(items[0].details) == 1 assert items[0].details[0].contract_id == 2 # filter by all filters account_ids = [1] contract_ids = [1] payment_statuses = ['init'] items, total_count = repository.payments_search( 300, 0, account_ids, contract_ids, payment_statuses, ) assert total_count == 1 assert len(items) == 1 assert len(items[0].details) == 1 assert items[0].details[0].contract_id == 1 def test_payments_search_only_active(mock_payments): """Test payments search function only active records.""" account_ids = [] contract_ids = [] payment_statuses = [] db.session.execute( update(PaymentGroupPaymentAccount) .values(deleted_at=func.now(), deleted_by='test user') .execution_options(synchronize_session=False) ) db.session.commit() items, total_count = repository.payments_search( 300, 0, account_ids, contract_ids, payment_statuses, ) assert total_count == 0 assert len(items) == 0 def test_payments_search_exclude_items_that_have_pending_payments(mock_payments): """Test payments search function pending payments case.""" db.session.execute( update(PaymentGroupPaymentAccount) .where(PaymentGroupPaymentAccount.account_id == 1) .values(prior_payment_group_payment_id=100) .execution_options(synchronize_session=False) ) db.session.commit() account_ids = [] contract_ids = [] payment_statuses = [] items, total_count = repository.payments_search( 300, 0, account_ids, contract_ids, payment_statuses, ) assert total_count == 7 assert len(items) == 7 assert 1 not in [item.account_id for item in items]