diff options
| -rw-r--r-- | generalresearch/managers/gr/business.py | 7 | ||||
| -rw-r--r-- | generalresearch/managers/gr/team.py | 45 | ||||
| -rw-r--r-- | generalresearch/managers/thl/payout.py | 307 | ||||
| -rw-r--r-- | generalresearch/models/gr/business.py | 17 | ||||
| -rw-r--r-- | generalresearch/models/thl/product.py | 67 | ||||
| -rw-r--r-- | tests/managers/gr/test_business.py | 24 | ||||
| -rw-r--r-- | tests/managers/thl/test_ledger/test_thl_pem.py | 14 | ||||
| -rw-r--r-- | tests/models/gr/test_business.py | 8 | ||||
| -rw-r--r-- | tests/models/gr/test_team.py | 4 |
9 files changed, 325 insertions, 168 deletions
diff --git a/generalresearch/managers/gr/business.py b/generalresearch/managers/gr/business.py index 664c746..238469c 100644 --- a/generalresearch/managers/gr/business.py +++ b/generalresearch/managers/gr/business.py @@ -16,6 +16,7 @@ from generalresearch.models.custom_types import UUIDStr from generalresearch.models.gr.business import ( Business, BusinessBankAccount, + BusinessCreate, ) from generalresearch.models.gr.definitions import BusinessType, TransferMethod @@ -208,7 +209,7 @@ class BusinessManager(PostgresManagerWithRedis): Behavior: does this raise on duplicate? """ # Business.model_rebuild() - business = Business.model_validate( + business = BusinessCreate.model_validate( { "uuid": uuid or uuid4().hex, "name": name, @@ -231,13 +232,13 @@ class BusinessManager(PostgresManagerWithRedis): ) business_id = c.fetchone()["id"] # type: ignore conn.commit() - business.id = business_id if team: from generalresearch.managers.gr.team import TeamManager + assert team.id is not None, "Team must be persisted before adding a Business" tm = TeamManager(pg_config=self.pg_config, redis_config=self.redis_config) - tm.add_business(team=team, business=business) + tm.add_business(team_id=team.id, business_id=business_id) persisted_business = self.get_by_id(business_id=business_id) assert persisted_business is not None diff --git a/generalresearch/managers/gr/team.py b/generalresearch/managers/gr/team.py index 968f3b5..781cf1f 100644 --- a/generalresearch/managers/gr/team.py +++ b/generalresearch/managers/gr/team.py @@ -4,7 +4,7 @@ from datetime import UTC, datetime from typing import TYPE_CHECKING from uuid import uuid4 -from psycopg import sql +from psycopg import Connection, sql from pydantic import PositiveInt from generalresearch.managers.base import ( @@ -19,9 +19,7 @@ from generalresearch.models.gr.team import ( ) if TYPE_CHECKING: - from generalresearch.models.gr.authentication import GRUser - from generalresearch.models.gr.business import Business from generalresearch.models.gr.team import Team @@ -139,7 +137,6 @@ class MembershipManager(PostgresManager): class TeamManager(PostgresManagerWithRedis): - def get_or_create( self, uuid: UUIDStr | None = None, name: str | None = None ) -> Team: @@ -155,10 +152,12 @@ class TeamManager(PostgresManagerWithRedis): from generalresearch.models.gr.team import Team with self.pg_config.make_connection() as conn, conn.cursor() as c: - c.execute(query=sql.SQL(""" + c.execute( + query=sql.SQL(""" SELECT t.id, t.uuid, t.name FROM common_team AS t - """)) + """) + ) res = c.fetchall() return [Team.model_validate(i) for i in res] @@ -196,26 +195,30 @@ class TeamManager(PostgresManagerWithRedis): team.prefetch_gr_users(gr_user_manager=gr_user_manager) assert gr_user not in team.gr_users, ( - "Can't create multiple Memberships for " "the same User to the same Team" + "Can't create multiple Memberships for the same User to the same Team" ) mm = MembershipManager(pg_config=self.pg_config) return mm.create(team=team, gr_user=gr_user) - def add_business(self, team: Team, business: Business) -> None: - with self.pg_config.make_connection() as conn: - with conn.cursor() as c: - c.execute( - query=sql.SQL(""" - INSERT INTO common_team_businesses - (team_id, business_id) - VALUES (%s, %s) - """), - params=( - team.id, - business.id, - ), - ) + def add_business( + self, + team_id: PositiveInt, + business_id: PositiveInt, + conn: Connection | None = None, + ) -> None: + with self.connection(conn) as conn, conn.cursor() as c: + c.execute( + query=sql.SQL(""" + INSERT INTO common_team_businesses + (team_id, business_id) + VALUES (%s, %s) + """), + params=( + team_id, + business_id, + ), + ) conn.commit() def get_by_uuid(self, team_uuid: UUIDStr) -> Team | None: diff --git a/generalresearch/managers/thl/payout.py b/generalresearch/managers/thl/payout.py index 4a3aad7..70046a3 100644 --- a/generalresearch/managers/thl/payout.py +++ b/generalresearch/managers/thl/payout.py @@ -183,7 +183,11 @@ class BrokerageProductPayoutEventManager(PayoutEventManager): product_ids: Collection[str] | None = None, cashout_types: Collection[PayoutType] | None = None, statuses: Collection[PayoutStatus] | None = None, - ) -> list[BrokerageProductPayoutEvent]: + page: int | None = None, + size: int | None = None, + order_field: str = "created", + descending: bool = False, + ) -> tuple[list[BrokerageProductPayoutEvent], NonNegativeInt]: """Try to retrieve BP payout events. WARNING: This is only on the "payout events" table and nothing to @@ -191,71 +195,158 @@ class BrokerageProductPayoutEventManager(PayoutEventManager): *** IT IS ONLY FOR Brokerage Product PAYOUTS *** """ - params = {} - filters = [] + filter_str, params = self.make_filter_str( + ext_ref_id=ext_ref_id, + debit_account_uuids=debit_account_uuids, + amount=amount, + created=created, + created_after=created_after, + product_ids=product_ids, + cashout_types=cashout_types, + statuses=statuses, + ) + pagination_sql = "" + if page is not None or size is not None: + pagination_sql = self.validate_pagination(page=page, size=size) + order_fields = { + "created": "ep.created", + "amount": "ep.amount", + "status": "ep.status", + } + order_by_sql = ( + f"{order_fields[order_field]} {'DESC' if descending else 'ASC'}, ep.uuid" + ) + + res = self.pg_config.execute_sql_query( + query=f""" + SELECT ep.uuid, ep.debit_account_uuid, ep.cashout_method_uuid, + ep.created, ep.amount, ep.status, ep.ext_ref_id, + ep.payout_type, ep.supplier_payout_id, + ep.request_data::jsonb, ep.order_data::jsonb, + ac.name as description, + la.reference_uuid as product_id + FROM event_payout AS ep + LEFT JOIN accounting_cashoutmethod AS ac + ON ep.cashout_method_uuid = ac.id + LEFT JOIN ledger_account AS la + ON la.uuid = ep.debit_account_uuid + {filter_str} + ORDER BY {order_by_sql} + {pagination_sql} + """, + params=params, + ) + pes = [] + for row in res: + pes.append(BrokerageProductPayoutEvent.model_validate(row)) + count = self.filter_count( + ext_ref_id=ext_ref_id, + debit_account_uuids=debit_account_uuids, + amount=amount, + created=created, + created_after=created_after, + product_ids=product_ids, + cashout_types=cashout_types, + statuses=statuses, + ) + return pes, count + + def filter_count( + self, + ext_ref_id: str | None = None, + debit_account_uuids: Collection[UUIDStr] | None = None, + amount: int | None = None, + created: datetime | None = None, + created_after: datetime | None = None, + product_ids: Collection[str] | None = None, + cashout_types: Collection[PayoutType] | None = None, + statuses: Collection[PayoutStatus] | None = None, + ) -> NonNegativeInt: + filter_str, params = self.make_filter_str( + ext_ref_id=ext_ref_id, + debit_account_uuids=debit_account_uuids, + amount=amount, + created=created, + created_after=created_after, + product_ids=product_ids, + cashout_types=cashout_types, + statuses=statuses, + ) + res = self.pg_config.execute_sql_query( + query=f""" + SELECT COUNT(1) AS cnt + FROM event_payout AS ep + LEFT JOIN ledger_account AS la + ON la.uuid = ep.debit_account_uuid + {filter_str} + """, + params=params, + ) + return int(res[0]["cnt"]) + + def make_filter_str( + self, + ext_ref_id: str | None = None, + debit_account_uuids: Collection[UUIDStr] | None = None, + amount: int | None = None, + created: datetime | None = None, + created_after: datetime | None = None, + product_ids: Collection[str] | None = None, + cashout_types: Collection[PayoutType] | None = None, + statuses: Collection[PayoutStatus] | None = None, + ) -> tuple[str, dict[str, Any]]: + params: dict[str, Any] = { + "cashout_method_uuid": self.CASHOUT_METHOD_UUID, + } + filters = [ + "ep.cashout_method_uuid = %(cashout_method_uuid)s", + "la.reference_type = 'bp'", + ] + supplied_filter = False if ext_ref_id: - # This is transaction id for tracking ACH/Wires with a banking institution filters.append("ep.ext_ref_id = %(ext_ref_id)s") params["ext_ref_id"] = ext_ref_id + supplied_filter = True if debit_account_uuids: - # Or we could use the bp_wallet's account uuid - # instead of looking up by the product filters.append("ep.debit_account_uuid = ANY(%(debit_account_uuids)s)") - params["debit_account_uuids"] = debit_account_uuids + params["debit_account_uuids"] = list(debit_account_uuids) + supplied_filter = True if amount: filters.append("ep.amount = %(amount)s") params["amount"] = amount + supplied_filter = True if created: filters.append("ep.created = %(created)s") params["created"] = created + supplied_filter = True if created_after: filters.append("ep.created >= %(created_after)s") params["created_after"] = created_after + supplied_filter = True if product_ids is not None: filters.append("la.reference_uuid = ANY(%(product_ids)s)") - params["product_ids"] = product_ids + params["product_ids"] = list(product_ids) + supplied_filter = True if cashout_types is not None: - filters.append("payout_type = ANY(%(cashout_types)s)") + filters.append("ep.payout_type = ANY(%(cashout_types)s)") params["cashout_types"] = [x.value for x in cashout_types] + supplied_filter = True if statuses is not None: - filters.append("status = ANY(%(statuses)s)") + filters.append("ep.status = ANY(%(statuses)s)") params["statuses"] = [x.value for x in statuses] + supplied_filter = True - assert len(filters) > 0, "must pass at least 1 filter" - filter_str = " AND ".join(filters) - params["cashout_method_uuid"] = self.CASHOUT_METHOD_UUID - - res = self.pg_config.execute_sql_query( - query=f""" - SELECT ep.uuid, ep.debit_account_uuid, ep.cashout_method_uuid, - ep.created, ep.amount, ep.status, ep.ext_ref_id, - ep.payout_type, ep.supplier_payout_id, - ep.request_data::jsonb, ep.order_data::jsonb, - ac.name as description, - la.reference_uuid as product_id - FROM event_payout AS ep - LEFT JOIN accounting_cashoutmethod AS ac - ON ep.cashout_method_uuid = ac.id - LEFT JOIN ledger_account AS la - ON la.uuid = ep.debit_account_uuid - WHERE cashout_method_uuid = %(cashout_method_uuid)s - AND la.reference_type = 'bp' - AND {filter_str} - """, - params=params, - ) - pes = [] - for row in res: - pes.append(BrokerageProductPayoutEvent.model_validate(row)) - return pes + assert supplied_filter, "must pass at least 1 filter" + return "WHERE " + " AND ".join(filters), params def get_bp_payout_events_for_accounts( self, accounts: Collection[LedgerAccount] ) -> list[BrokerageProductPayoutEvent]: - return self.filter_by( + payout_events, _ = self.filter_by( debit_account_uuids=[i.uuid for i in accounts], cashout_types=[PayoutType.ACH], ) + return payout_events def get_bp_bp_payout_events_for_products( self, @@ -271,12 +362,10 @@ class BrokerageProductPayoutEventManager(PayoutEventManager): assert len(product_uuids) > 0, "Must provide product_uuids" order_by = order_by or OrderBy.ASC - payout_events = self.filter_by( + payout_events, _ = self.filter_by( product_ids=product_uuids, cashout_types=[PayoutType.ACH], - ) - payout_events = sorted( - payout_events, key=lambda x: x.created, reverse=order_by == OrderBy.DESC + descending=order_by == OrderBy.DESC, ) return payout_events @@ -389,52 +478,37 @@ class BusinessPayoutEventManager(PostgresManagerWithRedis): self.bp_pe_manager = BrokerageProductPayoutEventManager(*arg, **kwargs) def get_by_ext_ref_id(self, ext_ref_id: str) -> BusinessPayoutEvent: - res = self.pg_config.execute_sql_query( - """ - SELECT - sp.*, - ep.bp_payouts - FROM supplier_payout sp - JOIN ( - SELECT - ep_inner.supplier_payout_id, - jsonb_agg( - to_jsonb(ep_inner) - || jsonb_build_object('product_id', la.reference_uuid) - ORDER BY ep_inner.created - ) AS bp_payouts - FROM event_payout ep_inner - JOIN ledger_account la - ON ep_inner.debit_account_uuid = la.uuid - GROUP BY ep_inner.supplier_payout_id - ) ep ON sp.id = ep.supplier_payout_id - WHERE sp.ext_ref_id = %(ext_ref_id)s - """, - {"ext_ref_id": ext_ref_id}, - ) - assert len(res) == 1, f"No Business Payout found with ext ref: {ext_ref_id}" - d = res[0] - for bp_payout in d["bp_payouts"]: - bp_payout["created"] = datetime.fromisoformat(bp_payout["created"]) - bpe = BusinessPayoutEvent.model_validate(d) - assert bpe.bp_payouts is not None and len(bpe.bp_payouts) > 0, ( - "No BP payouts found for this Business Payout Event. This shouldn't happen!" - ) - return bpe + payouts, count = self.filter_by(ext_ref_id=ext_ref_id) + assert count == 1, f"No Business Payout found with ext ref: {ext_ref_id}" + assert len(payouts) == 1 + return payouts[0] def filter_by( self, business_uuids: Collection[UUIDStr] | None = None, - ) -> list[BusinessPayoutEvent]: - - params = {} - filters = [] - if business_uuids is not None: - filters.append("business_id = ANY(%(business_uuids)s)") - params["business_uuids"] = business_uuids - - assert len(filters) > 0, "must pass at least 1 filter" - filter_str = " AND ".join(filters) + business_uuid: UUIDStr | None = None, + ext_ref_id: str | None = None, + page: int | None = None, + size: int | None = None, + order_field: str = "created", + descending: bool = False, + ) -> tuple[list[BusinessPayoutEvent], NonNegativeInt]: + filter_str, params = self.make_filter_str( + business_uuids=business_uuids, + business_uuid=business_uuid, + ext_ref_id=ext_ref_id, + ) + pagination_sql = "" + if page is not None or size is not None: + pagination_sql = self.validate_pagination(page=page, size=size) + order_fields = { + "created": "sp.created", + "amount": "sp.amount", + "status": "sp.status", + } + order_by_sql = ( + f"{order_fields[order_field]} {'DESC' if descending else 'ASC'}, sp.id" + ) res = self.pg_config.execute_sql_query( f""" @@ -455,7 +529,9 @@ class BusinessPayoutEventManager(PostgresManagerWithRedis): ON ep_inner.debit_account_uuid = la.uuid GROUP BY ep_inner.supplier_payout_id ) ep ON sp.id = ep.supplier_payout_id - WHERE {filter_str} + {filter_str} + ORDER BY {order_by_sql} + {pagination_sql} """, params, ) @@ -468,7 +544,54 @@ class BusinessPayoutEventManager(PostgresManagerWithRedis): "No BP payouts found for this Business Payout Event. This shouldn't happen!" ) bpes.append(bpe) - return bpes + count = self.filter_count( + business_uuids=business_uuids, + business_uuid=business_uuid, + ext_ref_id=ext_ref_id, + ) + return bpes, count + + def filter_count( + self, + business_uuids: Collection[UUIDStr] | None = None, + business_uuid: UUIDStr | None = None, + ext_ref_id: str | None = None, + ) -> NonNegativeInt: + filter_str, params = self.make_filter_str( + business_uuids=business_uuids, + business_uuid=business_uuid, + ext_ref_id=ext_ref_id, + ) + res = self.pg_config.execute_sql_query( + f""" + SELECT COUNT(1) AS cnt + FROM supplier_payout AS sp + {filter_str} + """, + params, + ) + return int(res[0]["cnt"]) + + @staticmethod + def make_filter_str( + business_uuids: Collection[UUIDStr] | None = None, + business_uuid: UUIDStr | None = None, + ext_ref_id: str | None = None, + ) -> tuple[str, dict[str, Any]]: + params: dict[str, Any] = {} + filters = [] + if business_uuids is not None: + filters.append("sp.business_id = ANY(%(business_uuids)s)") + params["business_uuids"] = list(business_uuids) + if business_uuid is not None: + filters.append("sp.business_id = %(business_uuid)s") + params["business_uuid"] = business_uuid + if ext_ref_id: + filters.append("sp.ext_ref_id = %(ext_ref_id)s") + params["ext_ref_id"] = ext_ref_id + + assert len(filters) > 0, "must pass at least 1 filter" + return "WHERE " + " AND ".join(filters), params def validate_business_payout_in_ledger( self, ext_ref_id: str, thl_lm: ThlLedgerManager @@ -542,18 +665,6 @@ class BusinessPayoutEventManager(PostgresManagerWithRedis): return - def get_business_payout_events_for_business( - self, - business_uuid: UUIDStr, - order_by: OrderBy | None = OrderBy.ASC, - ) -> list[BusinessPayoutEvent]: - order_by = order_by or OrderBy.ASC - bpes = self.filter_by( - business_uuids=[business_uuid], - ) - bpes = sorted(bpes, key=lambda x: x.created, reverse=order_by == OrderBy.DESC) - return bpes - @staticmethod def recoup_proportional( df: pd.DataFrame, diff --git a/generalresearch/models/gr/business.py b/generalresearch/models/gr/business.py index 3deff19..5ab819f 100644 --- a/generalresearch/models/gr/business.py +++ b/generalresearch/models/gr/business.py @@ -180,12 +180,11 @@ class BusinessContact(BaseModel): ) -class Business(BaseModel): +class BusinessCreate(BaseModel): """This is the Base model to represent a Business,""" model_config = ConfigDict(extra="ignore") - id: SkipJsonSchema[PositiveInt | None] = Field(default=None) uuid: UUIDStrCoerce = Field(examples=[uuid4().hex]) name: str = Field( @@ -256,7 +255,11 @@ class Business(BaseModel): def __repr__(self): return f"<Business: {self.name} ({self.uuid}) >" - # --- Prefetch --- + +class Business(BusinessCreate): + id: SkipJsonSchema[PositiveInt] = Field(exclude=True) + + # --- Prefetch --- def prefetch_addresses(self, pg_config: PostgresConfig) -> None: with ( @@ -437,6 +440,7 @@ class Business(BaseModel): assert lm.currency self.prefetch_products(product_manager=product_manager) + assert self.products is not None, "prefetch products" accounts: list[LedgerAccount] = lm.get_accounts_if_exists( qualified_names=( @@ -694,11 +698,8 @@ class Business(BaseModel): # --- Properties --- @property - def product_uuids(self) -> list[UUIDStr] | None: - if self.products is None: - LOG.warning("prefetch not run") - return None - + def product_uuids(self) -> list[UUIDStr]: + assert self.products is not None, "prefetch not run" return [p.uuid for p in self.products] @property diff --git a/generalresearch/models/thl/product.py b/generalresearch/models/thl/product.py index e7b4e31..302b013 100644 --- a/generalresearch/models/thl/product.py +++ b/generalresearch/models/thl/product.py @@ -973,11 +973,13 @@ class Product(BaseModel, validate_assignment=True): balance: ProductBalances | None = Field(default=None, description="Product Balance") user_wallet_balance: ProductUserWalletBalances | None = Field(default=None) - payouts: ProductPayouts | None = Field( - default=None, - description="Product Payouts. These are the ACH or Wire payments that were sent to the" - "Business on behalf of this specific Product", - ) + + # This should be queried for + # payouts: ProductPayouts | None = Field( + # default=None, + # description="Product Payouts. These are the ACH or Wire payments that were sent to the" + # "Business on behalf of this specific Product", + # ) pop_financial: ProductPOPFinancials | None = Field(default=None) users_active_7d: int | None = Field( @@ -1408,32 +1410,32 @@ class Product(BaseModel, validate_assignment=True): self.pop_financial = ProductPOPFinancials(periods=periods) - def prebuild_payouts( - self, - bp_pem: BrokerageProductPayoutEventManager, - ) -> None: - LOG.debug(f"Product.prebuild_payouts({self.uuid=})") - from generalresearch.models.thl.ledger import OrderBy - - events = bp_pem.get_bp_bp_payout_events_for_products( - product_uuids=[self.uuid], - order_by=OrderBy.DESC, - ) - self.payouts = ProductPayouts(events=events) - - @computed_field - @property - def payouts_total(self) -> USDCent | None: - if self.payouts is None: - return None - return USDCent(sum(event.amount for event in self.payouts.events)) - - @computed_field - @property - def payouts_total_str(self) -> str | None: - if self.payouts_total is None: - return None - return self.payouts_total.to_usd_str() + # def prebuild_payouts( + # self, + # bp_pem: BrokerageProductPayoutEventManager, + # ) -> None: + # LOG.debug(f"Product.prebuild_payouts({self.uuid=})") + # from generalresearch.models.thl.ledger import OrderBy + # + # events = bp_pem.get_bp_bp_payout_events_for_products( + # product_uuids=[self.uuid], + # order_by=OrderBy.DESC, + # ) + # self.payouts = ProductPayouts(events=events) + # + # @computed_field + # @property + # def payouts_total(self) -> USDCent | None: + # if self.payouts is None: + # return None + # return USDCent(sum(event.amount for event in self.payouts.events)) + # + # @computed_field + # @property + # def payouts_total_str(self) -> str | None: + # if self.payouts_total is None: + # return None + # return self.payouts_total.to_usd_str() def set_cache( self, @@ -1484,7 +1486,8 @@ class Product(BaseModel, validate_assignment=True): self.prebuild_user_wallet_balances( pop_ledger_df=pop_ledger_df, ) - self.prebuild_payouts(bp_pem=bp_pem) + # This should be queried for + # self.prebuild_payouts(bp_pem=bp_pem) self.prebuild_pop_financial( thl_lm=thl_lm, pop_ledger_df=pop_ledger_df, diff --git a/tests/managers/gr/test_business.py b/tests/managers/gr/test_business.py index 022086a..f5ea9f0 100644 --- a/tests/managers/gr/test_business.py +++ b/tests/managers/gr/test_business.py @@ -136,13 +136,13 @@ class TestBusinessManager: # Add the Business to the Team... now the Business should be available # to the gr_user - gr_team_manager.add_business(team=t1, business=b1) + gr_team_manager.add_business(team_id=t1.id, business_id=b1.id) res = gr_business_manager.get_by_user_id(user_id=gr_user.id) assert len(res) == 1 # Add another Business to the Team! b2 = gr_business_factory() - gr_team_manager.add_business(team=t1, business=b2) + gr_team_manager.add_business(team_id=t1.id, business_id=b2.id) res = gr_business_manager.get_by_user_id(user_id=gr_user.id) assert len(res) == 2 @@ -164,6 +164,26 @@ class TestBusinessManager: assert isinstance(instance, Business) assert gr_business.uuid == instance.uuid + def test_get_methods_include_cached_fields( + self, gr_business: Business, gr_business_manager: BusinessManager + ): + gr_business.users_active_7d = 11 + gr_business.task_completes_7d = 22 + gr_business.balance_net_7d = 33 + gr_business_manager.update_cached_fields(gr_business) + + by_id = gr_business_manager.get_by_id(business_id=gr_business.id) + by_uuid = gr_business_manager.get_by_uuid(business_uuid=gr_business.uuid) + filtered = gr_business_manager.filter(business_id=gr_business.id) + + assert by_id is not None + assert by_uuid is not None + assert len(filtered) == 1 + for business in (by_id, by_uuid, filtered[0]): + assert business.users_active_7d == 11 + assert business.task_completes_7d == 22 + assert business.balance_net_7d == 33 + def test_cache_key(self, gr_business: Business): assert "business:" in gr_business.cache_key diff --git a/tests/managers/thl/test_ledger/test_thl_pem.py b/tests/managers/thl/test_ledger/test_thl_pem.py index 348a02d..ddf9bc9 100644 --- a/tests/managers/thl/test_ledger/test_thl_pem.py +++ b/tests/managers/thl/test_ledger/test_thl_pem.py @@ -69,13 +69,25 @@ class TestThlPayoutEventManager: accounts = thl_ledger_manager.get_accounts_bp_wallet_for_products( product_uuids=[i.uuid for i in products] ) - res = brokerage_product_payout_event_manager.filter_by( + res, count = brokerage_product_payout_event_manager.filter_by( debit_account_uuids=[i.uuid for i in accounts] ) assert len(res) == (N_PRODUCTS * N_PAYOUT_EVENTS) + assert count == len(res) assert sum([i.amount for i in res]) == sum(amounts) + page, count = brokerage_product_payout_event_manager.filter_by( + debit_account_uuids=[i.uuid for i in accounts], + page=1, + size=2, + order_field="created", + descending=True, + ) + assert len(page) == 2 + assert count == (N_PRODUCTS * N_PAYOUT_EVENTS) + assert page == sorted(page, key=lambda payout: payout.created, reverse=True) + def test_get_bp_payout_events_for_product( self, product_factory: Callable[..., Product], diff --git a/tests/models/gr/test_business.py b/tests/models/gr/test_business.py index 8de2a47..7e0932c 100644 --- a/tests/models/gr/test_business.py +++ b/tests/models/gr/test_business.py @@ -218,7 +218,9 @@ class TestBusiness: assert isinstance(gr_business.teams, list) assert len(gr_business.teams) == 0 - gr_team_manager.add_business(team=gr_team, business=gr_business) + gr_team_manager.add_business( + team_id=gr_team.id, business_id=gr_business.id + ) assert len(gr_business.teams) == 0 gr_business.prefetch_teams(pg_config=gr_db) assert len(gr_business.teams) == 1 @@ -1246,7 +1248,9 @@ class TestBusinessMethods: p1 = product_factory(team=gr_team, business=gr_business) u1 = user_factory(product=p1) - gr_team_manager.add_business(team=gr_team, business=gr_business) + gr_team_manager.add_business( + team_id=gr_team.id, business_id=gr_business.id + ) # Business needs tx & incite to build balance delete_ledger_db() diff --git a/tests/models/gr/test_team.py b/tests/models/gr/test_team.py index 7c93209..8cc00c8 100644 --- a/tests/models/gr/test_team.py +++ b/tests/models/gr/test_team.py @@ -117,7 +117,9 @@ class TestTeam: assert isinstance(gr_team.businesses, list) assert len(gr_team.businesses) == 0 - gr_team_manager.add_business(team=gr_team, business=gr_business) + gr_team_manager.add_business( + team_id=gr_team.id, business_id=gr_business.id + ) assert len(gr_team.businesses) == 0 gr_team.prefetch_businesses(gr_business_manager=gr_business_manager) assert len(gr_team.businesses) == 1 |
