diff options
| -rw-r--r-- | generalresearch/models/gr/business.py | 56 | ||||
| -rw-r--r-- | generalresearch/models/thl/finance.py | 15 | ||||
| -rw-r--r-- | pyproject.toml | 2 | ||||
| -rw-r--r-- | tests/models/thl/test_product.py | 2 |
4 files changed, 70 insertions, 5 deletions
diff --git a/generalresearch/models/gr/business.py b/generalresearch/models/gr/business.py index 24894cf..d5a4c0a 100644 --- a/generalresearch/models/gr/business.py +++ b/generalresearch/models/gr/business.py @@ -30,7 +30,11 @@ from generalresearch.models.custom_types import ( ) from generalresearch.models.gr.definitions import BusinessType, TransferMethod from generalresearch.models.gr.team import Team -from generalresearch.models.thl.finance import BusinessBalances, POPFinancial +from generalresearch.models.thl.finance import ( + BusinessBalances, + BusinessUserWalletBalances, + POPFinancial, +) from generalresearch.models.thl.ledger import LedgerAccount, OrderBy from generalresearch.models.thl.payout import BusinessPayoutEvent @@ -202,6 +206,7 @@ class Business(BaseModel): # Initialization is deferred until unless it's called # (see .prebuild_***()) 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) @@ -352,6 +357,45 @@ class Business(BaseModel): # --- Prebuild --- + def prebuild_user_wallet_balance( + self, + client: DaskClient, + pop_ledger: PopLedgerMerge | None = None, + ): + from generalresearch.incite.schemas.mergers.pop_ledger import ( + numerical_col_names, + ) + + assert self.products is not None, "prefetch products" + product_uuids = self.product_uuids + assert product_uuids is not None, "prefetch products" + if not any(p.user_wallet_enabled for p in self.products): + return + + ddf = pop_ledger.ddf( + force_rr_latest=False, + include_partial=True, + columns=numerical_col_names + + ["time_idx", "account_id", "product_id", "product_user_id"], + filters=[("product_id", "in", list(product_uuids))], + ) + df: pd.DataFrame = client.compute(collections=ddf, sync=True) + for product in self.products: + if product.user_wallet_enabled and product.user_wallet_balance is None: + product.prebuild_user_wallet_balances(df) + product_user_wallet_balances = [ + p.user_wallet_balance + for p in self.products + if p.user_wallet_balance is not None + ] + if product_user_wallet_balances: + self.user_wallet_balance = ( + BusinessUserWalletBalances.from_product_user_wallet_balances( + business_id=self.uuid, + product_user_wallet_balances=product_user_wallet_balances, + ) + ) + def prebuild_balance( self, product_manager: ProductManager, @@ -658,7 +702,6 @@ class Business(BaseModel): pg_config: PostgresConfig, product_manager: ProductManager, business_bank_account_manager: BusinessBankAccountManager, - thl_web_rr: PostgresConfig, redis_config: RedisConfig, client: DaskClient, ds: GRLDatasets, @@ -673,6 +716,10 @@ class Business(BaseModel): LOG.debug(f"Business.set_cache({self.uuid=})") # ex_secs = 60 * 60 * 24 * 3 # 3 days + if pop_ledger is None: + from generalresearch.incite.defaults import pop_ledger as plm + + pop_ledger = plm(ds=ds) self.prefetch_addresses(pg_config=pg_config) self.prefetch_teams(pg_config=pg_config) @@ -689,6 +736,11 @@ class Business(BaseModel): client=client, pop_ledger=pop_ledger, ) + self.prebuild_user_wallet_balance( + client=client, + pop_ledger=pop_ledger, + ) + self.prebuild_payouts(bpem=bpem) self.prebuild_metrics(product_manager=product_manager) # self.prebuild_pop_financial( diff --git a/generalresearch/models/thl/finance.py b/generalresearch/models/thl/finance.py index 7c488e6..49672f1 100644 --- a/generalresearch/models/thl/finance.py +++ b/generalresearch/models/thl/finance.py @@ -1721,8 +1721,9 @@ class BusinessUserWalletBalances(UserWalletBalanceSummary): @classmethod def from_product_user_wallet_balances( cls, + business_id: str, product_user_wallet_balances: list[ProductUserWalletBalances], - ): + ) -> BusinessUserWalletBalances: sum_fields = [ k for k, v in UserWalletBalanceSummary.model_fields.items() @@ -1747,7 +1748,17 @@ class BusinessUserWalletBalances(UserWalletBalanceSummary): ], default=None, ) - return cls.model_validate(d) + d["wallet_balance_buckets"] = [ + UserWalletBalanceHistogramBucket( + upper_bound=upper_bound, + cumulative_count=sum( + product.wallet_balance_buckets[index].cumulative_count + for product in product_user_wallet_balances + ), + ) + for index, upper_bound in enumerate(USER_WALLET_BALANCE_BUCKETS) + ] + return cls.model_validate(d | {"business_id": business_id}) class BusinessBalances(BaseModel): diff --git a/pyproject.toml b/pyproject.toml index 5839d26..bf52137 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta" [project] name = "generalresearch" -version = "3.7.6" +version = "3.7.7" description = "Python Utilities for General Research" readme = "README.md" requires-python = ">=3.14" diff --git a/tests/models/thl/test_product.py b/tests/models/thl/test_product.py index f8f3da3..d5e51f0 100644 --- a/tests/models/thl/test_product.py +++ b/tests/models/thl/test_product.py @@ -952,6 +952,8 @@ class TestProductFinancials: p1.prebuild_balance(thl_lm=thl_ledger_manager, pop_ledger_df=df) assert p1.balance.payout == 95 assert p1.balance.commission == 5 + # This will equal 0 b/c the wall events are in 2018 + assert p1.balance_net_7d == 0 p2.prebuild_balance(thl_lm=thl_ledger_manager, pop_ledger_df=df) assert p2.balance.payout == 57 |
