aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorstuppie2026-10-12 12:58:37 -0700
committerstuppie2026-10-12 12:58:37 -0700
commitc975021688d2c195f8d585ebd919b9cbdacb09ad (patch)
treef70b920f89451e5d2b27d310853e23a278ce6a7d
parentae15e98e3dfef9c8b00b232fc74654499e119da1 (diff)
downloadgeneralresearch-3.7.9.tar.gz
generalresearch-3.7.9.zip
Business common filter method. Remove payout attribute (should be called explicitly)HEADv3.7.9master
-rw-r--r--generalresearch/managers/gr/business.py168
-rw-r--r--generalresearch/models/gr/business.py76
-rw-r--r--pyproject.toml2
3 files changed, 120 insertions, 126 deletions
diff --git a/generalresearch/managers/gr/business.py b/generalresearch/managers/gr/business.py
index 734ba55..664c746 100644
--- a/generalresearch/managers/gr/business.py
+++ b/generalresearch/managers/gr/business.py
@@ -73,7 +73,7 @@ class BusinessBankAccountManager(PostgresManager):
ba.id = ba_id
return ba
- def get_by_business_id(self, business_id: UUIDStr) -> list[BusinessBankAccount]:
+ def get_by_business_id(self, business_id: int) -> list[BusinessBankAccount]:
with self.pg_config.make_connection() as conn, conn.cursor() as c:
c.execute(
@@ -239,7 +239,9 @@ class BusinessManager(PostgresManagerWithRedis):
tm = TeamManager(pg_config=self.pg_config, redis_config=self.redis_config)
tm.add_business(team=team, business=business)
- return business
+ persisted_business = self.get_by_id(business_id=business_id)
+ assert persisted_business is not None
+ return persisted_business
def get_all(self) -> list[Business]:
"""WARNING: This should be access by the /god/ page only, and only
@@ -251,84 +253,86 @@ class BusinessManager(PostgresManagerWithRedis):
:return:
"""
- from generalresearch.models.gr.business import Business
+ return self.filter()
- with self.pg_config.make_connection() as conn, conn.cursor() as c:
- c.execute(query=sql.SQL("""
- SELECT b.id, b.uuid, b.kind, b.name, b.tax_number
- FROM common_business AS b
- """))
- res = c.fetchall()
+ def filter(
+ self,
+ *,
+ business_id: PositiveInt | None = None,
+ business_uuid: UUIDStr | None = None,
+ team_id: PositiveInt | None = None,
+ user_id: PositiveInt | None = None,
+ ) -> list[Business]:
+ """Return businesses matching all of the supplied identifiers."""
+ joins: list[sql.Composable] = []
+ conditions: list[sql.Composable] = []
+ params: list[int | str] = []
+
+ if business_id is not None:
+ conditions.append(sql.SQL("b.id = %s"))
+ params.append(business_id)
+ if business_uuid is not None:
+ conditions.append(sql.SQL("b.uuid = %s"))
+ params.append(business_uuid)
+ if team_id is not None or user_id is not None:
+ joins.append(
+ sql.SQL("""
+ INNER JOIN common_team_businesses AS tb
+ ON tb.business_id = b.id
+ """)
+ )
+ if team_id is not None:
+ conditions.append(sql.SQL("tb.team_id = %s"))
+ params.append(team_id)
+ if user_id is not None:
+ joins.append(
+ sql.SQL("""
+ INNER JOIN common_membership AS m
+ ON m.team_id = tb.team_id
+ """)
+ )
+ conditions.append(sql.SQL("m.user_id = %s"))
+ params.append(user_id)
+
+ where = sql.SQL("")
+ if conditions:
+ where = sql.SQL("WHERE ") + sql.SQL(" AND ").join(conditions)
- response = []
- for i in res:
- # i["contact"] = BusinessContact.model_validate(i)
- # i["address"] = BusinessAddress.model_validate(i)
- i["contact"] = None
- i["address"] = None
+ query = sql.SQL("""
+ SELECT DISTINCT
+ b.id,
+ b.uuid,
+ b.kind,
+ b.name,
+ b.tax_number,
+ b.balance,
+ b.user_wallet_balance,
+ b.users_active_7d,
+ b.task_completes_7d,
+ b.balance_net_7d
+ FROM common_business AS b
+ {joins}
+ {where}
+ """).format(joins=sql.SQL(" ").join(joins), where=where)
- response.append(Business.model_validate(i))
+ with self.pg_config.make_connection() as conn, conn.cursor() as c:
+ c.execute(query=query, params=params)
+ res = c.fetchall()
- return response
+ return [Business.model_validate(item) for item in res]
def get_by_team(
self,
team_id: PositiveInt,
) -> list[Business]:
- # conn: psycopg.Connection = GR_POSTGRES_C.make_connection()
- with self.pg_config.make_connection() as conn, conn.cursor() as c:
- c.execute(
- query=sql.SQL("""
- SELECT b.id, b.uuid, b.kind, b.name, b.tax_number
- FROM common_business AS b
- INNER JOIN common_team_businesses as tb
- ON tb.business_id = b.id
- WHERE tb.team_id = %s
- """),
- params=(team_id,),
- )
-
- res = c.fetchall()
-
- response = []
-
- for i in res:
- # i["contact"] = BusinessContact.model_validate(i)
- # i["address"] = BusinessAddress.model_validate(i)
- response.append(Business.model_validate(i))
-
- return response
+ return self.filter(team_id=team_id)
def get_by_user_id(
self,
user_id: PositiveInt,
) -> list[Business]:
- from generalresearch.models.gr.business import Business
-
- with self.pg_config.make_connection() as conn, conn.cursor() as c:
- c.execute(
- query=sql.SQL("""
- SELECT b.id, b.uuid, b.kind, b.name, b.tax_number
- FROM common_business AS b
- INNER JOIN common_team_businesses AS tb
- ON tb.business_id = b.id
- INNER JOIN common_membership AS m
- ON m.team_id = tb.team_id
- WHERE m.user_id = %s
- """),
- params=(user_id,),
- )
-
- res = c.fetchall()
-
- response = []
- for i in res:
- # i["contact"] = BusinessContact.model_validate(i)
- # i["address"] = BusinessAddress.model_validate(i)
- response.append(Business.model_validate(i))
-
- return response
+ return self.filter(user_id=user_id)
def get_uuids(self, user_id: PositiveInt | None) -> list[UUIDStr]:
"""
@@ -367,48 +371,24 @@ class BusinessManager(PostgresManagerWithRedis):
) -> Business | None:
assert UUID(hex=business_uuid).hex == business_uuid
- with self.pg_config.make_connection() as conn, conn.cursor() as c:
- c.execute(
- query=sql.SQL("""
- SELECT id, uuid, kind, name, tax_number
- FROM common_business
- WHERE uuid = %s
- LIMIT 1;
- """),
- params=(business_uuid,),
- )
-
- res = c.fetchall()
+ res = self.filter(business_uuid=business_uuid)
if len(res) == 0:
return None
assert len(res) == 1, "BusinessManager.get_by_uuid returned invalid results"
- data = res[0]
- # data["address"] = BusinessAddress.model_validate(data)
- # data["contact"] = BusinessContact.model_validate(data)
- return Business.model_validate(data)
+ return res[0]
def get_by_id(self, business_id: PositiveInt) -> Business | None:
assert isinstance(business_id, int)
- with self.pg_config.make_connection() as conn, conn.cursor() as c:
- c.execute(
- query=sql.SQL("""
- SELECT id, uuid, kind, name, tax_number
- FROM common_business
- WHERE id = %s
- LIMIT 1;
- """),
- params=(business_id,),
- )
-
- res = c.fetchall()
+ res = self.filter(business_id=business_id)
if len(res) == 0:
return None
- return Business.model_validate(res[0])
+ assert len(res) == 1, "BusinessManager.get_by_id returned invalid results"
+ return res[0]
def update_cached_fields(self, business: Business) -> None:
"""
diff --git a/generalresearch/models/gr/business.py b/generalresearch/models/gr/business.py
index d5a4c0a..3deff19 100644
--- a/generalresearch/models/gr/business.py
+++ b/generalresearch/models/gr/business.py
@@ -13,7 +13,14 @@ import pyarrow as pa
from dask.distributed import Client as DaskClient
from psycopg.cursor import Cursor
from psycopg.rows import dict_row
-from pydantic import BaseModel, ConfigDict, Field, PositiveInt, ValidationError
+from pydantic import (
+ BaseModel,
+ ConfigDict,
+ Field,
+ PositiveInt,
+ ValidationError,
+ computed_field,
+)
from pydantic.json_schema import SkipJsonSchema
from pydantic_extra_types.phone_numbers import PhoneNumber
@@ -208,17 +215,16 @@ class Business(BaseModel):
balance: BusinessBalances | None = Field(default=None, title="Business Balance")
user_wallet_balance: BusinessUserWalletBalances | None = Field(default=None)
- payouts_total_str: str | None = Field(default=None)
- payouts_total: USDCent | None = Field(default=None)
- payouts: list[BusinessPayoutEvent] | None = Field(
- default=None,
- title="Business Payouts",
- description=(
- "These are the ACH or Wire payments that were sent to the"
- "Business as a single amount, summed for all the Business"
- "child Products"
- ),
- )
+ # These should be queried for if we want them
+ # payouts: list[BusinessPayoutEvent] | None = Field(
+ # default=None,
+ # title="Business Payouts",
+ # description=(
+ # "These are the ACH or Wire payments that were sent to the"
+ # "Business as a single amount, summed for all the Business"
+ # "child Products"
+ # ),
+ # )
pop_financial: list[POPFinancial] | None = Field(default=None)
bp_accounts: list[LedgerAccount] | None = Field(default=None)
@@ -243,7 +249,7 @@ class Business(BaseModel):
f"Teams: {len(self.teams) if self.teams else 'Not Loaded'}\n"
f"Bank Accounts: {len(self.bank_accounts) if self.bank_accounts else 'Not Loaded'}\n"
f"–––\n"
- f"Payouts: {len(self.payouts) if self.payouts else 'Not Loaded'}\n"
+ # f"Payouts: {len(self.payouts) if self.payouts else 'Not Loaded'}\n"
f"Available Balance: {self.balance.available_balance if self.balance else 'Not Loaded'}\n"
)
@@ -302,12 +308,12 @@ class Business(BaseModel):
"""
:return: All the Products for this Business
"""
-
self.products = product_manager.filter_paginated(business_uuids=[self.uuid])
def prefetch_bank_accounts(
self, business_bank_account_manager: BusinessBankAccountManager
) -> None:
+ assert self.id is not None
self.bank_accounts = business_bank_account_manager.get_by_business_id(
business_id=self.id
)
@@ -510,22 +516,30 @@ class Business(BaseModel):
self.task_completes_7d = res["task_completes_7d"]
self.balance_net_7d = res["balance_net_7d"]
- def prebuild_payouts(
- self,
- bpem: BusinessPayoutEventManager,
- ) -> None:
- LOG.debug(f"Business.prebuild_payouts({self.uuid=})")
-
- self.payouts = bpem.get_business_payout_events_for_business(
- business_uuid=self.uuid,
- order_by=OrderBy.DESC,
- )
- self.prebuild_payouts_total()
-
- def prebuild_payouts_total(self):
- assert self.payouts is not None
- self.payouts_total = USDCent(sum([po.amount for po in self.payouts]))
- self.payouts_total_str = self.payouts_total.to_usd_str()
+ # def prebuild_payouts(
+ # self,
+ # bpem: BusinessPayoutEventManager,
+ # ) -> None:
+ # LOG.debug(f"Business.prebuild_payouts({self.uuid=})")
+ #
+ # self.payouts = bpem.get_business_payout_events_for_business(
+ # business_uuid=self.uuid,
+ # order_by=OrderBy.DESC,
+ # )
+ #
+ # @computed_field
+ # @property
+ # def payouts_total(self) -> USDCent | None:
+ # if self.payouts is None:
+ # return None
+ # return USDCent(sum(payout.amount for payout in self.payouts))
+ #
+ # @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_pop_financial(
self,
@@ -741,8 +755,8 @@ class Business(BaseModel):
pop_ledger=pop_ledger,
)
- self.prebuild_payouts(bpem=bpem)
self.prebuild_metrics(product_manager=product_manager)
+ # self.prebuild_payouts(bpem=bpem)
# self.prebuild_pop_financial(
# product_manager=product_manager,
# thl_lm=thl_lm,
diff --git a/pyproject.toml b/pyproject.toml
index 6b41fb1..d72ad8a 100644
--- a/pyproject.toml
+++ b/pyproject.toml
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
[project]
name = "generalresearch"
-version = "3.7.8"
+version = "3.7.9"
description = "Python Utilities for General Research"
readme = "README.md"
requires-python = ">=3.14"