Coverage for functions \ flipdare \ payments \ dto \ customer_dto.py: 76%

90 statements  

« prev     ^ index     » next       coverage.py v7.13.0, created at 2026-05-08 12:22 +1000

1#!/usr/bin/env python 

2# Copyright (c) 2026 Flipdare Pty Ltd. All rights reserved. 

3# 

4# This file is part of Flipdare's proprietary software and contains 

5# confidential and copyrighted material. Unauthorised copying, 

6# modification, distribution, or use of this file is strictly 

7# prohibited without prior written permission from Flipdare Pty Ltd. 

8# 

9# This software includes third-party components licensed under MIT, 

10# BSD, and Apache 2.0 licences. See THIRD_PARTY_NOTICES for details. 

11# 

12 

13from __future__ import annotations 

14from typing import Self 

15from flipdare.app_log import LOG 

16from flipdare.constants import IS_TRACE 

17from flipdare.generated.shared.stripe.stripe_country_code import StripeCountryCode 

18from flipdare.generated.shared.stripe.stripe_currency_code import StripeCurrencyCode 

19from flipdare.payments.dto.safe_stripe_object import SafeStripeObject 

20from stripe.v2.core import Account as StripeV2Account 

21 

22from flipdare.util.debug_util import stringify_debug 

23 

24 

25class CustomerDTO: 

26 

27 __slots__ = ( 

28 "_closed", 

29 "_country_code", 

30 "_created", 

31 "_currency_code", 

32 "_description", 

33 "_email", 

34 "_id", 

35 "_invoice_prefix", 

36 "_metadata", 

37 "_name", 

38 "_test_clock", 

39 ) 

40 

41 def __init__( 

42 self, 

43 customer_id: str, 

44 name: str, 

45 closed: bool, 

46 email: str | None = None, 

47 country_code: StripeCountryCode | None = None, 

48 currency_code: StripeCurrencyCode | None = None, 

49 invoice_prefix: str | None = None, 

50 description: str | None = None, 

51 metadata: dict[str, str] | None = None, 

52 created: int = 0, 

53 test_clock: str | None = None, 

54 ) -> None: 

55 self._name = name 

56 self._id = customer_id 

57 self._email = email 

58 self._country_code = country_code 

59 self._currency_code = currency_code 

60 self._invoice_prefix = invoice_prefix 

61 self._closed = closed 

62 self._description = description 

63 self._metadata = metadata 

64 self._created = created 

65 self._test_clock = test_clock 

66 

67 @classmethod 

68 def from_stripe_customer(cls, cust_account: StripeV2Account) -> Self: 

69 

70 cust_id = cust_account.id 

71 

72 safe = SafeStripeObject(cust_account) 

73 name = safe.display_name.unwrap() 

74 email = safe.contact_email.unwrap() 

75 closed = safe.closed.unwrap() 

76 created = safe.created.unwrap() 

77 metadata = safe.metadata.unwrap() 

78 

79 description = safe.defaults.profile.product_description.unwrap() 

80 invoice_prefix = safe.billing.invoice.prefix.unwrap() 

81 test_clock = safe.configuration.test_clock.unwrap() 

82 

83 currency = safe.defaults.currency.unwrap() 

84 currency_code: StripeCurrencyCode | None = None 

85 

86 if IS_TRACE: 

87 LOG().trace( 

88 f"Processing Stripe Customer object with details:\n{stringify_debug(cust_account)}" 

89 ) 

90 

91 if currency is not None: 

92 try: 

93 currency_code = StripeCurrencyCode.from_stripe(currency) 

94 except ValueError: 

95 LOG().warning( 

96 f"Customer {cust_account.id} has unrecognised currency code: {currency}" 

97 ) 

98 currency_code = None 

99 

100 country = safe.identity.country.unwrap() 

101 country_code: StripeCountryCode | None = None 

102 if country is not None: 

103 try: 

104 country_code = StripeCountryCode(country) 

105 except ValueError: 

106 LOG().warning(f"Customer {cust_id} has unrecognised country code: {country}") 

107 country_code = None 

108 

109 return cls( 

110 customer_id=cust_id, 

111 name=name, 

112 email=email, 

113 closed=closed, 

114 country_code=country_code, 

115 currency_code=currency_code, 

116 description=description, 

117 invoice_prefix=invoice_prefix, 

118 created=created, 

119 test_clock=test_clock, 

120 metadata=metadata, 

121 ) 

122 

123 @property 

124 def id(self) -> str: 

125 return self._id 

126 

127 @property 

128 def email(self) -> str | None: 

129 return self._email 

130 

131 @property 

132 def name(self) -> str | None: 

133 return self._name 

134 

135 @property 

136 def country_code(self) -> StripeCountryCode | None: 

137 return self._country_code 

138 

139 @property 

140 def currency_code(self) -> StripeCurrencyCode | None: 

141 return self._currency_code 

142 

143 @property 

144 def closed(self) -> bool: 

145 return self._closed 

146 

147 @property 

148 def description(self) -> str | None: 

149 return self._description 

150 

151 @property 

152 def invoice_prefix(self) -> str | None: 

153 return self._invoice_prefix 

154 

155 @property 

156 def created(self) -> int: 

157 return self._created 

158 

159 @property 

160 def metadata(self) -> dict[str, str] | None: 

161 return self._metadata 

162 

163 @property 

164 def test_clock(self) -> str | None: 

165 return self._test_clock 

166 

167 def debug_str(self) -> str: 

168 msg = f""" 

169 CustomerDTO: 

170 id = {self._id} 

171 name = {self._name} 

172 email = {self._email} 

173 country_code = {self._country_code} 

174 currency_code = {self._currency_code} 

175 closed = {self._closed} 

176 description = {self._description} 

177 metadata = {self._metadata} 

178 created = {self._created} 

179 test_clock = {self._test_clock} 

180 """ 

181 return msg.strip()