Coverage for functions \ flipdare \ generated \ model \ payment \ stripe_account_model.py: 100%
0 statements
« prev ^ index » next coverage.py v7.13.0, created at 2026-05-08 12:22 +1000
« prev ^ index » next coverage.py v7.13.0, created at 2026-05-08 12:22 +1000
1#!/usr/bin/env python
2#
3# Copyright (c) 2026 Flipdare Pty Ltd. All rights reserved.
4#
5# This file is part of Flipdare's proprietary software and contains
6# confidential and copyrighted material. Unauthorised copying,
7# modification, distribution, or use of this file is strictly
8# prohibited without prior written permission from Flipdare Pty Ltd.
9#
10# This software includes third-party components licensed under MIT,
11# BSD, and Apache 2.0 licences. See THIRD_PARTY_NOTICES for details.
12#
13# NOTE: THIS FILE IS AUTO GENERATED. DO NOT EDIT.
14#
15# Generated by codegen_models.py
16#
17# Modify 'codegen_models.py'
18# and re-run the script above to update.
19#
20# pragma: no cover
21from __future__ import annotations
22from typing import Any, TypedDict, cast, Unpack, Literal
23from enum import StrEnum
24from pydantic import Field, ConfigDict, TypeAdapter
25from flipdare.generated.shared.stripe.stripe_account_type import StripeAccountType
26from flipdare.generated.shared.stripe.stripe_onboard_state import StripeOnboardState
27from flipdare.generated.model.payment.stripe_customer_model import StripeCustomerModel
28from flipdare.util.time_util import FirestoreTime, TimeUtil
31class StripeAccountKeys(StrEnum):
32 ACCOUNT_TYPE = "account_type"
33 ONBOARD_STATE = "onboard_state"
34 ACCOUNT_ID = "account_id"
35 ACCOUNT_LINK = "account_link"
36 ACCOUNT_LINK_EXPIRES = "account_link_expires"
37 STRIPE_DISABLED = "stripe_disabled"
38 STRIPE_DISABLED_REASON = "stripe_disabled_reason"
39 STRIPE_CLOSED = "stripe_closed"
40 HIGHEST_TRANSACTION_AMOUNT = "highest_transaction_amount"
41 TRANSACTION_VOLUME = "transaction_volume"
42 DISPUTE_FOR_CT = "dispute_for_ct"
43 REFUND_FOR_CT = "refund_for_ct"
44 PAYOUT_FOR_CT = "payout_for_ct"
45 DISPUTE_AGAINST_CT = "dispute_against_ct"
46 REFUND_AGAINST_CT = "refund_against_ct"
47 PAYOUT_AGAINST_CT = "payout_against_ct"
50class StripeAccountModel(StripeCustomerModel):
51 """Internal Stripe Account Settings Schema"""
53 model_config = ConfigDict(populate_by_name=True)
55 type: Literal["account"] = "account" # type: ignore
56 account_type: StripeAccountType
57 onboard_state: StripeOnboardState = Field(default=StripeOnboardState.NOT_STARTED)
58 account_id: str
59 account_link: str | None = None
60 account_link_expires: float | None = None
61 stripe_disabled: bool = Field(default=False)
62 stripe_disabled_reason: str | None = None
63 stripe_closed: bool = Field(default=False)
64 # Highest transaction amount in cents
65 highest_transaction_amount: int = Field(default=0)
66 # Total transaction volume in cents
67 transaction_volume: int = Field(default=0)
68 # Count of disputes for connected account
69 dispute_for_ct: int = Field(default=0)
70 # Count of refunds for connected account
71 refund_for_ct: int = Field(default=0)
72 # Count of payouts for connected account
73 payout_for_ct: int = Field(default=0)
74 # Count of disputes against connected account
75 dispute_against_ct: int = Field(default=0)
76 # Count of refunds against connected account
77 refund_against_ct: int = Field(default=0)
78 # Count of payouts against connected account
79 payout_against_ct: int = Field(default=0)
81 @classmethod
82 def validate_partial(cls, **data: Unpack[StripeAccountDict]) -> dict[str, Any]: # type: ignore
83 """
84 Uses Unpack to give you autocomplete and static warnings
85 if you pass an invalid key or type in your code.
87 Returns a dict with Firestore field names (aliases) for use with batch.update().
88 """
89 result: dict[str, Any] = {}
90 for k, v in data.items():
91 if k in cls.__pydantic_fields__:
92 field_info = cls.__pydantic_fields__[k]
93 validated_value = cast(
94 "Any",
95 TypeAdapter(field_info.annotation).validate_python(v),
96 )
97 # Use alias if defined, otherwise use field name
98 output_key = field_info.alias or k
99 result[output_key] = validated_value
100 return result
102 # ---- Convenience predicates -----------------------------------------
104 @property
105 def is_link_active(self) -> bool:
106 now = TimeUtil.get_current_utc_float_time()
107 expires_at = self.account_link_expires
108 if expires_at is None or expires_at < now:
109 return False
110 return True
112 @property
113 def account_age_days(self) -> int:
114 created = self.created_at
115 return FirestoreTime.age_in_days(created)
117 @property
118 def transaction_count(self) -> int:
119 return (
120 self.dispute_against_ct
121 + self.refund_against_ct
122 + self.payout_against_ct
123 + self.dispute_for_ct
124 + self.refund_for_ct
125 + self.payout_for_ct
126 )
128 @property
129 def disputed_rate(self) -> float:
130 volume = self.transaction_count
131 ct = self.dispute_for_ct + self.dispute_against_ct
132 return ct / volume if volume > 0 else 0.0
134 @property
135 def refund_rate(self) -> float:
136 volume = self.transaction_count
137 ct = self.refund_for_ct + self.refund_against_ct
138 return ct / volume if volume > 0 else 0.0
140 @property
141 def payout_rate(self) -> float:
142 volume = self.transaction_count
143 ct = self.payout_for_ct + self.payout_against_ct
144 return ct / volume if volume > 0 else 0.0
147STRIPEACCOUNT_FIELD_NAMES: list[str] = list(StripeAccountModel.model_fields.keys())
150class StripeAccountDict(TypedDict, total=False):
151 account_type: StripeAccountType
152 onboard_state: StripeOnboardState | None
153 account_id: str
154 account_link: str | None
155 account_link_expires: float | None
156 stripe_disabled: bool | None
157 stripe_disabled_reason: str | None
158 stripe_closed: bool | None
159 highest_transaction_amount: int | None
160 transaction_volume: int | None
161 dispute_for_ct: int | None
162 refund_for_ct: int | None
163 payout_for_ct: int | None
164 dispute_against_ct: int | None
165 refund_against_ct: int | None
166 payout_against_ct: int | None