"""Shared fixtures for tests.""" from datetime import datetime import pytest from abacus_common_logic.connectors.database import db from abacus_common_logic.db.adapters import get_adapter from abacus_contract.constants import constants from abacus_contract.tests.utils.factories import ( AccountContractFactory, ContractAdvanceFactory, ContractFactory, ContractLifecycleFactory, ReferencePaymentEntityFactory, ReferenceSapProfitCenterFactory, ReferenceSigningEntityFactory, ) from royalties.tests.utils.factories import ( AccountingRunFactory, RunControllerContractFactory, RunControllerFactory, StatementPeriodFactory, ) # --- DB --- @pytest.fixture def fresh_db(): """Refresh the test database.""" top_level_tables = ( 'accounting_period', 'accounting_run', 'run_controller', 'run_controller_contract', 'legacy_contract', 'contract', 'abacus_event', 'abacus_state', 'account_contract', 'account_payee', 'account_payment_term', 'account_tax_info', 'account', 'contract_advance', 'contract_flowthrough', 'contract_lifecycle_schedule_detail', 'contract_lifecycle_schedule', 'contract_lifecycle', 'contract_mechanical_deduction', 'contract_party', 'contract_term', 'contract_term_condition', 'contract_term_schedule', 'contract_term_schedule_history', 'contract_template', 'contract_exclusion', 'contract_reserve', 'historical_contract_advance', 'ledger_account_contract', 'ledger_accounting_run_balance', 'ledger_contract_advance_applied', 'worksheet_adjustment', 'reference_flowthrough_calculation', 'signing_entity_sap_profit_center', 'reference_sap_profit_center', 'reference_signing_entity', 'reference_payment_entity', 'schedule', 'statement_period', 'reference_flowthrough_calculation', 'reference_mechanical_rate', 'reference_payment_type', 'reference_transaction_type_group_transaction_type', 'reference_transaction_type_group', 'reference_transaction_type', ) with db.engine.connect() as conn: get_adapter(conn).truncate_tables(conn, top_level_tables) # --- Mocks --- @pytest.fixture def create_mock_account(): """Create mock account rows.""" ADD_ACCOUNT = """ INSERT INTO account( `account_id`, `account_name`, `created_by`, `created_at`, `last_modified_by`, `last_modified` ) VALUES (1, 'Test Account 1', '11', CURRENT_TIMESTAMP, '11', CURRENT_TIMESTAMP), (2, 'Test Account 2', '22', CURRENT_TIMESTAMP, '22', CURRENT_TIMESTAMP), (3, 'Test Account 3', '33', CURRENT_TIMESTAMP, '33', CURRENT_TIMESTAMP) """ db.engine.execute(ADD_ACCOUNT) @pytest.fixture def create_mock_account_payee(): """Create mock payee and account_payee rows.""" ADD_ACCOUNT_PAYEE = """ INSERT INTO account_payee( `account_id`, `created_by`, `created_at`, `last_modified_by`, `last_modified` ) VALUES (1, 'QA', CURRENT_TIMESTAMP, 'QA', CURRENT_TIMESTAMP), (2, 'QA', CURRENT_TIMESTAMP, 'QA', CURRENT_TIMESTAMP)""" db.engine.execute(ADD_ACCOUNT_PAYEE) @pytest.fixture def create_mock_account_payment_term(): """Create mock account_payment_term rows.""" mock_reference_payment_entity = ReferencePaymentEntityFactory.create() ADD_ACCOUNT_PAYMENT_TERM = """ INSERT INTO account_payment_term( `account_payment_term_id`, `account_id`, `currency_code`, `payment_minimum`, `payment_entity_id`, `payment_schedule`, `created_by`, `created_at`, `last_modified_by`, `last_modified` ) VALUES (1, 1, 'USD', NULL, {}, '30_days_after_month_end', '', CURRENT_TIMESTAMP, '', CURRENT_TIMESTAMP), (2, 2, 'USD', NULL, {}, '30_days_after_month_end', '', CURRENT_TIMESTAMP, '', CURRENT_TIMESTAMP); """ db.engine.execute( ADD_ACCOUNT_PAYMENT_TERM.format( mock_reference_payment_entity.reference_payment_entity_id, mock_reference_payment_entity.reference_payment_entity_id, ) ) @pytest.fixture def create_mock_reference_sap_profit_center(): """Create mock reference_sap_profit_center rows.""" return ReferenceSapProfitCenterFactory.create() @pytest.fixture def create_mock_reference_signing_entity(): """Create mock reference_signing_entity rows.""" mock_reference_signing_entity = ReferenceSigningEntityFactory.create( company_code='4378' ) ReferenceSapProfitCenterFactory.create( company_code=mock_reference_signing_entity.company_code ) return mock_reference_signing_entity @pytest.fixture def create_mock_contract(create_mock_reference_sap_profit_center): """Create mock contract rows.""" ADD_CONTRACT = """ INSERT INTO contract( `contract_id`, `contract_name`, `contract_type`, `term_start`, `term_end`, `reference_signing_entity_id`, `created_by`, `created_at`, `last_modified_by`, `last_modified` ) VALUES (1, 'Test contract', 'distribution', '2021-01-01', '2022-01-01', 1, '', CURRENT_TIMESTAMP, '', CURRENT_TIMESTAMP), (2, 'Contract test', 'distribution', '2021-01-01', '2022-01-01', 1, '', CURRENT_TIMESTAMP, '', CURRENT_TIMESTAMP) """ db.engine.execute(ADD_CONTRACT) @pytest.fixture def create_mock_run_controller(): """Create mock run_controller and run_controller_contract rows.""" RunControllerFactory.create( run_controller_id=1, run_controller_name='Default Run Controller' ) RunControllerFactory.create( run_controller_id=2, run_controller_name='Second Run Controller' ) return True def create_mock_run_controller_contract(contracts): """Create mock run_controller_contracts.""" first_run_controller = RunControllerFactory.create( run_controller_name='Default Run Controller' ) RunControllerFactory.create(run_controller_name='Second Run Controller') for contract in contracts: RunControllerContractFactory.create( run_controller=first_run_controller, contract=contract ) return True @pytest.fixture def create_mock_account_tax_info(): """Create mock account_tax_info.""" ADD_ACCOUNT_TAX_INFO = """ INSERT INTO account_tax_info( `account_tax_info_id`, `account_id`, `country_of_tax_residence`, `is_sba_signed`, `created_by`, `created_at`, `last_modified_by`, `last_modified` ) VALUES (1, 1, 'GBR', 1, '2', CURRENT_TIMESTAMP, '2', CURRENT_TIMESTAMP), (2, 2, 'GBR', 0, '2', CURRENT_TIMESTAMP, '2', CURRENT_TIMESTAMP) """ db.engine.execute(ADD_ACCOUNT_TAX_INFO) @pytest.fixture def create_mock_abacus_event(): """Create mock abacus_event.""" ADD_ABACUS_EVENT = """ INSERT INTO abacus_event ( `abacus_event_id`, `statement_period_id`, `event_date`, `event_name`, `target_type`, `target_id`, `created_by` ) VALUES ( 1, 1, '2022-09-13', 'confirm_advance_payment', 'contract', 1, 'Test' ), ( 2, 1, '2022-09-16', 'confirm_advance_payment', 'contract', 2, 'Test' ), ( 3, 1, '2022-09-16', 'commit_to_subledger', 'contract', 3, 'Test' ), ( 4, 1, '2022-09-16', 'accounting_run_calculate', 'accounting_run', 6, 'Test' ) """ db.engine.execute(ADD_ABACUS_EVENT) @pytest.fixture def create_mock_statement_period(): """Insert statement period data.""" StatementPeriodFactory.create( statement_period_id=1, statement_period_name='Jan 20', statement_period_status='current', ) StatementPeriodFactory.create( statement_period_id=2, statement_period_name='Feb 20', statement_period_status='open', ) @pytest.fixture def create_mock_paid_advances( create_mock_statement_period, create_mock_account, create_mock_abacus_event ): """Create mock paid advances.""" contract = ContractFactory.create(contract_id=1) ContractAdvanceFactory.create( contract=contract, advance_status=constants.ADVANCE_STATUSES.PAID ) ContractAdvanceFactory.create( contract_id=2, advance_description='Advance Description', amount=11290.90, currency_code='CAD', milestone=constants.MILESTONES.DELIVERY, milestone_description='Milestone Description', milestone_date='2022-09-30', advance_status=constants.ADVANCE_STATUSES.PAID, ) ContractAdvanceFactory.create( contract=contract, advance_status=constants.ADVANCE_STATUSES.PENDING_PAYMENT ) LEDGER_CONTRACT_ADVANCE_APPLIED = """ INSERT INTO ledger_contract_advance_applied ( `abacus_event_id`, `account_id`, `contract_id`, `contract_advance_id`, `statement_period_id`, `advance_amount`, `advance_currency_code`, `advance_amount_payee_currency`, `advance_payee_currency_code`, `created_by`, `created_at`, `last_modified_by`, `last_modified` ) VALUES (1, 1, 1, 1, 1, '100.00', 'USD', '100.00','USD', '2', CURRENT_TIMESTAMP, '2', CURRENT_TIMESTAMP), (2, 1, 2, 2, 1, '11290.90', 'CAD', '11765.28','AUD', '2', CURRENT_TIMESTAMP, '2', CURRENT_TIMESTAMP), (1, 1, 1, 3, 1, '101.00', 'USD', '101.00','USD', '2', CURRENT_TIMESTAMP, '2', CURRENT_TIMESTAMP) """ db.engine.execute(LEDGER_CONTRACT_ADVANCE_APPLIED) @pytest.fixture def create_mock_paid_advances_with_worksheets_logic( create_mock_statement_period, create_mock_account, create_mock_abacus_event ): """Create mock paid advances with worksheets logic.""" mock_contract = ContractFactory.create() ContractAdvanceFactory.create( contract=mock_contract, advance_status=constants.ADVANCE_STATUSES.PAID ) ContractAdvanceFactory.create(advance_status=constants.ADVANCE_STATUSES.PAID) ContractAdvanceFactory.create( contract=mock_contract, advance_status=constants.ADVANCE_STATUSES.PENDING_PAYMENT, ) LEDGER_CONTRACT_ADVANCE_APPLIED = """ INSERT INTO ledger_contract_advance_applied ( `abacus_event_id`, `account_id`, `contract_id`, `contract_advance_id`, `statement_period_id`, `advance_amount`, `advance_currency_code`, `advance_amount_payee_currency`, `advance_payee_currency_code`, `created_by`, `created_at`, `last_modified_by`, `last_modified` ) VALUES (1, 1, 1, 1, 1, '100.00', 'USD', '100.00','USD', '2', CURRENT_TIMESTAMP, '2', CURRENT_TIMESTAMP), (2, 1, 2, 2, 1, '11290.90', 'CAD', '11765.28','AUD', '2', CURRENT_TIMESTAMP, '2', CURRENT_TIMESTAMP), (3, 1, 1, 3, 1, '101.00', 'USD', '101.00','USD', '2', CURRENT_TIMESTAMP, '2', CURRENT_TIMESTAMP) """ db.engine.execute(LEDGER_CONTRACT_ADVANCE_APPLIED) @pytest.fixture def create_mock_paid_advances_previously_failed_worksheets( create_mock_statement_period, create_mock_account, create_mock_abacus_event ): """Create mock paid advances with previously rejected worksheets.""" mock_contract = ContractFactory.create() ContractAdvanceFactory.create( contract=mock_contract, advance_status=constants.ADVANCE_STATUSES.PAID ) ABACUS_STATE = """ INSERT INTO abacus_state ( `abacus_state_id`, `action_name`, `action_status`, `parent_table_name`, `parent_table_id`, `created_by`, `created_at`, `last_modified_by`, `last_modified` ) VALUES ( 1, 'send_payments', 'rejected', 'worksheet_payment_contract_advance', 1, '2', CURRENT_TIMESTAMP, '2', CURRENT_TIMESTAMP ), ( 2, 'send_payments', 'complete', 'worksheet_payment_contract_advance', 2, '2', CURRENT_TIMESTAMP, '2', CURRENT_TIMESTAMP ) """ LEDGER_CONTRACT_ADVANCE_APPLIED = """ INSERT INTO ledger_contract_advance_applied ( `abacus_event_id`, `account_id`, `contract_id`, `contract_advance_id`, `worksheet_payment_contract_advance_id`, `statement_period_id`, `advance_amount`, `advance_currency_code`, `advance_amount_payee_currency`, `advance_payee_currency_code`, `created_by`, `created_at`, `last_modified_by`, `last_modified` ) VALUES (1, 1, 1, 1, 1, 1, '100.00', 'USD', '100.00','USD', '2', CURRENT_TIMESTAMP, '2', CURRENT_TIMESTAMP), (2, 1, 1, 1, 1, 1, '-100.00', 'USD', '-100.00', 'USD', '2', CURRENT_TIMESTAMP, '2', CURRENT_TIMESTAMP), (3, 1, 1, 1, 2, 1, '100.00', 'USD', '120.00','AUD', '2', CURRENT_TIMESTAMP, '2', CURRENT_TIMESTAMP) """ db.engine.execute(ABACUS_STATE) db.engine.execute(LEDGER_CONTRACT_ADVANCE_APPLIED) @pytest.fixture def create_mock_paid_advances_running_worksheets( create_mock_statement_period, create_mock_account, create_mock_abacus_event ): """Create mock paid advances with running worksheets.""" mock_contract = ContractFactory.create() ContractAdvanceFactory.create( contract=mock_contract, advance_status=constants.ADVANCE_STATUSES.PAID ) ABACUS_STATE = """ INSERT INTO abacus_state ( `abacus_state_id`, `action_name`, `action_status`, `parent_table_name`, `parent_table_id`, `created_by`, `created_at`, `last_modified_by`, `last_modified` ) VALUES ( 1, 'send_payments', 'running', 'worksheet_payment_contract_advance', 1, '2', CURRENT_TIMESTAMP, '2', CURRENT_TIMESTAMP ) """ LEDGER_CONTRACT_ADVANCE_APPLIED = """ INSERT INTO ledger_contract_advance_applied ( `abacus_event_id`, `account_id`, `contract_id`, `contract_advance_id`, `worksheet_payment_contract_advance_id`, `statement_period_id`, `advance_amount`, `advance_currency_code`, `advance_amount_payee_currency`, `advance_payee_currency_code`, `created_by`, `created_at`, `last_modified_by`, `last_modified` ) VALUES (1, 1, 1, 1, 1, 1, '100.00', 'USD', '100.00','USD', '2', CURRENT_TIMESTAMP, '2', CURRENT_TIMESTAMP) """ db.engine.execute(ABACUS_STATE) db.engine.execute(LEDGER_CONTRACT_ADVANCE_APPLIED) @pytest.fixture def create_mock_schedule(): """Create mock schedule.""" ADD_SCHEDULE = """ INSERT INTO schedule( `schedule_id`, `schedule_name`, `target_type`, `target_id`, `created_by`, `created_at`, `last_modified_by`, `last_modified` ) VALUES (1, 'Schedule Abrahams, Kyle James', 'contributor', '935657b3-bcfb-4f7f-84d6-74822dea5f39', 'test_user', CURRENT_TIMESTAMP, 'test_user', CURRENT_TIMESTAMP), (2, 'Contributor Only Schedule', 'contributor', '8931b2f5-f0d9-49b1-bfa7-186b684299b1', 'test_user', CURRENT_TIMESTAMP, 'test_user', CURRENT_TIMESTAMP), (3, 'Schedule Abbott, Judith', 'contributor', 'f41ca716-19e6-47a5-97c8-b5714d245bb4', 'test_user', CURRENT_TIMESTAMP, 'test_user', CURRENT_TIMESTAMP) """ db.engine.execute(ADD_SCHEDULE) @pytest.fixture def mock_contract_and_lifecycle_post_payload(create_mock_account): """Mock POST request payload for contract, contract_lifecycle and schedules.""" continuously_active_renewal_type = ( constants.CONTRACT_LIFECYCLE_SCHEDULE_RENEWAL_TYPES.CONTINUOUSLY_ACTIVE ) reference_sap_profit_center = ReferenceSapProfitCenterFactory.create( company_code=4914 ) mock_reference_signing_entity = ReferenceSigningEntityFactory.create( company_code=4914, reference_sap_profit_center=reference_sap_profit_center ) mock_contract = { 'account_id': 1, 'contract_name': 'Test Contract', 'contract_type': 'distribution', 'reference_signing_entity_id': mock_reference_signing_entity.reference_signing_entity_id, 'execution_date': None, 'summary_note': 'This is for the test', 'general_note': 'This is for the test (general_note)', 'oa_contract_id': 1, } mock_contract_lifecycle_schedules = [ { 'renewal_type': continuously_active_renewal_type, 'schedule_end': None, 'termination_notice_detail_interval': 1, 'termination_notice_detail_type': 'month', 'renewal_offset_detail_interval': None, 'renewal_offset_detail_type': None, 'collection_period_detail_interval': None, 'collection_period_detail_type': None, } ] mock_contract_lifecycle = {'lifecycle_term_start': '2024-07-30'} mock_post_request_payload = { 'contract': mock_contract, 'contract_lifecycle_schedules': mock_contract_lifecycle_schedules, 'contract_lifecycle': mock_contract_lifecycle, } return mock_post_request_payload @pytest.fixture def mock_contracts(create_mock_account, create_mock_run_controller): """Mock contracts.""" distribution_contracts = [ ContractFactory.create( contract_name=f'Distribution Contract {i}', contract_type=constants.CONTRACT_TYPES.DISTRIBUTION, is_excluded_from_accounting_run=0, ) for i in range(1, 4) ] distribution_contracts.extend( [ ContractFactory.create( contract_name='A1 LaFlare\\Amigo Records, LLC', contract_type=constants.CONTRACT_TYPES.DISTRIBUTION, is_excluded_from_accounting_run=1, ), ContractFactory.create( contract_name='Test Distribution Contract', contract_type=constants.CONTRACT_TYPES.DISTRIBUTION, is_excluded_from_accounting_run=1, ), ] ) for contract in distribution_contracts: AccountContractFactory.create(contract=contract, account_id=1) ContractLifecycleFactory.create( contract=distribution_contracts[0], lifecycle_status=constants.CONTRACT_LIFECYCLE_STATUSES.INIT, ) ContractLifecycleFactory.create( contract=distribution_contracts[1], lifecycle_status=constants.CONTRACT_LIFECYCLE_STATUSES.INACTIVE, deleted_by='test account', deleted_at=datetime(2025, 2, 28, 0, 0), ) ContractLifecycleFactory.create( contract=distribution_contracts[2], lifecycle_status=constants.CONTRACT_LIFECYCLE_STATUSES.ACTIVE, ) ContractLifecycleFactory.create( contract=distribution_contracts[3], lifecycle_status=constants.CONTRACT_LIFECYCLE_STATUSES.TO_BE_TERMINATED, ) nr_contracts = [ ContractFactory.create( contract_name=f'NR Contract {i}', contract_type=constants.CONTRACT_TYPES.NEIGHBOURING_RIGHTS, is_excluded_from_accounting_run=1, ) for i in range(1, 4) ] nr_contracts.extend( [ ContractFactory.create( contract_name='Dylan Bukov 100% t/a Dybbukk', contract_type=constants.CONTRACT_TYPES.NEIGHBOURING_RIGHTS, is_excluded_from_accounting_run=0, ), ContractFactory.create( contract_name='Test NR Contract', contract_type=constants.CONTRACT_TYPES.NEIGHBOURING_RIGHTS, is_excluded_from_accounting_run=1, ), ] ) for contract in nr_contracts: AccountContractFactory.create(contract=contract, account_id=2) create_mock_run_controller_contract([*distribution_contracts, *nr_contracts]) ContractLifecycleFactory.create( contract=nr_contracts[0], lifecycle_status=constants.CONTRACT_LIFECYCLE_STATUSES.IN_COLLECTION_PERIOD, ) ContractLifecycleFactory.create( contract=nr_contracts[1], lifecycle_status=constants.CONTRACT_LIFECYCLE_STATUSES.TERMINATED, ) # Contracts to test sort order with search term search_order_contracts = [ ContractFactory.create( contract_name='Contract 8675309', ), ContractFactory.create( contract_id=8675309, contract_name='Contract sort order', ), ] for contract in search_order_contracts: AccountContractFactory.create(contract=contract, account_id=2) ContractLifecycleFactory.create( contract=contract, lifecycle_status=constants.CONTRACT_LIFECYCLE_STATUSES.ACTIVE, ) create_mock_run_controller_contract(search_order_contracts) @pytest.fixture def mock_revenue_associated_with_accounting_run( create_mock_statement_period, create_mock_account, create_mock_abacus_event ): """Mock data for accounting run revenue.""" mock_contract = ContractFactory.create( contract_id=9012890, contract_name='Contract 8675309', ) AccountContractFactory.create(contract=mock_contract, account_id=2) mock_run_controller = RunControllerFactory.create() RunControllerContractFactory.create( run_controller=mock_run_controller, contract=mock_contract ) mock_accounting_run = AccountingRunFactory.create( run_controller=mock_run_controller ) ACCOUNTING_RUN_BALANCE_QUERY = """ INSERT INTO ledger_accounting_run_balance( `accounting_run_id`, `abacus_event_id`, `contract_id`, `currency_code`, `total_gross_revenue_amount`, `total_net_revenue_amount`, `adjusted_net_revenue`, `created_by`, `created_at`, `last_modified_by`, `last_modified` ) VALUES ({}, 4, {}, 'USD', '2173.90', '2131.91', '2131.91', 'test_user', CURRENT_TIMESTAMP, 'test_user', CURRENT_TIMESTAMP); """ db.engine.execute( ACCOUNTING_RUN_BALANCE_QUERY.format( mock_accounting_run.accounting_run_id, mock_contract.contract_id ) )