aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorstuppie2026-10-12 16:59:03 -0700
committerstuppie2026-10-12 16:59:03 -0700
commit1746411f8dd0b880b3d069afc0b008a176fd811a (patch)
tree069e422f1914e70b5d15bee2057bb7c04bcc38dc
parentc975021688d2c195f8d585ebd919b9cbdacb09ad (diff)
downloadgeneralresearch-1746411f8dd0b880b3d069afc0b008a176fd811a.tar.gz
generalresearch-1746411f8dd0b880b3d069afc0b008a176fd811a.zip
BusinessCreate model. Remove payouts from Product (query for me). Pagination and ordering of business and product payouts
-rw-r--r--generalresearch/managers/gr/business.py7
-rw-r--r--generalresearch/managers/gr/team.py45
-rw-r--r--generalresearch/managers/thl/payout.py307
-rw-r--r--generalresearch/models/gr/business.py17
-rw-r--r--generalresearch/models/thl/product.py67
-rw-r--r--tests/managers/gr/test_business.py24
-rw-r--r--tests/managers/thl/test_ledger/test_thl_pem.py14
-rw-r--r--tests/models/gr/test_business.py8
-rw-r--r--tests/models/gr/test_team.py4
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