"""Functional tests for POST /abacus-statement-period//dp-payment-transactions endpoint.""" from datetime import date import http import json from sqlalchemy import select from collaborator.connectors import mysql from collaborator.constants import error from collaborator.constants.features import ABACUS_COLLABORATORS from collaborator.constants.transaction import TransactionType from collaborator.models.rds.dp_payment import DpPayment from collaborator.models.rds.transaction import Transaction from tests.testutils import db, mock_auth @mysql.db_session def _get_dp_balance_payment_transactions(session): query = ( select( Transaction.collaborator_id, Transaction.statement_period_id, Transaction.currency, Transaction.description, Transaction.transaction_type, Transaction.original_amount, Transaction.chargeable_amount, Transaction.date, ) .where( Transaction.transaction_type == TransactionType.DIRECT_PAYMENT, Transaction.description == "Jan 2026 Balance Payment", ) .order_by(Transaction.collaborator_id.asc()) ) return session.execute(query).all() @mysql.db_session def _get_transaction_count(session): return session.query(Transaction).count() @mysql.db_session def _get_dp_payments_with_transaction_ids(abacus_statement_period_id, session): """Get DpPayment records for the given statement period with transaction IDs.""" query = ( select( DpPayment.collaborator_id, DpPayment.collaborator_transaction_id, ) .where( DpPayment.abacus_statement_period_id == abacus_statement_period_id, DpPayment.collaborator_transaction_id.isnot(None), ) .order_by(DpPayment.collaborator_id.asc()) ) return session.execute(query).all() @db.test_schema_default_seed def test_post_dp_payment_transactions_success( auth_client, mock_features, mock_account, mocker ): """Test successfully creating DP payment transactions for a statement period.""" abacus_statement_period_id = 1 mock_auth(mocker, mock_account.id) mock_features({ABACUS_COLLABORATORS: True}) result = auth_client.post( f"/abacus-statement-period/{abacus_statement_period_id}/dp-payment-transactions" ) assert result.status_code == http.HTTPStatus.NO_CONTENT transactions = _get_dp_balance_payment_transactions() assert len(transactions) == 2 assert transactions[0].collaborator_id == 1 assert transactions[0].statement_period_id == 2 assert transactions[0].currency == "USD" assert transactions[0].description == "Jan 2026 Balance Payment" assert transactions[0].transaction_type == TransactionType.DIRECT_PAYMENT assert float(transactions[0].original_amount) == -1500.00 assert float(transactions[0].chargeable_amount) == -1500.00 assert transactions[0].date == date.today() assert transactions[1].collaborator_id == 2 assert transactions[1].statement_period_id == 2 assert transactions[1].currency == "USD" assert transactions[1].description == "Jan 2026 Balance Payment" assert transactions[1].transaction_type == TransactionType.DIRECT_PAYMENT assert float(transactions[1].original_amount) == -2750.50 assert float(transactions[1].chargeable_amount) == -2750.50 assert transactions[1].date == date.today() # Verify DpPayment records were updated with transaction IDs dp_payments = _get_dp_payments_with_transaction_ids(abacus_statement_period_id) assert len(dp_payments) == 3 assert dp_payments[0].collaborator_id == 1 assert dp_payments[0].collaborator_transaction_id is not None assert dp_payments[1].collaborator_id == 2 assert dp_payments[1].collaborator_transaction_id is not None @db.test_schema_default_seed def test_post_dp_payment_transactions_feature_disabled( auth_client, mock_account, mocker ): """Test POST returns 403 when feature flag is disabled.""" abacus_statement_period_id = 1 mock_auth(mocker, mock_account.id) result = auth_client.post( f"/abacus-statement-period/{abacus_statement_period_id}/dp-payment-transactions" ) assert result.status_code == http.HTTPStatus.FORBIDDEN result_data = json.loads(result.data.decode()) assert result_data["code"] == error.ERROR_CODE_AUTHORIZATION assert result_data["message"] == error.ERROR_MESSAGE_FORBIDDEN_USER @db.test_schema_default_seed def test_post_dp_payment_transactions_no_matching_payments( auth_client, mock_features, mock_account, mocker ): """Test POST returns 204 and does not create transactions when no DP payments match.""" abacus_statement_period_id = 324 mock_auth(mocker, mock_account.id) mock_features({ABACUS_COLLABORATORS: True}) transaction_count_before = _get_transaction_count() result = auth_client.post( f"/abacus-statement-period/{abacus_statement_period_id}/dp-payment-transactions" ) assert result.status_code == http.HTTPStatus.NO_CONTENT transaction_count_after = _get_transaction_count() assert transaction_count_after == transaction_count_before