"""Revenue Analysis logic tests.""" from collections import namedtuple from datetime import datetime from decimal import Decimal from unittest.mock import patch import pytest from moneyhub.constants.constants import ContractType from moneyhub.constants.constants import ORDER_BY_ARTIST_NAME from moneyhub.constants.constants import ORDER_BY_IMPRINT from moneyhub.constants.constants import ORDER_BY_NET_REVENUE_PAYEE_CURRENCY from moneyhub.constants.constants import ORDER_BY_PRODUCT_ID from moneyhub.constants.constants import ORDER_BY_RECORDING_ID from moneyhub.constants.constants import ORDER_BY_SUBACCOUNT_ID from moneyhub.constants.constants import ORDER_BY_TRACK_UNIQUE_ID from moneyhub.constants.constants import OrderBy from moneyhub.constants.constants import OrderDirection from moneyhub.constants.constants import StatementPeriodStatus from moneyhub.logic import revenue_analysis as logic from moneyhub.schemas import PaginatedRevenueByActivityMonthSchema from moneyhub.schemas import PaginatedRevenueByArtistSchema from moneyhub.schemas import PaginatedRevenueByImprintSchema from moneyhub.schemas import PaginatedRevenueByRecordingSchema from moneyhub.schemas import PaginatedRevenueByTrackSchema from moneyhub.schemas.revenue_analysis import AccountRevenueSchema from moneyhub.schemas.revenue_analysis import AccountStatementPeriodRevenueSchema from moneyhub.schemas.revenue_analysis import PaginatedRevenueByProjectSchema from moneyhub.schemas.revenue_analysis import PaginatedRevenueByStoreSchema from moneyhub.schemas.revenue_analysis import PaginatedRevenueBySubaccountSchema from moneyhub.schemas.revenue_analysis import ResponseRevenueByTransactionTypeSchema from moneyhub.schemas.revenue_analysis import RevenueByStatementPeriodSchema from moneyhub.schemas.revenue_analysis import RevenuePayeeCurrencyTotalsSchema from tests.utils.factories import AccountPaymentTermFactory from tests.utils.factories import ContractFactory from tests.utils.factories import DimSubaccountFactory from tests.utils.factories import RevenueByActivityMonthFactory from tests.utils.factories import RevenueByArtistFactory from tests.utils.factories import RevenueByCountryFactory from tests.utils.factories import RevenueByImprintFactory from tests.utils.factories import RevenueByProductDistroFactory from tests.utils.factories import RevenueByProjectFactory from tests.utils.factories import RevenueByRecordingDistroFactory from tests.utils.factories import RevenueByRecordingNrFactory from tests.utils.factories import RevenueByStatementPeriodFactory from tests.utils.factories import RevenueByStoreFactory from tests.utils.factories import RevenueBySubaccountFactory from tests.utils.factories import RevenueByTrackFactory from tests.utils.factories import RevenueByTransactionTypeFactory from tests.utils.factories import StatementPeriodFactory TotalRevenueResult = namedtuple( 'TotalRevenueResult', [ 'gross_revenue_payee_currency', 'net_revenue_payee_currency', 'currency_code', ] ) ACCOUNT_ID = 57608 @patch('moneyhub.logic.revenue_analysis.models.RevenueByProductDistro') def test_get_revenue_analysis_by_product(mock_RevenueByProductDistro): """Test to get revenue analysis info by product.""" account_id = 57608 limit = 50 offset = 0 total_records = 1 mock_model = RevenueByProductDistroFactory.build( account_id=account_id, mechanical_deduction_amount_payee_currency=20, publisher_admin_fee_payee_currency=2, net_share_payee_currency=20, gross_revenue_payee_currency=40) mock_RevenueByProductDistro.get_by_account_id.return_value = ( [mock_model.to_dict()], total_records) result = logic.get_revenue_analysis_by_product( account_id, limit, offset, None, None, None, None, None, None, None, ORDER_BY_PRODUCT_ID, OrderDirection.ASC, None, None, None, None, None, False) assert result == { 'items': [ { 'product_id': 1234, 'product_name': 'Best Name', 'display_upc': '1111111111111', 'account_id': 57608, 'artist_name': 'Best Artist', 'account_payee_currency': 'JPY', 'project_name': 'Project Alpha', 'mechanical_deduction_amount_payee_currency': 20, 'publisher_admin_fee_payee_currency': 2, 'net_share_payee_currency': 20, 'release_date': datetime(2010, 9, 8, 7, 6, 5), 'gross_revenue_payee_currency': 40 } ], 'pagination': { 'pagination_type': 'standard', 'total_records': 1, }, } @patch('moneyhub.logic.revenue_analysis.models') def test_get_revenue_analysis_by_product_with_subaccount(mock_models): """Test to get revenue analysis info by product.""" account_id = 57608 limit = 50 offset = 0 total_records = 1 subaccount_id = 1 subaccount_info = DimSubaccountFactory.build( subaccount_id=subaccount_id) mock_model = RevenueByProductDistroFactory.build( account_id=account_id, mechanical_deduction_amount_payee_currency=20, publisher_admin_fee_payee_currency=2, net_share_payee_currency=20, gross_revenue_payee_currency=40) mock_model = mock_model.to_dict() mock_model['subaccount_revenue'] = 18 mock_models.RevenueByProductDistro.get_by_account_id.return_value = ( [mock_model], total_records) mock_models.DimSubaccount.get_by_id.return_value = subaccount_info result = logic.get_revenue_analysis_by_product( account_id, limit, offset, None, None, None, None, None, None, None, ORDER_BY_PRODUCT_ID, OrderDirection.ASC, None, None, None, None, None, True) assert result == { 'items': [ { 'product_id': 1234, 'product_name': 'Best Name', 'display_upc': '1111111111111', 'account_id': 57608, 'artist_name': 'Best Artist', 'account_payee_currency': 'JPY', 'project_name': 'Project Alpha', 'mechanical_deduction_amount_payee_currency': 20, 'publisher_admin_fee_payee_currency': 2, 'net_share_payee_currency': 20, 'release_date': datetime(2010, 9, 8, 7, 6, 5), 'gross_revenue_payee_currency': 40, 'subaccount_revenue': 18 }], 'pagination': { 'pagination_type': 'standard', 'total_records': 1, }, } @patch('moneyhub.logic.revenue_analysis.models.RevenueByProductDistro') def test_get_revenue_analysis_by_product_with_list_filters(mock_RevenueByProductDistro): """Test to get revenue analysis info by product with list filters.""" account_id = 57608 limit = 50 offset = 0 total_records = 1 store_ids = [101, 102] country_codes = ['US', 'GB'] imprint_ids = [201] transaction_type_ids = [301, 302] mock_model = RevenueByProductDistroFactory.build( account_id=account_id, mechanical_deduction_amount_payee_currency=20, publisher_admin_fee_payee_currency=2, net_share_payee_currency=20, gross_revenue_payee_currency=40) mock_RevenueByProductDistro.get_by_account_id.return_value = ( [mock_model.to_dict()], total_records) result = logic.get_revenue_analysis_by_product( account_id, limit, offset, None, None, None, None, None, None, None, ORDER_BY_PRODUCT_ID, OrderDirection.ASC, None, store_ids, country_codes, transaction_type_ids, imprint_ids, False) assert result == { 'items': [ { 'product_id': 1234, 'product_name': 'Best Name', 'display_upc': '1111111111111', 'account_id': 57608, 'artist_name': 'Best Artist', 'account_payee_currency': 'JPY', 'project_name': 'Project Alpha', 'mechanical_deduction_amount_payee_currency': 20, 'publisher_admin_fee_payee_currency': 2, 'net_share_payee_currency': 20, 'release_date': datetime(2010, 9, 8, 7, 6, 5), 'gross_revenue_payee_currency': 40 } ], 'pagination': { 'pagination_type': 'standard', 'total_records': 1, }, } @patch('moneyhub.logic.revenue_analysis.models.RevenueByStatementPeriod') def test_get_revenue_analysis_by_statement_period(mock_RevenueByStatementPeriod): """Test getting revenue by statement period.""" account_id = 24601 contract_id = 10001 artist_id = 12345 subaccount_id = 1111 product_id = 1234 track_unique_id = 12345678 statement_period_id_start = 123 statement_period_id_end = 124 is_subaccount = False activity_period_id_start = 123 activity_period_id_end = 123 store_ids = [1] country_codes = ['US', 'JP'] imprint_ids = [1, 2, 2] transaction_type_ids = [4, 5, 6] expected = [RevenueByStatementPeriodSchema(**item) for item in [ { 'statement_period_id': 123, 'statement_period_name': 'August 2024', 'statement_period_status': StatementPeriodStatus.CLOSED, 'account_payee_currency': 'JPY', 'net_revenue_payee_currency': 20, 'gross_revenue_payee_currency': 40, 'net_publishing_revenue_payee_currency': 5, 'gross_publishing_revenue_payee_currency': 6, 'subaccount_revenue': None }, { 'statement_period_id': 124, 'statement_period_name': 'September 2024', 'statement_period_status': StatementPeriodStatus.OPEN, 'account_payee_currency': 'JPY', 'net_revenue_payee_currency': 20, 'gross_revenue_payee_currency': 40, 'net_publishing_revenue_payee_currency': 7, 'gross_publishing_revenue_payee_currency': 8, 'subaccount_revenue': None }, ]] mock_models = [ RevenueByStatementPeriodFactory.build( statement_period_id=123, statement_period_name='August 2024', statement_period_status=StatementPeriodStatus.CLOSED, account_payee_currency='JPY', net_revenue_payee_currency=20, gross_revenue_payee_currency=40, net_publishing_revenue_payee_currency=5, gross_publishing_revenue_payee_currency=6, ), RevenueByStatementPeriodFactory.build( statement_period_id=124, statement_period_name='September 2024', statement_period_status=StatementPeriodStatus.OPEN, account_payee_currency='JPY', net_revenue_payee_currency=20, gross_revenue_payee_currency=40, net_publishing_revenue_payee_currency=7, gross_publishing_revenue_payee_currency=8, ), ] mock_RevenueByStatementPeriod.get_by_account_id.return_value = mock_models result = logic.get_revenue_analysis_by_statement_period( account_id, contract_id, artist_id, subaccount_id, product_id, track_unique_id, statement_period_id_start, statement_period_id_end, is_subaccount, activity_period_id_start, activity_period_id_end, store_ids, country_codes, imprint_ids, transaction_type_ids, ) assert result == expected mock_RevenueByStatementPeriod.get_by_account_id.assert_called_once_with( account_id, artist_id, subaccount_id, contract_id, product_id, track_unique_id, statement_period_id_start, statement_period_id_end, None, activity_period_id_start, activity_period_id_end, store_ids, country_codes, imprint_ids, transaction_type_ids, project_id=None, ) test_scenarios = [ ( 123, 124, [ RevenueByStatementPeriodFactory.build( statement_period_id=123, account_payee_currency='JPY', net_revenue_payee_currency=20, gross_revenue_payee_currency=40, net_publishing_revenue_payee_currency=5, gross_publishing_revenue_payee_currency=6, ), ], [ { 'statement_period_id': 123, 'account_payee_currency': 'JPY', 'net_revenue_payee_currency': 20, 'gross_revenue_payee_currency': 40, 'net_publishing_revenue_payee_currency': 5, 'gross_publishing_revenue_payee_currency': 6, 'subaccount_revenue': None }, { 'statement_period_id': 124, 'account_payee_currency': 'JPY', 'net_revenue_payee_currency': 0, 'gross_revenue_payee_currency': 0, 'net_publishing_revenue_payee_currency': 0, 'gross_publishing_revenue_payee_currency': 0, 'subaccount_revenue': None }, ] ), ( 123, 124, [ RevenueByStatementPeriodFactory.build( statement_period_id=124, account_payee_currency='JPY', net_revenue_payee_currency=20, gross_revenue_payee_currency=40, net_publishing_revenue_payee_currency=7, gross_publishing_revenue_payee_currency=8, ), ], [ { 'statement_period_id': 124, 'account_payee_currency': 'JPY', 'net_revenue_payee_currency': 20, 'gross_revenue_payee_currency': 40, 'net_publishing_revenue_payee_currency': 7, 'gross_publishing_revenue_payee_currency': 8, 'subaccount_revenue': None }, { 'statement_period_id': 123, 'account_payee_currency': 'JPY', 'net_revenue_payee_currency': 0, 'gross_revenue_payee_currency': 0, 'net_publishing_revenue_payee_currency': 0, 'gross_publishing_revenue_payee_currency': 0, 'subaccount_revenue': None }, ] ), ] @pytest.mark.parametrize( 'statement_period_id_start, statement_period_id_end, mock_models, expected_response', test_scenarios, ids=[ 'statement_period_end not present in range', 'statement_period_start not present in range', ] ) @patch('moneyhub.logic.revenue_analysis.models.RevenueByStatementPeriod') def test_get_revenue_analysis_by_statement_period_missing_statement_period( mock_RevenueByStatementPeriod, statement_period_id_start, statement_period_id_end, mock_models, expected_response ): """Test getting revenue by statement period.""" account_id = 24601 contract_id = 10001 artist_id = 12345 subaccount_id = 1111 product_id = 1234 track_unique_id = 12345678 is_subaccount = False activity_period_id_start = 123 activity_period_id_end = 124 store_ids = [1] country_codes = ['US', 'JP'] imprint_ids = [1, 2, 2] transaction_type_ids = [4, 5, 6] expected = [RevenueByStatementPeriodSchema(**item) for item in expected_response] mock_RevenueByStatementPeriod.get_by_account_id.return_value = mock_models result = logic.get_revenue_analysis_by_statement_period( account_id, contract_id, artist_id, subaccount_id, product_id, track_unique_id, statement_period_id_start, statement_period_id_end, is_subaccount, activity_period_id_start, activity_period_id_end, store_ids, country_codes, imprint_ids, transaction_type_ids, ) assert result == expected mock_RevenueByStatementPeriod.get_by_account_id.assert_called_once_with( account_id, artist_id, subaccount_id, contract_id, product_id, track_unique_id, statement_period_id_start, statement_period_id_end, None, activity_period_id_start, activity_period_id_end, store_ids, country_codes, imprint_ids, transaction_type_ids, project_id=None, ) @patch('moneyhub.logic.revenue_analysis.models.RevenueByTrack') def test_get_revenue_analysis_by_track(mock_RevenueByTrack): """Test to get revenue track info by track.""" account_id = 57608 limit = 50 offset = 0 total_records = 1 payload = { 'items': [ { 'track_unique_id': 12341234, 'track_name': 'Best Name', 'isrc': 'IIIII1234187', 'account_id': 57608, 'account_payee_currency': 'JPY', 'project_name': 'Project Alpha', 'mechanical_deduction_amount_payee_currency': 20, 'publisher_admin_fee_payee_currency': 2, 'net_revenue_payee_currency': 20, 'gross_revenue_payee_currency': 40 }], 'pagination': { 'pagination_type': 'standard', 'total_records': 1, }, } mock_model = RevenueByTrackFactory.build( account_id=account_id, mechanical_deduction_amount_payee_currency=20, publisher_admin_fee_payee_currency=2, net_revenue_payee_currency=20, gross_revenue_payee_currency=40) mock_RevenueByTrack.get_by_account_id.return_value = ( [mock_model.to_dict()], total_records) result = logic.get_revenue_analysis_by_track( account_id, limit, offset, None, None, None, None, None, None, None, None, ORDER_BY_TRACK_UNIQUE_ID, OrderDirection.ASC, None, None, None, None, None, False) assert result.__class__ == PaginatedRevenueByTrackSchema assert result == PaginatedRevenueByTrackSchema(**payload) @patch('moneyhub.logic.revenue_analysis.models') def test_get_revenue_analysis_by_track_with_subaccount(mock_models): """Test to get revenue track info by track.""" account_id = 57608 limit = 50 offset = 0 total_records = 1 subaccount_id = 1 subaccount_info = DimSubaccountFactory.build( subaccount_id=subaccount_id) payload = { 'items': [ { 'track_unique_id': 12341234, 'track_name': 'Best Name', 'isrc': 'IIIII1234187', 'account_id': 57608, 'account_payee_currency': 'JPY', 'project_name': 'Project Alpha', 'mechanical_deduction_amount_payee_currency': 20, 'publisher_admin_fee_payee_currency': 2, 'net_revenue_payee_currency': 20, 'gross_revenue_payee_currency': 40, 'subaccount_revenue': 18 }], 'pagination': { 'pagination_type': 'standard', 'total_records': 1, }, } mock_model = RevenueByTrackFactory.build( account_id=account_id, mechanical_deduction_amount_payee_currency=20, publisher_admin_fee_payee_currency=2, net_revenue_payee_currency=20, gross_revenue_payee_currency=40) mock_model = mock_model.to_dict() mock_model['subaccount_revenue'] = 18 mock_models.RevenueByTrack.get_by_account_id.return_value = ( [mock_model], total_records) mock_models.DimSubaccount.get_by_id.return_value = subaccount_info result = logic.get_revenue_analysis_by_track( account_id, limit, offset, None, None, None, None, None, None, subaccount_id, None, ORDER_BY_TRACK_UNIQUE_ID, OrderDirection.ASC, None, None, None, None, None, True) assert result.__class__ == PaginatedRevenueByTrackSchema assert result == PaginatedRevenueByTrackSchema(**payload) @patch('moneyhub.logic.revenue_analysis.models.RevenueByTrack') def test_get_revenue_analysis_by_track_with_list_filters(mock_RevenueByTrack): """Test to get revenue track info by track with list filters.""" account_id = 57608 limit = 50 offset = 0 total_records = 1 store_ids = [101, 102] country_codes = ['US', 'GB'] imprint_ids = [201] transaction_type_ids = [301] mock_model = RevenueByTrackFactory.build(account_id=account_id) mock_RevenueByTrack.get_by_account_id.return_value = ([mock_model], total_records) result = logic.get_revenue_analysis_by_track( account_id, limit, offset, None, None, None, None, None, None, None, None, ORDER_BY_TRACK_UNIQUE_ID, OrderDirection.ASC, None, store_ids, country_codes, transaction_type_ids, imprint_ids, False) assert result.__class__ == PaginatedRevenueByTrackSchema mock_RevenueByTrack.get_by_account_id.assert_called_once_with( account_id, limit, offset, None, None, None, None, None, None, None, None, ORDER_BY_TRACK_UNIQUE_ID, OrderDirection.ASC, None, store_ids, country_codes, transaction_type_ids, imprint_ids, None, None ) @patch('moneyhub.logic.revenue_analysis.models.RevenueByProject') def test_get_revenue_analysis_by_project(mock_RevenueByProject): """Test getting revenue by project.""" account_id = 57608 limit = 50 offset = 0 total_records = 1 mock_model = RevenueByProjectFactory.build( project_id=123, project_name='Project Nimbus', project_code='PN-001' ) mock_RevenueByProject.get_by_account_id.return_value = ([mock_model.to_dict()], total_records) result = logic.get_revenue_analysis_by_project( account_id, limit, offset, None, None, 10, 20, 'project_id', OrderDirection.ASC, 'Nimbus', False, 1, 2, [101], ['US'], [201], [301], ) assert result.__class__ == PaginatedRevenueByProjectSchema assert result.items[0].project_id == 123 assert result.items[0].project_name == 'Project Nimbus' assert result.items[0].project_code == 'PN-001' mock_RevenueByProject.get_by_account_id.assert_called_once_with( account_id, limit, offset, None, None, 10, 20, 'project_id', OrderDirection.ASC, 'Nimbus', None, 1, 2, ['US'], [201], [301], [101], ) @patch('moneyhub.logic.revenue_analysis.models.RevenueByArtist') def test_get_revenue_analysis_by_artist(mock_RevenueByArtist): """Test to get revenue by artist.""" account_id = 57608 subaccount_id = 1001 limit = 50 offset = 0 total_records = 1 payload = { 'items': [ { 'artist_id': 12345, 'artist_name': 'The Artist Formerly Known As Test Artist', 'account_id': account_id, 'account_payee_currency': 'JPY', 'subaccount_id': subaccount_id, 'mechanical_deduction_amount_payee_currency': 20, 'publisher_admin_fee_payee_currency': 2, 'net_revenue_payee_currency': 20, 'gross_revenue_payee_currency': 40 }], 'pagination': { 'pagination_type': 'standard', 'total_records': 1, }, } mock_model = RevenueByArtistFactory.build( account_id=account_id, mechanical_deduction_amount_payee_currency=20, publisher_admin_fee_payee_currency=2, subaccount_id=subaccount_id, net_revenue_payee_currency=20, gross_revenue_payee_currency=40) mock_RevenueByArtist.get_by_account_id.return_value = ( [mock_model.to_dict()], total_records) result = logic.get_revenue_analysis_by_artist( account_id, limit, offset, None, None, None, None, None, None, ORDER_BY_ARTIST_NAME, OrderDirection.ASC, None, None, None, None, None) assert result.__class__ == PaginatedRevenueByArtistSchema assert result == PaginatedRevenueByArtistSchema(**payload) @patch('moneyhub.logic.revenue_analysis.models.RevenueByArtist') def test_get_revenue_analysis_by_artist_with_subaccount_revenue(mock_RevenueByArtist): """Test to get revenue by artist with subaccount revenue.""" account_id = 57608 limit = 50 offset = 0 total_records = 1 payload = { 'items': [ { 'artist_id': 12345, 'artist_name': 'The Artist Formerly Known As Test Artist', 'account_id': account_id, 'account_payee_currency': 'JPY', 'mechanical_deduction_amount_payee_currency': 20, 'publisher_admin_fee_payee_currency': 2, 'net_revenue_payee_currency': 20, 'gross_revenue_payee_currency': 40, 'subaccount_revenue': 18 }], 'pagination': { 'pagination_type': 'standard', 'total_records': 1, }, } mock_model = RevenueByArtistFactory.build( account_id=account_id, mechanical_deduction_amount_payee_currency=20, publisher_admin_fee_payee_currency=2, net_revenue_payee_currency=20, gross_revenue_payee_currency=40) mock_model = mock_model.to_dict() mock_model['subaccount_revenue'] = 18 mock_RevenueByArtist.get_by_account_id.return_value = ( [mock_model], total_records) result = logic.get_revenue_analysis_by_artist( account_id, limit, offset, None, 10001, None, None, None, None, ORDER_BY_ARTIST_NAME, OrderDirection.ASC, None, None, None, None, None, is_subaccount=True) assert result.__class__ == PaginatedRevenueByArtistSchema assert result == PaginatedRevenueByArtistSchema(**payload) @patch('moneyhub.logic.revenue_analysis.models.RevenueBySubaccount') def test_get_revenue_analysis_by_subaccount(mock_RevenueBySubaccount): """Test to get revenue subaccount info by subaccount.""" account_id = 57608 artist_id = 1234 contract_id = None statement_period_id_start = 10 statement_period_id_end = 20 store_ids = None activity_period_id_start = None activity_period_id_end = None imprint_ids = None transaction_type_ids = [1, 2, 3] country_codes = ['NO'] search_term = None limit = 50 offset = 0 total_records = 1 payload = { 'items': [ { 'subaccount_id': 111222, 'subaccount_name': 'Test Subaccount', 'account_id': account_id, 'account_payee_currency': 'USD', 'mechanical_deduction_amount_payee_currency': 20, 'publisher_admin_fee_payee_currency': 2, 'net_revenue_payee_currency': 20, 'gross_revenue_payee_currency': 40 }], 'pagination': { 'pagination_type': 'standard', 'total_records': 1, }, } mock_model = RevenueBySubaccountFactory.build( account_id=account_id, mechanical_deduction_amount_payee_currency=20, publisher_admin_fee_payee_currency=2, net_revenue_payee_currency=20, gross_revenue_payee_currency=40) mock_RevenueBySubaccount.get_by_account_id.return_value = ( [mock_model.to_dict()], total_records) result = logic.get_revenue_analysis_by_subaccount( account_id, limit, offset, artist_id, contract_id, store_ids, activity_period_id_start, activity_period_id_end, imprint_ids, transaction_type_ids, country_codes, statement_period_id_start, statement_period_id_end, ORDER_BY_SUBACCOUNT_ID, OrderDirection.ASC, search_term ) assert result.__class__ == PaginatedRevenueBySubaccountSchema assert result == PaginatedRevenueBySubaccountSchema(**payload) mock_RevenueBySubaccount.get_by_account_id.assert_called_once_with( account_id, limit, offset, artist_id, contract_id, statement_period_id_start, statement_period_id_end, activity_period_id_start, activity_period_id_end, store_ids, imprint_ids, transaction_type_ids, country_codes, ORDER_BY_SUBACCOUNT_ID, OrderDirection.ASC, search_term ) @patch('moneyhub.logic.revenue_analysis.create_paginated_response') @patch('moneyhub.logic.revenue_analysis.models.Contract') @patch('moneyhub.logic.revenue_analysis.models.RevenueByRecordingNr') def test_get_revenue_analysis_by_recording_nr( mock_RevenueByRecordingNr, mock_contract, mock_pagination ): """Test to get revenue by recording for neighbouring rights accounts.""" account_id = 57608 limit = 50 offset = 0 total_records = 1 payload = { 'items': [{ 'recording_id': '1234', 'recording_title': 'Title', 'artist': 'Artist', 'version': 'Acoustic', 'isrc': 'JPYE70900611', 'account_id': 57608, 'contract_id': 10001, 'account_payee_currency': 'JPY', 'net_share_payee_currency': 100, 'gross_revenue_payee_currency': 110, }], 'pagination': { 'pagination_type': 'standard', 'total_records': 1, } } contract = ContractFactory.build(contract_type=ContractType.NEIGHBOURING_RIGHTS) revenue = RevenueByRecordingNrFactory.build( account_id=account_id, net_share_payee_currency=100, gross_revenue_payee_currency=110) row_result = [revenue.to_dict()], total_records mock_contract.get_contract_type_by_account.return_value = contract mock_RevenueByRecordingNr.get_by_account_id.return_value = row_result mock_pagination.return_value = payload result = logic.get_revenue_analysis_by_recording( account_id, limit, offset, None, None, None, None, ORDER_BY_RECORDING_ID, OrderDirection.ASC, None, None, None, None, None, None) mock_pagination.assert_called_once_with(*row_result) assert result.__class__ == PaginatedRevenueByRecordingSchema assert result == PaginatedRevenueByRecordingSchema(**payload) @patch('moneyhub.logic.revenue_analysis.create_paginated_response') @patch('moneyhub.logic.revenue_analysis.models.Contract') @patch('moneyhub.logic.revenue_analysis.models.RevenueByRecordingDistro') def test_get_revenue_analysis_by_recording_distro( mock_RevenueByRecordingDistro, mock_contract, mock_pagination ): """Test to get revenue by recording for distro (ownership) accounts.""" account_id = 68410 limit = 50 contract_id = 535877 offset = 0 total_records = 1 payload = { 'items': [{ 'recording_id': '37737082', 'recording_title': 'Come Wander', 'artist': 'Delorean', 'version': '', 'isrc': 'ES7001009807', 'account_id': 68410, 'contract_id': contract_id, 'account_payee_currency': 'EUR', 'net_share_payee_currency': 0.013031357743, 'gross_revenue_payee_currency': 0.01506515346 }], 'pagination': { 'pagination_type': 'standard', 'total_records': 1, } } contract = ContractFactory.build(contract_type=ContractType.DISTRIBUTION) revenue = RevenueByRecordingDistroFactory.build( account_id=account_id, contract_id=contract_id, net_share_payee_currency=100, gross_revenue_payee_currency=110) row_result = [revenue.to_dict()], total_records mock_contract.get_by_id.return_value = contract mock_RevenueByRecordingDistro.get_by_account_id.return_value = row_result mock_pagination.return_value = payload result = logic.get_revenue_analysis_by_recording( account_id, limit, offset, contract_id, None, None, None, None, None, ORDER_BY_RECORDING_ID, OrderDirection.ASC, None, None, None, None) mock_pagination.assert_called_once_with(*row_result) assert result.__class__ == PaginatedRevenueByRecordingSchema assert result == PaginatedRevenueByRecordingSchema(**payload) @patch('moneyhub.logic.revenue_analysis.create_paginated_response') @patch('moneyhub.logic.revenue_analysis.models.Contract') @patch('moneyhub.logic.revenue_analysis.models.RevenueByRecordingDistro') def test_get_revenue_analysis_by_recording_no_revenue( mock_RevenueByRecordingDistro, mock_contract, mock_pagination ): """Test to get revenue by recording for distro (ownership) accounts.""" account_id = 68410 limit = 50 contract_id = 535877 offset = 0 total_records = 1 payload = { 'items': [], 'pagination': { 'pagination_type': 'standard', 'total_records': 0, } } contract = ContractFactory.build(contract_type=ContractType.DISTRIBUTION) revenue = RevenueByRecordingDistroFactory.build( account_id=account_id, contract_id=contract_id, net_share_payee_currency=None, gross_revenue_payee_currency=None) row_result = [revenue.to_dict()], total_records mock_contract.get_by_id.return_value = contract mock_RevenueByRecordingDistro.get_by_account_id.return_value = row_result mock_pagination.return_value = payload result = logic.get_revenue_analysis_by_recording( account_id, limit, offset, contract_id, None, None, None, None, None, ORDER_BY_RECORDING_ID, OrderDirection.ASC, None, None, None, None) mock_pagination.assert_called_once_with(*row_result) assert result.__class__ == PaginatedRevenueByRecordingSchema assert result == PaginatedRevenueByRecordingSchema(**payload) @patch('moneyhub.logic.revenue_analysis.create_paginated_response') @patch('moneyhub.logic.revenue_analysis.models.RevenueByStore') def test_get_revenue_analysis_by_store(mock_RevenueByStore, mock_pagination): """Test to get revenue analysis info by store.""" total_records = 1 artist_id = 1 subaccount_id = 1 product_id = 1 track_unique_id = 1 contract_id = 1 activity_period_id_start = 1 activity_period_id_end = 1 country_codes = ['US'] imprint_ids = [1] transaction_type_ids = [2] mock_model = RevenueByStoreFactory.build( store_id=123, artist_id=2, net_revenue_payee_currency=100, gross_revenue_payee_currency=110) mock_stores_totals = RevenueByStoreFactory.build( net_revenue_payee_currency=1000, gross_revenue_payee_currency=29988) payload = { 'items': [ { 'store_id': 123, 'store_name': 'Spotify', 'account_payee_currency': 'USD', 'net_revenue_payee_currency': 100, 'gross_revenue_payee_currency': 110, }, ], 'pagination': { 'pagination_type': 'standard', 'total_records': 1, } } mock_pagination.return_value = payload mock_RevenueByStore.get_by_account_id.return_value = [mock_model.to_dict()], total_records mock_RevenueByStore.get_stores_totals_by_account_id.return_value = mock_stores_totals result = logic.get_revenue_analysis_by_store( ACCOUNT_ID, artist_id, subaccount_id, 1, 0, contract_id, product_id, track_unique_id, None, None, OrderBy.NET_REVENUE_PAYEE_CURRENCY, OrderDirection.ASC, None, False, activity_period_id_start, activity_period_id_end, country_codes, imprint_ids, transaction_type_ids, None, ) assert payload['totals'] == RevenuePayeeCurrencyTotalsSchema( net_revenue_payee_currency=mock_stores_totals.net_revenue_payee_currency, gross_revenue_payee_currency=mock_stores_totals.gross_revenue_payee_currency, ) assert result == PaginatedRevenueByStoreSchema(**payload) mock_RevenueByStore.get_by_account_id.assert_called_once_with( ACCOUNT_ID, artist_id, subaccount_id, 1, 0, contract_id, product_id, track_unique_id, None, None, OrderBy.NET_REVENUE_PAYEE_CURRENCY, OrderDirection.ASC, None, None, activity_period_id_start, activity_period_id_end, country_codes, imprint_ids, transaction_type_ids, None, project_id=None, ) mock_RevenueByStore.get_stores_totals_by_account_id.assert_called_once_with( ACCOUNT_ID, artist_id, subaccount_id, contract_id, product_id, track_unique_id, None, None, None, activity_period_id_start, activity_period_id_end, country_codes, imprint_ids, transaction_type_ids, None, project_id=None, ) @patch('moneyhub.logic.revenue_analysis.create_paginated_response') @patch('moneyhub.logic.revenue_analysis.models.RevenueByStore') def test_get_revenue_analysis_by_store_with_zero_revenue(mock_RevenueByStore, mock_pagination): """Test to get revenue analysis info by store.""" mock_RevenueByStore.get_by_account_id.return_value = [], 0 contract_id = None artist_id = None subaccount_id = None payload = { 'items': [], 'pagination': { 'pagination_type': 'standard', 'total_records': 0, } } mock_pagination.return_value = payload mock_stores_totals = RevenueByStoreFactory.build( net_revenue_payee_currency=None, gross_revenue_payee_currency=None, ) mock_RevenueByStore.get_stores_totals_by_account_id.return_value = mock_stores_totals result = logic.get_revenue_analysis_by_store( ACCOUNT_ID, artist_id, subaccount_id, 1, 0, contract_id, None, None, None, None, OrderBy.NET_REVENUE_PAYEE_CURRENCY, OrderDirection.ASC, None, False, None, None, None, None, None, None ) assert payload['totals'] == RevenuePayeeCurrencyTotalsSchema( net_revenue_payee_currency=mock_stores_totals.net_revenue_payee_currency, gross_revenue_payee_currency=mock_stores_totals.gross_revenue_payee_currency, ) assert result == PaginatedRevenueByStoreSchema(**payload) mock_RevenueByStore.get_by_account_id.assert_called_once_with( ACCOUNT_ID, artist_id, subaccount_id, 1, 0, contract_id, None, None, None, None, OrderBy.NET_REVENUE_PAYEE_CURRENCY, OrderDirection.ASC, None, None, None, None, None, None, None, None, project_id=None, ) mock_RevenueByStore.get_stores_totals_by_account_id.assert_called_once_with( ACCOUNT_ID, artist_id, subaccount_id, contract_id, None, None, None, None, None, None, None, None, None, None, None, project_id=None, ) @patch('moneyhub.logic.revenue_analysis.create_paginated_response') @patch('moneyhub.logic.revenue_analysis.models') def test_get_revenue_analysis_by_store_subaccount(mock_models, mock_pagination): """Test to get revenue analysis info by store for a subaccount.""" total_records = 1 artist_id = 1 subaccount_id = 1 contract_id = 1 subaccount_info = DimSubaccountFactory.build( subaccount_id=subaccount_id) mock_models.DimSubaccount.get_by_id.return_value = subaccount_info mock_model = RevenueByStoreFactory.build( store_id=123, artist_id=2, net_revenue_payee_currency=100, gross_revenue_payee_currency=110).to_dict() mock_model['subaccount_revenue'] = 90 mock_stores_totals = RevenueByStoreFactory.build( net_revenue_payee_currency=1000, gross_revenue_payee_currency=29988) mock_stores_totals.__setattr__('subaccount_revenue', 900) payload = { 'items': [ { 'store_id': 123, 'store_name': 'Spotify', 'account_payee_currency': 'USD', 'net_revenue_payee_currency': 100, 'gross_revenue_payee_currency': 110, 'subaccount_revenue': 90 }, ], 'pagination': { 'pagination_type': 'standard', 'total_records': 1, } } mock_pagination.return_value = payload mock_models.RevenueByStore.get_by_account_id.return_value = [mock_model], total_records mock_models.RevenueByStore.get_stores_totals_by_account_id.return_value = mock_stores_totals result = logic.get_revenue_analysis_by_store( ACCOUNT_ID, artist_id, subaccount_id, 1, 0, contract_id, None, None, None, None, OrderBy.NET_REVENUE_PAYEE_CURRENCY, OrderDirection.ASC, None, True, None, None, None, None, None, None ) assert payload['totals'] == RevenuePayeeCurrencyTotalsSchema( net_revenue_payee_currency=mock_stores_totals.net_revenue_payee_currency, gross_revenue_payee_currency=mock_stores_totals.gross_revenue_payee_currency, subaccount_revenue=mock_stores_totals.subaccount_revenue ) assert result == PaginatedRevenueByStoreSchema(**payload) mock_models.RevenueByStore.get_by_account_id.assert_called_once_with( ACCOUNT_ID, artist_id, subaccount_id, 1, 0, contract_id, None, None, None, None, OrderBy.NET_REVENUE_PAYEE_CURRENCY, OrderDirection.ASC, None, subaccount_info, None, None, None, None, None, None, project_id=None, ) mock_models.RevenueByStore.get_stores_totals_by_account_id.assert_called_once_with( ACCOUNT_ID, artist_id, subaccount_id, contract_id, None, None, None, None, subaccount_info, None, None, None, None, None, None, project_id=None, ) @patch('moneyhub.logic.revenue_analysis.models.RevenueByTransactionType') def test_get_revenue_analysis_by_transaction_type(mock_RevenueByTransactionType): """Test to get revenue analysis info by transaction type.""" account_id = 24601 subaccount_id = 24604 items = [ RevenueByTransactionTypeFactory.build( transaction_type_id=1, transaction_type_desc='Downloaded Ringtones', transaction_type_group_name='Ringtone Group', account_payee_currency='USD', quantity=10, net_revenue_payee_currency=200, gross_revenue_payee_currency=220), RevenueByTransactionTypeFactory.build( transaction_type_id=1, transaction_type_desc='Downloaded Ringtones', transaction_type_group_name='Ringtone Group', account_payee_currency='USD', quantity=5, net_revenue_payee_currency=100, gross_revenue_payee_currency=110), ] mock_totals = RevenueByTransactionTypeFactory.build( net_revenue_payee_currency=1000, gross_revenue_payee_currency=29988) expected_totals = { 'net_revenue_payee_currency': 1000, 'gross_revenue_payee_currency': 29988 } expected_items = [item.to_dict() for item in items] mock_RevenueByTransactionType.get_transaction_types_totals_by_account_id.return_value \ = mock_totals mock_RevenueByTransactionType.get_by_account_id.return_value = items expected_payload = ResponseRevenueByTransactionTypeSchema( totals=expected_totals, items=expected_items) result = logic.get_revenue_analysis_by_transaction_type( account_id, None, None, None, None, None, None, subaccount_id, ORDER_BY_NET_REVENUE_PAYEE_CURRENCY, OrderDirection.DESC, None, False, None, None, None, None, None, None) assert result == expected_payload mock_RevenueByTransactionType.get_by_account_id.assert_called_once_with( account_id, None, None, None, None, None, None, subaccount_id, ORDER_BY_NET_REVENUE_PAYEE_CURRENCY, OrderDirection.DESC, None, None, None, None, None, None, None, None, project_id=None, ) mock_RevenueByTransactionType.get_transaction_types_totals_by_account_id.assert_called_once_with( # noqa:E501 account_id, None, None, None, None, None, None, subaccount_id, None, None, None, None, None, None, None, project_id=None, ) @patch('moneyhub.logic.revenue_analysis.models.RevenueByTransactionType') @patch('moneyhub.logic.revenue_analysis.models.DimSubaccount') def test_get_revenue_analysis_by_transaction_type_filters( mock_DimSubaccount, mock_RevenueByTransactionType ): """Test to get revenue analysis info by transaction type with filters.""" account_id = 24601 artist_id = 123 contract_id = 10001 statement_period_id_start = 100 statement_period_id_end = 110 activity_period_id_start = 98 activity_period_id_end = 99 subaccount_id = 24604 order_by = ORDER_BY_NET_REVENUE_PAYEE_CURRENCY order_dir = OrderDirection.DESC search_term = 'test' is_subaccount = True product_id = 23456 track_unique_id = 9999 store_ids = [1, 2] country_codes = ['GB'] imprint_ids = [321] transaction_type_ids = [1] subaccount_info = DimSubaccountFactory.build(subaccount_id=subaccount_id) items = [ RevenueByTransactionTypeFactory.build( transaction_type_id=1, transaction_type_desc='Downloaded Ringtones', transaction_type_group_name='Ringtone Group', account_payee_currency='USD', quantity=10, net_revenue_payee_currency=200, gross_revenue_payee_currency=220), ] mock_totals = RevenueByTransactionTypeFactory.build( net_revenue_payee_currency=1000, gross_revenue_payee_currency=29988) expected_totals = { 'net_revenue_payee_currency': 1000, 'gross_revenue_payee_currency': 29988 } expected_items = [item.to_dict() for item in items] mock_DimSubaccount.get_by_id.return_value = subaccount_info mock_RevenueByTransactionType.get_transaction_types_totals_by_account_id.return_value \ = mock_totals mock_RevenueByTransactionType.get_by_account_id.return_value = items expected_payload = ResponseRevenueByTransactionTypeSchema( totals=expected_totals, items=expected_items) result = logic.get_revenue_analysis_by_transaction_type( account_id, artist_id, contract_id, statement_period_id_start, statement_period_id_end, activity_period_id_start, activity_period_id_end, subaccount_id, order_by, order_dir, search_term, is_subaccount, product_id, track_unique_id, store_ids, country_codes, imprint_ids, transaction_type_ids, ) assert result == expected_payload mock_RevenueByTransactionType.get_by_account_id.assert_called_once_with( account_id, artist_id, contract_id, statement_period_id_start, statement_period_id_end, activity_period_id_start, activity_period_id_end, subaccount_id, order_by, order_dir, search_term, product_id, track_unique_id, store_ids, country_codes, imprint_ids, transaction_type_ids, subaccount_info, project_id=None, ) mock_RevenueByTransactionType.get_transaction_types_totals_by_account_id.assert_called_once_with( # noqa:E501 account_id, artist_id, contract_id, statement_period_id_start, statement_period_id_end, activity_period_id_start, activity_period_id_end, subaccount_id, product_id, track_unique_id, store_ids, country_codes, imprint_ids, transaction_type_ids, subaccount_info, project_id=None, ) @patch('moneyhub.logic.revenue_analysis.models') def test_get_revenue_analysis_by_transaction_type_subaccount(mock_models): """Test to get revenue analysis info by transaction type for a subaccount.""" account_id = 24601 subaccount_id = 24604 item1 = RevenueByTransactionTypeFactory.build( transaction_type_id=1, transaction_type_desc='Downloaded Ringtones', transaction_type_group_name='Ringtone Group', account_payee_currency='USD', quantity=10, net_revenue_payee_currency=200, gross_revenue_payee_currency=220) item1.__setattr__('subaccount_revenue', 180) item2 = RevenueByTransactionTypeFactory.build( transaction_type_id=1, transaction_type_desc='Downloaded Ringtones', transaction_type_group_name='Ringtone Group', account_payee_currency='USD', quantity=5, net_revenue_payee_currency=100, gross_revenue_payee_currency=110) item2.__setattr__('subaccount_revenue', 90) items = [item1, item2] total = RevenueByTransactionTypeFactory.build( net_revenue_payee_currency=1000, gross_revenue_payee_currency=29988) total.__setattr__('subaccount_revenue', 900) mock_totals = total expected_totals = { 'net_revenue_payee_currency': 1000, 'gross_revenue_payee_currency': 29988, 'subaccount_revenue': 900 } expected_items = [item.to_dict() for item in items] mock_models.RevenueByTransactionType.get_transaction_types_totals_by_account_id.return_value \ = mock_totals mock_models.RevenueByTransactionType.get_by_account_id.return_value = items expected_payload = ResponseRevenueByTransactionTypeSchema( totals=expected_totals, items=expected_items) subaccount_info = DimSubaccountFactory.build( subaccount_id=subaccount_id) mock_models.DimSubaccount.get_by_id.return_value = subaccount_info result = logic.get_revenue_analysis_by_transaction_type( account_id, None, None, None, None, None, None, subaccount_id, ORDER_BY_NET_REVENUE_PAYEE_CURRENCY, OrderDirection.DESC, None, True, None, None, None, None, None, None) assert result == expected_payload @patch('moneyhub.logic.revenue_analysis.models') def test_get_revenue_analysis_by_transaction_type_product_id_track_unique_id(mock_models): """Test to get revenue analysis info by transaction type for a product/track.""" account_id = 24601 subaccount_id = 24604 item1 = RevenueByTransactionTypeFactory.build( transaction_type_id=1, product_id=1, track_unique_id=1, transaction_type_desc='Downloaded Ringtones', transaction_type_group_name='Ringtone Group', account_payee_currency='USD', quantity=10, net_revenue_payee_currency=200, gross_revenue_payee_currency=220) item2 = RevenueByTransactionTypeFactory.build( transaction_type_id=1, product_id=1, track_unique_id=1, transaction_type_desc='Downloaded Ringtones', transaction_type_group_name='Ringtone Group', account_payee_currency='USD', quantity=5, net_revenue_payee_currency=100, gross_revenue_payee_currency=110) items = [item1, item2] total = RevenueByTransactionTypeFactory.build( net_revenue_payee_currency=1000, gross_revenue_payee_currency=29988) mock_totals = total expected_totals = { 'net_revenue_payee_currency': 1000, 'gross_revenue_payee_currency': 29988, } expected_items = [item.to_dict() for item in items] mock_models.RevenueByTransactionType.get_transaction_types_totals_by_account_id.return_value \ = mock_totals mock_models.RevenueByTransactionType.get_by_account_id.return_value = items expected_payload = ResponseRevenueByTransactionTypeSchema( totals=expected_totals, items=expected_items) subaccount_info = DimSubaccountFactory.build( subaccount_id=subaccount_id) mock_models.DimSubaccount.get_by_id.return_value = subaccount_info result = logic.get_revenue_analysis_by_transaction_type( account_id, None, None, None, None, None, None, subaccount_id, ORDER_BY_NET_REVENUE_PAYEE_CURRENCY, OrderDirection.DESC, None, False, product_id=1, track_unique_id=1, store_ids=None, country_codes=None, imprint_ids=None, transaction_type_ids=None ) assert result == expected_payload @patch('moneyhub.logic.revenue_analysis.models.RevenueByCountry') def test_get_revenue_analysis_by_country(mock_RevenueByCountry): """Test to get revenue analysis info by country.""" account_id = 57608 mock_model = RevenueByCountryFactory.build( account_id=account_id, net_revenue_payee_currency=20, gross_revenue_payee_currency=40) mock_RevenueByCountry.get_by_account_id.return_value = [mock_model.to_dict()] result = logic.get_revenue_analysis_by_country( account_id, None, None, None, None, None, None, None, None, None, None, None, None, None, False) assert result == [ { 'account_id': account_id, 'account_payee_currency': 'GBP', 'country_code': 'GB', 'net_revenue_payee_currency': 20, 'gross_revenue_payee_currency': 40, } ] mock_RevenueByCountry.get_by_account_id.assert_called_once_with( account_id, None, None, None, None, None, None, None, None, None, None, None, None, None, None, project_id=None, ) @patch('moneyhub.logic.revenue_analysis.models') def test_get_revenue_analysis_by_country_with_subaccount(mock_models): """Test to get revenue analysis info by country with subaccount info.""" account_id = 57608 subaccount_id = 10001 mock_revenue = RevenueByCountryFactory.build( account_id=account_id, net_revenue_payee_currency=20, gross_revenue_payee_currency=40).to_dict() mock_revenue['subaccount_revenue'] = 18 subaccount_info = DimSubaccountFactory.build( subaccount_id=subaccount_id) mock_models.RevenueByCountry.get_by_account_id.return_value = [mock_revenue] mock_models.DimSubaccount.get_by_id.return_value = subaccount_info result = logic.get_revenue_analysis_by_country( account_id, None, subaccount_id, None, None, None, None, None, None, None, None, None, None, None, True) assert result == [ { 'account_id': account_id, 'account_payee_currency': 'GBP', 'country_code': 'GB', 'net_revenue_payee_currency': 20, 'gross_revenue_payee_currency': 40, 'subaccount_revenue': 18 } ] mock_models.DimSubaccount.get_by_id.assert_called_once_with(10001) mock_models.RevenueByCountry.get_by_account_id.assert_called_once_with( account_id, None, subaccount_id, None, None, None, None, None, None, None, None, None, None, None, subaccount_info, project_id=None, ) @patch('moneyhub.logic.revenue_analysis.models.RevenueByCountry') def test_get_revenue_analysis_by_country_with_list_filters(mock_RevenueByCountry): """Test to get revenue analysis info by country with list filters.""" account_id = 57608 store_ids = [101, 102] country_codes = ['GB', 'NO'] imprint_ids = [201] transaction_type_ids = [301, 302] mock_model = RevenueByCountryFactory.build( account_id=account_id, net_revenue_payee_currency=30, gross_revenue_payee_currency=50) mock_RevenueByCountry.get_by_account_id.return_value = [mock_model.to_dict()] result = logic.get_revenue_analysis_by_country( account_id, None, None, None, None, None, None, None, None, None, store_ids, country_codes, imprint_ids, transaction_type_ids, False) assert result == [ { 'account_id': account_id, 'account_payee_currency': 'GBP', 'country_code': 'GB', 'net_revenue_payee_currency': 30, 'gross_revenue_payee_currency': 50, } ] mock_RevenueByCountry.get_by_account_id.assert_called_once_with( account_id, None, None, None, None, None, None, None, None, None, store_ids, country_codes, imprint_ids, transaction_type_ids, None, project_id=None, ) @patch('moneyhub.logic.revenue_analysis.models') def test_get_revenue_by_account(mock_models): """Test getting account revenue.""" account_id = 24601 visible_statement_periods = [285, 286] expected_response = AccountRevenueSchema( since_statement_period_id=285, currency_code='GBP', gross_revenue_payee_currency=Decimal('3757441.58'), net_revenue_payee_currency=Decimal('1234567.89'), ) mock_models.AccountStatementPeriods. \ get_activity_statement_period_ids.return_value = \ visible_statement_periods mock_models.RevenueByStatementPeriod.get_currencies_periods.return_value = \ [ RevenueByStatementPeriodFactory.build( account_payee_currency='GBP', statement_period_id=Decimal(286), ), RevenueByStatementPeriodFactory.build( account_payee_currency='GBP', statement_period_id=Decimal(285), ), ] mock_models.RevenueByStatementPeriod. \ get_revenue_total_for_account_statement_periods.return_value = \ { 'currency_code': 'GBP', 'gross_revenue_payee_currency': Decimal('3757441.58'), 'net_revenue_payee_currency': Decimal('1234567.89'), } result = logic.get_revenue_by_account(account_id, None, None) mock_models.AccountStatementPeriods.get_activity_statement_period_ids. \ assert_called_once_with(account_id=account_id) mock_models.RevenueByStatementPeriod.get_revenue_total_for_account_statement_periods. \ assert_called_once_with(account_id, 285, 286, None, None, None) mock_models.RevenueByStatementPeriod.get_currencies_periods.assert_called_once_with( account_id, visible_statement_periods, None, None) assert result == expected_response @patch('moneyhub.logic.revenue_analysis.models') def test_get_revenue_by_account_multiple_currencies(mock_models): """Test getting account revenue.""" account_id = 24601 visible_statement_periods = [284, 285, 286] expected_response = AccountRevenueSchema( since_statement_period_id=286, currency_code='NOK', gross_revenue_payee_currency=Decimal('3757441.58'), net_revenue_payee_currency=Decimal('1234567.89'), ) mock_models.AccountStatementPeriods. \ get_activity_statement_period_ids.return_value = \ visible_statement_periods mock_models.RevenueByStatementPeriod.get_currencies_periods.return_value = \ [ RevenueByStatementPeriodFactory.build( account_payee_currency='NOK', statement_period_id=Decimal(286), ), RevenueByStatementPeriodFactory.build( account_payee_currency='GBP', statement_period_id=Decimal(285), ), RevenueByStatementPeriodFactory.build( account_payee_currency='NOK', statement_period_id=Decimal(284), ), ] mock_models.RevenueByStatementPeriod. \ get_revenue_total_for_account_statement_periods.return_value = \ { 'currency_code': 'NOK', 'gross_revenue_payee_currency': Decimal('3757441.58'), 'net_revenue_payee_currency': Decimal('1234567.89'), } result = logic.get_revenue_by_account(account_id, None, None) mock_models.AccountStatementPeriods.get_activity_statement_period_ids. \ assert_called_once_with(account_id=account_id) mock_models.RevenueByStatementPeriod.get_revenue_total_for_account_statement_periods. \ assert_called_once_with(account_id, 286, 286, None, None, None) mock_models.RevenueByStatementPeriod.get_currencies_periods.assert_called_once_with( account_id, visible_statement_periods, None, None) assert result == expected_response @patch('moneyhub.logic.revenue_analysis.models') def test_get_revenue_by_account_subaccount(mock_models): """Test getting account revenue.""" account_id = 24601 visible_statement_periods = [285, 286] subaccount_id = 124 expected_response = AccountRevenueSchema( since_statement_period_id=285, currency_code='GBP', gross_revenue_payee_currency=Decimal('100000.00'), net_revenue_payee_currency=Decimal('100000.00'), subaccount_revenue=(Decimal('90000.00')) ) subaccount_info = DimSubaccountFactory.build(subaccount_id=subaccount_id) mock_models.DimSubaccount.get_by_id.return_value = subaccount_info mock_models.AccountStatementPeriods. \ get_activity_statement_period_ids.return_value = \ visible_statement_periods mock_models.RevenueByStatementPeriod.get_currencies_periods.return_value = \ [ RevenueByStatementPeriodFactory.build( account_payee_currency='GBP', statement_period_id=Decimal(286), ), RevenueByStatementPeriodFactory.build( account_payee_currency='GBP', statement_period_id=Decimal(285), ), ] mock_models.RevenueByStatementPeriod. \ get_revenue_total_for_account_statement_periods.return_value = \ { 'currency_code': 'GBP', 'gross_revenue_payee_currency': Decimal('100000.00'), 'net_revenue_payee_currency': Decimal('100000.00'), 'subaccount_revenue': Decimal('90000.00') } result = logic.get_revenue_by_account(account_id, None, subaccount_id, True) mock_models.AccountStatementPeriods.get_activity_statement_period_ids. \ assert_called_once_with(account_id=account_id) mock_models.RevenueByStatementPeriod.get_revenue_total_for_account_statement_periods. \ assert_called_once_with( account_id, 285, 286, None, subaccount_id, subaccount_info) assert result == expected_response @patch('moneyhub.logic.revenue_analysis.models') def test_get_revenue_by_account_no_data(mock_models): """Test getting account revenue when there is no data available.""" account_id = 24601 visible_statement_periods = [123, 456] expected_response = AccountRevenueSchema( currency_code='GBP', gross_revenue_payee_currency=Decimal(0.00), net_revenue_payee_currency=Decimal(0.00), ) mock_models.AccountStatementPeriods. \ get_activity_statement_period_ids.return_value = \ visible_statement_periods mock_models.RevenueByStatementPeriod.get_currencies_periods.return_value = [] mock_models.RevenueByStatementPeriod.get_revenue_total_for_account_statement_periods \ .return_value = None mock_models.AccountPaymentTerm.get_by_account_id.return_value = AccountPaymentTermFactory.build( currency_code='GBP' ) result = logic.get_revenue_by_account(account_id, None, None) mock_models.AccountStatementPeriods.get_activity_statement_period_ids. \ assert_called_once_with(account_id=account_id) mock_models.RevenueByStatementPeriod.get_revenue_total_for_account_statement_periods. \ assert_not_called() assert result == expected_response @patch('moneyhub.logic.revenue_analysis.models') def test_get_latest_revenue_by_account_id(mock_models): """Test latest getting account revenue.""" account_id = 24601 latest_statement_period = StatementPeriodFactory.build( statement_period_id=286, statement_period_name='August 2023' ) expected_response = AccountStatementPeriodRevenueSchema( statement_period_id=286, currency_code='GBP', gross_revenue_payee_currency=3757441.58, net_revenue_payee_currency=1234567.89, gross_publishing_revenue_payee_currency=None, net_publishing_revenue_payee_currency=None, subaccount_revenue=None ) mock_models.AccountPaymentTerm.get_by_account_id.return_value = AccountPaymentTermFactory.build( currency_code='GBP' ) mock_models.StatementPeriod.get_by_id.return_value = latest_statement_period mock_models.RevenueByStatementPeriod.get_by_account_id\ .return_value = [RevenueByStatementPeriodFactory.build( account_payee_currency='GBP', statement_period_id=286, gross_revenue_payee_currency=Decimal('3757441.58'), net_revenue_payee_currency=Decimal('1234567.89'), gross_publishing_revenue_payee_currency=None, net_publishing_revenue_payee_currency=None, )] result = logic.get_latest_revenue_by_account_id( account_id, latest_statement_period.statement_period_id, None, None, None, None, False) mock_models.RevenueByStatementPeriod.get_by_account_id. \ assert_called_once_with( account_id=account_id, contract_id=None, artist_id=None, subaccount_id=None, product_id=None, track_unique_id=None, statement_period_id_start=latest_statement_period.statement_period_id, statement_period_id_end=latest_statement_period.statement_period_id, subaccount_info=None, project_id=None ) assert result == expected_response @patch('moneyhub.logic.revenue_analysis.models') def test_get_latest_revenue_by_account_id_with_publishing(mock_models): """Test getting latest account revenue including publishing revenue.""" account_id = 24601 latest_statement_period = StatementPeriodFactory.build( statement_period_id=286, statement_period_name='August 2023' ) expected_response = AccountStatementPeriodRevenueSchema( statement_period_id=286, currency_code='GBP', gross_revenue_payee_currency=3757441.58, net_revenue_payee_currency=1234567.89, gross_publishing_revenue_payee_currency=0.0, net_publishing_revenue_payee_currency=512.34, subaccount_revenue=None ) mock_models.AccountPaymentTerm.get_by_account_id.return_value = AccountPaymentTermFactory.build( currency_code='GBP' ) mock_models.StatementPeriod.get_by_id.return_value = latest_statement_period mock_models.RevenueByStatementPeriod.get_by_account_id\ .return_value = [RevenueByStatementPeriodFactory.build( account_payee_currency='GBP', statement_period_id=286, gross_revenue_payee_currency=Decimal('3757441.58'), net_revenue_payee_currency=Decimal('1234567.89'), gross_publishing_revenue_payee_currency=Decimal('0.00'), net_publishing_revenue_payee_currency=Decimal('512.34'), )] result = logic.get_latest_revenue_by_account_id( account_id, latest_statement_period.statement_period_id, None, None, None, None, False) mock_models.RevenueByStatementPeriod.get_by_account_id. \ assert_called_once_with( account_id=account_id, contract_id=None, artist_id=None, subaccount_id=None, product_id=None, track_unique_id=None, statement_period_id_start=latest_statement_period.statement_period_id, statement_period_id_end=latest_statement_period.statement_period_id, subaccount_info=None, project_id=None ) assert result == expected_response @patch('moneyhub.logic.revenue_analysis.models') def test_get_latest_revenue_by_account_id_publishing_only(mock_models): """Test getting latest account revenue for a publishing-only period.""" account_id = 24601 latest_statement_period = StatementPeriodFactory.build( statement_period_id=286, statement_period_name='August 2023' ) expected_response = AccountStatementPeriodRevenueSchema( statement_period_id=286, currency_code='GBP', gross_revenue_payee_currency=None, net_revenue_payee_currency=None, gross_publishing_revenue_payee_currency=0.0, net_publishing_revenue_payee_currency=512.34, subaccount_revenue=None ) mock_models.AccountPaymentTerm.get_by_account_id.return_value = AccountPaymentTermFactory.build( currency_code='GBP' ) mock_models.StatementPeriod.get_by_id.return_value = latest_statement_period mock_models.RevenueByStatementPeriod.get_by_account_id\ .return_value = [RevenueByStatementPeriodFactory.build( account_payee_currency='GBP', statement_period_id=286, gross_revenue_payee_currency=None, net_revenue_payee_currency=None, gross_publishing_revenue_payee_currency=Decimal('0.00'), net_publishing_revenue_payee_currency=Decimal('512.34'), )] result = logic.get_latest_revenue_by_account_id( account_id, latest_statement_period.statement_period_id, None, None, None, None, False) assert result == expected_response @patch('moneyhub.logic.revenue_analysis.models') def test_get_latest_revenue_by_subaccount(mock_models): """Test latest getting account revenue for a subaccount.""" account_id = 24601 subaccount_id = 1234 product_id = 1 track_unique_id = 1 latest_statement_period = StatementPeriodFactory.build( statement_period_id=286, statement_period_name='August 2023' ) subaccount_info = DimSubaccountFactory.build( subaccount_id=subaccount_id) mock_models.DimSubaccount.get_by_id.return_value = subaccount_info expected_response = AccountStatementPeriodRevenueSchema( statement_period_id=286, currency_code='GBP', gross_revenue_payee_currency=1100.00, net_revenue_payee_currency=1000.00, gross_publishing_revenue_payee_currency=None, net_publishing_revenue_payee_currency=None, subaccount_revenue=900.0 ) mock_models.AccountPaymentTerm.get_by_account_id.return_value = AccountPaymentTermFactory.build( currency_code='GBP' ) mock_models.StatementPeriod.get_by_id.return_value = latest_statement_period revenue = RevenueByStatementPeriodFactory.build( account_payee_currency='GBP', statement_period_id=286, gross_revenue_payee_currency=Decimal('1100.00'), net_revenue_payee_currency=Decimal('1000.00'), gross_publishing_revenue_payee_currency=None, net_publishing_revenue_payee_currency=None, ) revenue.__setattr__('subaccount_revenue', Decimal('900.00')) mock_models.RevenueByStatementPeriod.get_by_account_id\ .return_value = [revenue] result = logic.get_latest_revenue_by_account_id( account_id, latest_statement_period.statement_period_id, None, subaccount_id, product_id, track_unique_id, True) mock_models.RevenueByStatementPeriod.get_by_account_id. \ assert_called_once_with( account_id=account_id, contract_id=None, artist_id=None, subaccount_id=subaccount_id, product_id=product_id, track_unique_id=track_unique_id, statement_period_id_start=latest_statement_period.statement_period_id, statement_period_id_end=latest_statement_period.statement_period_id, subaccount_info=subaccount_info, project_id=None ) assert result == expected_response @patch('moneyhub.logic.revenue_analysis.models') def test_get_latest_revenue_by_account_id_no_data(mock_models): """Test latest getting account revenue when there is no data available.""" account_id = 24601 latest_statement_period = StatementPeriodFactory.build( statement_period_id=456, statement_period_name='August 2023' ) expected_response = None mock_models.StatementPeriod.get_by_id.return_value = latest_statement_period mock_models.LedgerAccountingRunBalance.get_revenue_total_for_account_statement_periods\ .return_value = [RevenueByStatementPeriodFactory.build( account_payee_currency='USD', gross_revenue_payee_currency=Decimal(0), net_revenue_payee_currency=Decimal(0), )] mock_models.AccountPaymentTerm.get_by_account_id.return_value = None result = logic.get_latest_revenue_by_account_id( account_id, latest_statement_period.statement_period_id, None, None, None, None) mock_models.RevenueByStatementPeriod.get_by_account_id. \ assert_not_called() assert result == expected_response @patch('moneyhub.logic.revenue_analysis.models') def test_get_revenue_analysis_by_imprint(mock_models): """Test to get revenue info by imprint.""" account_id = 57608 subaccount_id = 57609 limit = 50 offset = 0 total_records = 1 payload = { 'items': [ { 'imprintid': 123456, 'imprint': 'TEST', 'contract_id': None, 'statement_period_id': 10, 'account_id': account_id, 'account_payee_currency': 'USD', 'mechanical_deduction_amount_payee_currency': 20.0, 'publisher_admin_fee_payee_currency': 2, 'net_share_payee_currency': 20.0, 'gross_revenue_payee_currency': 16.0, 'subaccount_id': 1234, 'subaccount_revenue': None }], 'pagination': { 'pagination_type': 'standard', 'total_records': 1, }, } mock_model = RevenueByImprintFactory.build( account_id=account_id, mechanical_deduction_amount_payee_currency=20, publisher_admin_fee_payee_currency=2, net_share_payee_currency=20, gross_revenue_payee_currency=16) mock_models.RevenueByImprint.get_by_account_id.return_value = ( [mock_model.to_dict()], total_records) result = logic.get_revenue_analysis_by_imprint( account_id, None, limit, offset, None, None, None, None, None, subaccount_id, ORDER_BY_IMPRINT, OrderDirection.ASC, None, None, None, None, None, False) assert result.__class__ == PaginatedRevenueByImprintSchema assert result == PaginatedRevenueByImprintSchema(**payload) mock_models.RevenueByImprint.get_by_account_id.assert_called_once_with( account_id, None, limit, offset, None, None, None, None, None, subaccount_id, ORDER_BY_IMPRINT, OrderDirection.ASC, None, None, None, None, None, None ) @patch('moneyhub.logic.revenue_analysis.models') def test_get_revenue_analysis_by_imprint_with_subaccount(mock_models): """Test to get revenue info by imprint for a subaccount.""" account_id = 57608 limit = 50 offset = 0 total_records = 1 subaccount_id = 1 subaccount_info = DimSubaccountFactory.build( subaccount_id=subaccount_id) payload = { 'items': [ { 'imprintid': 123456, 'imprint': 'TEST', 'contract_id': None, 'statement_period_id': 10, 'account_id': account_id, 'account_payee_currency': 'USD', 'mechanical_deduction_amount_payee_currency': 20.0, 'publisher_admin_fee_payee_currency': 2, 'net_share_payee_currency': 20.0, 'gross_revenue_payee_currency': 16.0, 'subaccount_id': 1234, 'subaccount_revenue': 18.0 }], 'pagination': { 'pagination_type': 'standard', 'total_records': 1, }, } mock_model = RevenueByImprintFactory.build( account_id=account_id, mechanical_deduction_amount_payee_currency=20, publisher_admin_fee_payee_currency=2, net_share_payee_currency=20, gross_revenue_payee_currency=16) mock_model = mock_model.to_dict() mock_model['subaccount_revenue'] = 18 mock_models.DimSubaccount.get_by_id.return_value = subaccount_info mock_models.RevenueByImprint.get_by_account_id.return_value = ( [mock_model], total_records) result = logic.get_revenue_analysis_by_imprint( account_id, None, limit, offset, None, None, None, None, None, subaccount_id, ORDER_BY_IMPRINT, OrderDirection.ASC, None, None, None, None, None, True) assert result.__class__ == PaginatedRevenueByImprintSchema assert result == PaginatedRevenueByImprintSchema(**payload) mock_models.RevenueByImprint.get_by_account_id.assert_called_once_with( account_id, None, limit, offset, None, None, None, None, None, subaccount_id, ORDER_BY_IMPRINT, OrderDirection.ASC, None, None, None, None, None, subaccount_info ) @patch('moneyhub.logic.revenue_analysis.models') def test_get_revenue_analysis_by_activity_month(mock_models): """Test to get revenue info by activity month.""" account_id = 57608 limit = 50 offset = 0 total_records = 1 payload = { 'items': [ { 'activity_period_id': 120, 'activity_month_name': 'July 2024', 'account_payee_currency': 'USD', 'net_share_payee_currency': 20.0, 'gross_revenue_payee_currency': 16.0, 'net_publishing_revenue_payee_currency': 8.0, 'gross_publishing_revenue_payee_currency': 10.0, }], 'pagination': { 'pagination_type': 'standard', 'total_records': 1, }, } mock_model = RevenueByActivityMonthFactory.build( account_id=account_id, activity_period_id=120, activity_month_name='July 2024', net_share_payee_currency=20, gross_revenue_payee_currency=16, net_publishing_revenue_payee_currency=8.0, gross_publishing_revenue_payee_currency=10.0, ) mock_models.RevenueByActivityMonth.get_revenue_by_activity_month_by_account_id.return_value = ( [mock_model.to_dict()], total_records) result = logic.get_revenue_analysis_by_activity_month( account_id, limit, offset, None, None, None, None, None, None, None, None, None, None, None, None, None, False) assert result.__class__ == PaginatedRevenueByActivityMonthSchema assert result == PaginatedRevenueByActivityMonthSchema(**payload) @patch('moneyhub.logic.revenue_analysis._get_subaccount_info') @patch('moneyhub.logic.revenue_analysis.models') def test_get_revenue_analysis_by_activity_month_with_subaccount_info(mock_models, mock_sub_info): """Test to get revenue info by activity month with subaccount info.""" account_id = 57608 limit = 50 offset = 0 total_records = 1 payload = { 'items': [ { 'activity_period_id': 120, 'activity_month_name': 'July 2024', 'account_payee_currency': 'USD', 'net_share_payee_currency': 20.0, 'gross_revenue_payee_currency': 16.0, 'net_publishing_revenue_payee_currency': None, 'gross_publishing_revenue_payee_currency': None, 'subaccount_revenue': 18.0, }], 'pagination': { 'pagination_type': 'standard', 'total_records': 1, }, } mock_model = RevenueByActivityMonthFactory.build( account_id=account_id, activity_period_id=120, activity_month_name='July 2024', net_share_payee_currency=20, gross_revenue_payee_currency=16, net_publishing_revenue_payee_currency=None, gross_publishing_revenue_payee_currency=None, ) mock_model = mock_model.to_dict() mock_model['subaccount_revenue'] = 18 mock_models.RevenueByActivityMonth.get_revenue_by_activity_month_by_account_id.return_value = ( [mock_model], total_records) mock_sub_info.return_value = DimSubaccountFactory result = logic.get_revenue_analysis_by_activity_month( account_id, limit, offset, None, None, None, None, None, None, None, None, None, None, None, None, None, is_subaccount=True) assert result.__class__ == PaginatedRevenueByActivityMonthSchema assert result == PaginatedRevenueByActivityMonthSchema(**payload) @patch('moneyhub.logic.revenue_analysis.models') def test_get_subaccount_info(mock_models): """Test returning subaccount info.""" subaccount_id = 46189 mock_models.DimSubaccount.get_by_id.return_value = DimSubaccountFactory.build( subaccount_id=subaccount_id) result = logic._get_subaccount_info(subaccount_id) assert result.subaccount_id == subaccount_id assert result.subaccount_split_type == 'Net' assert result.commission_override == 0.90 assert mock_models.DimSubaccount.get_by_id.called