ynab-cli 0.3.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (206) hide show
  1. ynab_cli/__init__.py +0 -0
  2. ynab_cli/adapters/__init__.py +0 -0
  3. ynab_cli/adapters/rich/__init__.py +0 -0
  4. ynab_cli/adapters/rich/io.py +38 -0
  5. ynab_cli/adapters/textual/__init__.py +0 -0
  6. ynab_cli/adapters/textual/io.py +62 -0
  7. ynab_cli/adapters/ynab/__init__.py +8 -0
  8. ynab_cli/adapters/ynab/api/__init__.py +1 -0
  9. ynab_cli/adapters/ynab/api/accounts/__init__.py +1 -0
  10. ynab_cli/adapters/ynab/api/accounts/create_account.py +186 -0
  11. ynab_cli/adapters/ynab/api/accounts/get_account_by_id.py +177 -0
  12. ynab_cli/adapters/ynab/api/accounts/get_accounts.py +184 -0
  13. ynab_cli/adapters/ynab/api/budgets/__init__.py +1 -0
  14. ynab_cli/adapters/ynab/api/budgets/get_budget_by_id.py +188 -0
  15. ynab_cli/adapters/ynab/api/budgets/get_budget_settings_by_id.py +163 -0
  16. ynab_cli/adapters/ynab/api/budgets/get_budgets.py +171 -0
  17. ynab_cli/adapters/ynab/api/categories/__init__.py +1 -0
  18. ynab_cli/adapters/ynab/api/categories/get_categories.py +188 -0
  19. ynab_cli/adapters/ynab/api/categories/get_category_by_id.py +180 -0
  20. ynab_cli/adapters/ynab/api/categories/get_month_category_by_id.py +194 -0
  21. ynab_cli/adapters/ynab/api/categories/update_category.py +199 -0
  22. ynab_cli/adapters/ynab/api/categories/update_month_category.py +213 -0
  23. ynab_cli/adapters/ynab/api/months/__init__.py +1 -0
  24. ynab_cli/adapters/ynab/api/months/get_budget_month.py +177 -0
  25. ynab_cli/adapters/ynab/api/months/get_budget_months.py +184 -0
  26. ynab_cli/adapters/ynab/api/payee_locations/__init__.py +1 -0
  27. ynab_cli/adapters/ynab/api/payee_locations/get_payee_location_by_id.py +176 -0
  28. ynab_cli/adapters/ynab/api/payee_locations/get_payee_locations.py +163 -0
  29. ynab_cli/adapters/ynab/api/payee_locations/get_payee_locations_by_payee.py +176 -0
  30. ynab_cli/adapters/ynab/api/payees/__init__.py +1 -0
  31. ynab_cli/adapters/ynab/api/payees/get_payee_by_id.py +176 -0
  32. ynab_cli/adapters/ynab/api/payees/get_payees.py +184 -0
  33. ynab_cli/adapters/ynab/api/payees/update_payee.py +199 -0
  34. ynab_cli/adapters/ynab/api/scheduled_transactions/__init__.py +1 -0
  35. ynab_cli/adapters/ynab/api/scheduled_transactions/create_scheduled_transaction.py +186 -0
  36. ynab_cli/adapters/ynab/api/scheduled_transactions/delete_scheduled_transaction.py +176 -0
  37. ynab_cli/adapters/ynab/api/scheduled_transactions/get_scheduled_transaction_by_id.py +176 -0
  38. ynab_cli/adapters/ynab/api/scheduled_transactions/get_scheduled_transactions.py +184 -0
  39. ynab_cli/adapters/ynab/api/scheduled_transactions/update_scheduled_transaction.py +199 -0
  40. ynab_cli/adapters/ynab/api/transactions/__init__.py +1 -0
  41. ynab_cli/adapters/ynab/api/transactions/create_transaction.py +202 -0
  42. ynab_cli/adapters/ynab/api/transactions/delete_transaction.py +176 -0
  43. ynab_cli/adapters/ynab/api/transactions/get_transaction_by_id.py +176 -0
  44. ynab_cli/adapters/ynab/api/transactions/get_transactions.py +227 -0
  45. ynab_cli/adapters/ynab/api/transactions/get_transactions_by_account.py +236 -0
  46. ynab_cli/adapters/ynab/api/transactions/get_transactions_by_category.py +236 -0
  47. ynab_cli/adapters/ynab/api/transactions/get_transactions_by_month.py +236 -0
  48. ynab_cli/adapters/ynab/api/transactions/get_transactions_by_payee.py +236 -0
  49. ynab_cli/adapters/ynab/api/transactions/import_transactions.py +183 -0
  50. ynab_cli/adapters/ynab/api/transactions/update_transaction.py +199 -0
  51. ynab_cli/adapters/ynab/api/transactions/update_transactions.py +177 -0
  52. ynab_cli/adapters/ynab/api/user/__init__.py +1 -0
  53. ynab_cli/adapters/ynab/api/user/get_user.py +130 -0
  54. ynab_cli/adapters/ynab/client.py +268 -0
  55. ynab_cli/adapters/ynab/errors.py +16 -0
  56. ynab_cli/adapters/ynab/models/__init__.py +229 -0
  57. ynab_cli/adapters/ynab/models/account.py +345 -0
  58. ynab_cli/adapters/ynab/models/account_response.py +65 -0
  59. ynab_cli/adapters/ynab/models/account_response_data.py +65 -0
  60. ynab_cli/adapters/ynab/models/account_type.py +23 -0
  61. ynab_cli/adapters/ynab/models/accounts_response.py +65 -0
  62. ynab_cli/adapters/ynab/models/accounts_response_data.py +81 -0
  63. ynab_cli/adapters/ynab/models/budget_detail.py +405 -0
  64. ynab_cli/adapters/ynab/models/budget_detail_response.py +65 -0
  65. ynab_cli/adapters/ynab/models/budget_detail_response_data.py +73 -0
  66. ynab_cli/adapters/ynab/models/budget_settings.py +115 -0
  67. ynab_cli/adapters/ynab/models/budget_settings_response.py +65 -0
  68. ynab_cli/adapters/ynab/models/budget_settings_response_data.py +65 -0
  69. ynab_cli/adapters/ynab/models/budget_summary.py +216 -0
  70. ynab_cli/adapters/ynab/models/budget_summary_response.py +65 -0
  71. ynab_cli/adapters/ynab/models/budget_summary_response_data.py +91 -0
  72. ynab_cli/adapters/ynab/models/bulk_response.py +65 -0
  73. ynab_cli/adapters/ynab/models/bulk_response_data.py +65 -0
  74. ynab_cli/adapters/ynab/models/bulk_response_data_bulk.py +68 -0
  75. ynab_cli/adapters/ynab/models/bulk_transactions.py +75 -0
  76. ynab_cli/adapters/ynab/models/categories_response.py +65 -0
  77. ynab_cli/adapters/ynab/models/categories_response_data.py +81 -0
  78. ynab_cli/adapters/ynab/models/category.py +519 -0
  79. ynab_cli/adapters/ynab/models/category_goal_type_type_1.py +15 -0
  80. ynab_cli/adapters/ynab/models/category_goal_type_type_2_type_1.py +15 -0
  81. ynab_cli/adapters/ynab/models/category_goal_type_type_3_type_1.py +15 -0
  82. ynab_cli/adapters/ynab/models/category_group.py +85 -0
  83. ynab_cli/adapters/ynab/models/category_group_with_categories.py +108 -0
  84. ynab_cli/adapters/ynab/models/category_response.py +65 -0
  85. ynab_cli/adapters/ynab/models/category_response_data.py +65 -0
  86. ynab_cli/adapters/ynab/models/currency_format_type_0.py +117 -0
  87. ynab_cli/adapters/ynab/models/date_format_type_0.py +61 -0
  88. ynab_cli/adapters/ynab/models/error_detail.py +75 -0
  89. ynab_cli/adapters/ynab/models/error_response.py +65 -0
  90. ynab_cli/adapters/ynab/models/existing_transaction.py +322 -0
  91. ynab_cli/adapters/ynab/models/get_transactions_by_account_type.py +12 -0
  92. ynab_cli/adapters/ynab/models/get_transactions_by_category_type.py +12 -0
  93. ynab_cli/adapters/ynab/models/get_transactions_by_month_type.py +12 -0
  94. ynab_cli/adapters/ynab/models/get_transactions_by_payee_type.py +12 -0
  95. ynab_cli/adapters/ynab/models/get_transactions_type.py +12 -0
  96. ynab_cli/adapters/ynab/models/hybrid_transaction.py +567 -0
  97. ynab_cli/adapters/ynab/models/hybrid_transaction_type.py +12 -0
  98. ynab_cli/adapters/ynab/models/hybrid_transactions_response.py +65 -0
  99. ynab_cli/adapters/ynab/models/hybrid_transactions_response_data.py +84 -0
  100. ynab_cli/adapters/ynab/models/loan_account_periodic_value_type_0.py +44 -0
  101. ynab_cli/adapters/ynab/models/month_detail.py +168 -0
  102. ynab_cli/adapters/ynab/models/month_detail_response.py +65 -0
  103. ynab_cli/adapters/ynab/models/month_detail_response_data.py +65 -0
  104. ynab_cli/adapters/ynab/models/month_summaries_response.py +65 -0
  105. ynab_cli/adapters/ynab/models/month_summaries_response_data.py +81 -0
  106. ynab_cli/adapters/ynab/models/month_summary.py +145 -0
  107. ynab_cli/adapters/ynab/models/new_transaction.py +352 -0
  108. ynab_cli/adapters/ynab/models/patch_category_wrapper.py +65 -0
  109. ynab_cli/adapters/ynab/models/patch_month_category_wrapper.py +65 -0
  110. ynab_cli/adapters/ynab/models/patch_payee_wrapper.py +65 -0
  111. ynab_cli/adapters/ynab/models/patch_transactions_wrapper.py +73 -0
  112. ynab_cli/adapters/ynab/models/payee.py +100 -0
  113. ynab_cli/adapters/ynab/models/payee_location.py +93 -0
  114. ynab_cli/adapters/ynab/models/payee_location_response.py +65 -0
  115. ynab_cli/adapters/ynab/models/payee_location_response_data.py +65 -0
  116. ynab_cli/adapters/ynab/models/payee_locations_response.py +65 -0
  117. ynab_cli/adapters/ynab/models/payee_locations_response_data.py +73 -0
  118. ynab_cli/adapters/ynab/models/payee_response.py +65 -0
  119. ynab_cli/adapters/ynab/models/payee_response_data.py +65 -0
  120. ynab_cli/adapters/ynab/models/payees_response.py +65 -0
  121. ynab_cli/adapters/ynab/models/payees_response_data.py +81 -0
  122. ynab_cli/adapters/ynab/models/post_account_wrapper.py +65 -0
  123. ynab_cli/adapters/ynab/models/post_scheduled_transaction_wrapper.py +65 -0
  124. ynab_cli/adapters/ynab/models/post_transactions_wrapper.py +91 -0
  125. ynab_cli/adapters/ynab/models/put_scheduled_transaction_wrapper.py +65 -0
  126. ynab_cli/adapters/ynab/models/put_transaction_wrapper.py +65 -0
  127. ynab_cli/adapters/ynab/models/save_account.py +77 -0
  128. ynab_cli/adapters/ynab/models/save_category.py +129 -0
  129. ynab_cli/adapters/ynab/models/save_category_response.py +65 -0
  130. ynab_cli/adapters/ynab/models/save_category_response_data.py +73 -0
  131. ynab_cli/adapters/ynab/models/save_month_category.py +59 -0
  132. ynab_cli/adapters/ynab/models/save_payee.py +59 -0
  133. ynab_cli/adapters/ynab/models/save_payee_response.py +65 -0
  134. ynab_cli/adapters/ynab/models/save_payee_response_data.py +73 -0
  135. ynab_cli/adapters/ynab/models/save_scheduled_transaction.py +269 -0
  136. ynab_cli/adapters/ynab/models/save_sub_transaction.py +166 -0
  137. ynab_cli/adapters/ynab/models/save_transaction_with_id_or_import_id.py +366 -0
  138. ynab_cli/adapters/ynab/models/save_transaction_with_optional_fields.py +322 -0
  139. ynab_cli/adapters/ynab/models/save_transactions_response.py +65 -0
  140. ynab_cli/adapters/ynab/models/save_transactions_response_data.py +123 -0
  141. ynab_cli/adapters/ynab/models/scheduled_sub_transaction.py +238 -0
  142. ynab_cli/adapters/ynab/models/scheduled_transaction_detail.py +381 -0
  143. ynab_cli/adapters/ynab/models/scheduled_transaction_frequency.py +23 -0
  144. ynab_cli/adapters/ynab/models/scheduled_transaction_response.py +65 -0
  145. ynab_cli/adapters/ynab/models/scheduled_transaction_response_data.py +65 -0
  146. ynab_cli/adapters/ynab/models/scheduled_transaction_summary.py +310 -0
  147. ynab_cli/adapters/ynab/models/scheduled_transaction_summary_frequency.py +23 -0
  148. ynab_cli/adapters/ynab/models/scheduled_transactions_response.py +65 -0
  149. ynab_cli/adapters/ynab/models/scheduled_transactions_response_data.py +81 -0
  150. ynab_cli/adapters/ynab/models/sub_transaction.py +259 -0
  151. ynab_cli/adapters/ynab/models/transaction_cleared_status.py +13 -0
  152. ynab_cli/adapters/ynab/models/transaction_detail.py +570 -0
  153. ynab_cli/adapters/ynab/models/transaction_flag_color_type_1.py +16 -0
  154. ynab_cli/adapters/ynab/models/transaction_flag_color_type_2_type_1.py +16 -0
  155. ynab_cli/adapters/ynab/models/transaction_flag_color_type_3_type_1.py +16 -0
  156. ynab_cli/adapters/ynab/models/transaction_response.py +65 -0
  157. ynab_cli/adapters/ynab/models/transaction_response_data.py +65 -0
  158. ynab_cli/adapters/ynab/models/transaction_summary.py +499 -0
  159. ynab_cli/adapters/ynab/models/transaction_summary_debt_transaction_type_type_1.py +18 -0
  160. ynab_cli/adapters/ynab/models/transaction_summary_debt_transaction_type_type_2_type_1.py +18 -0
  161. ynab_cli/adapters/ynab/models/transaction_summary_debt_transaction_type_type_3_type_1.py +18 -0
  162. ynab_cli/adapters/ynab/models/transactions_import_response.py +65 -0
  163. ynab_cli/adapters/ynab/models/transactions_import_response_data.py +59 -0
  164. ynab_cli/adapters/ynab/models/transactions_response.py +65 -0
  165. ynab_cli/adapters/ynab/models/transactions_response_data.py +81 -0
  166. ynab_cli/adapters/ynab/models/user.py +60 -0
  167. ynab_cli/adapters/ynab/models/user_response.py +65 -0
  168. ynab_cli/adapters/ynab/models/user_response_data.py +65 -0
  169. ynab_cli/adapters/ynab/types.py +46 -0
  170. ynab_cli/adapters/ynab/util.py +78 -0
  171. ynab_cli/domain/__init__.py +0 -0
  172. ynab_cli/domain/constants.py +3 -0
  173. ynab_cli/domain/models/__init__.py +0 -0
  174. ynab_cli/domain/models/rules.py +37 -0
  175. ynab_cli/domain/ports/__init__.py +5 -0
  176. ynab_cli/domain/ports/io.py +63 -0
  177. ynab_cli/domain/settings.py +16 -0
  178. ynab_cli/domain/use_cases/__init__.py +0 -0
  179. ynab_cli/domain/use_cases/categories.py +105 -0
  180. ynab_cli/domain/use_cases/payees.py +232 -0
  181. ynab_cli/domain/use_cases/transactions.py +93 -0
  182. ynab_cli/host/__init__.py +14 -0
  183. ynab_cli/host/cli.py +37 -0
  184. ynab_cli/host/click/__init__.py +0 -0
  185. ynab_cli/host/click/cli.py +44 -0
  186. ynab_cli/host/click/commands/__init__.py +0 -0
  187. ynab_cli/host/click/commands/categories.py +92 -0
  188. ynab_cli/host/click/commands/payees.py +157 -0
  189. ynab_cli/host/click/commands/rich/__init__.py +0 -0
  190. ynab_cli/host/click/commands/rich/progress_table.py +37 -0
  191. ynab_cli/host/click/commands/transactions.py +76 -0
  192. ynab_cli/host/constants.py +3 -0
  193. ynab_cli/host/textual/__init__.py +0 -0
  194. ynab_cli/host/textual/app.py +98 -0
  195. ynab_cli/host/textual/app.tcss +47 -0
  196. ynab_cli/host/textual/cli.py +42 -0
  197. ynab_cli/host/textual/widgets/__init__.py +58 -0
  198. ynab_cli/host/textual/widgets/categories.py +90 -0
  199. ynab_cli/host/textual/widgets/payees.py +154 -0
  200. ynab_cli/host/textual/widgets/transactions.py +89 -0
  201. ynab_cli/py.typed +0 -0
  202. ynab_cli-0.3.0.dist-info/METADATA +102 -0
  203. ynab_cli-0.3.0.dist-info/RECORD +206 -0
  204. ynab_cli-0.3.0.dist-info/WHEEL +4 -0
  205. ynab_cli-0.3.0.dist-info/entry_points.txt +2 -0
  206. ynab_cli-0.3.0.dist-info/licenses/LICENSE.md +21 -0
@@ -0,0 +1,519 @@
1
+ import datetime
2
+ from collections.abc import Mapping
3
+ from typing import Any, TypeVar, cast
4
+ from uuid import UUID
5
+
6
+ from attrs import define as _attrs_define
7
+ from attrs import field as _attrs_field
8
+ from dateutil.parser import isoparse
9
+
10
+ from ynab_cli.adapters.ynab.models.category_goal_type_type_1 import CategoryGoalTypeType1
11
+ from ynab_cli.adapters.ynab.models.category_goal_type_type_2_type_1 import CategoryGoalTypeType2Type1
12
+ from ynab_cli.adapters.ynab.models.category_goal_type_type_3_type_1 import CategoryGoalTypeType3Type1
13
+ from ynab_cli.adapters.ynab.types import UNSET, Unset
14
+
15
+ T = TypeVar("T", bound="Category")
16
+
17
+
18
+ @_attrs_define
19
+ class Category:
20
+ """
21
+ Attributes:
22
+ id (UUID):
23
+ category_group_id (UUID):
24
+ name (str):
25
+ hidden (bool): Whether or not the category is hidden
26
+ budgeted (int): Budgeted amount in milliunits format
27
+ activity (int): Activity amount in milliunits format
28
+ balance (int): Balance in milliunits format
29
+ deleted (bool): Whether or not the category has been deleted. Deleted categories will only be included in delta
30
+ requests.
31
+ category_group_name (Union[Unset, str]):
32
+ original_category_group_id (Union[None, UUID, Unset]): DEPRECATED: No longer used. Value will always be null.
33
+ note (Union[None, Unset, str]):
34
+ goal_type (Union[CategoryGoalTypeType1, CategoryGoalTypeType2Type1, CategoryGoalTypeType3Type1, None, Unset]):
35
+ The type of goal, if the category has a goal (TB='Target Category Balance', TBD='Target Category Balance by
36
+ Date', MF='Monthly Funding', NEED='Plan Your Spending')
37
+ goal_needs_whole_amount (Union[None, Unset, bool]): Indicates the monthly rollover behavior for "NEED"-type
38
+ goals. When "true", the goal will always ask for the target amount in the new month ("Set Aside"). When "false",
39
+ previous month category funding is used ("Refill"). For other goal types, this field will be null.
40
+ goal_day (Union[None, Unset, int]): A day offset modifier for the goal's due date. When goal_cadence is 2
41
+ (Weekly), this value specifies which day of the week the goal is due (0 = Sunday, 6 = Saturday). Otherwise, this
42
+ value specifies which day of the month the goal is due (1 = 1st, 31 = 31st, null = Last day of Month).
43
+ goal_cadence (Union[None, Unset, int]): The goal cadence. Value in range 0-14. There are two subsets of these
44
+ values which behave differently. For values 0, 1, 2, and 13, the goal's due date repeats every goal_cadence *
45
+ goal_cadence_frequency, where 0 = None, 1 = Monthly, 2 = Weekly, and 13 = Yearly. For example, goal_cadence 1
46
+ with goal_cadence_frequency 2 means the goal is due every other month. For values 3-12 and 14,
47
+ goal_cadence_frequency is ignored and the goal's due date repeats every goal_cadence, where 3 = Every 2 Months,
48
+ 4 = Every 3 Months, ..., 12 = Every 11 Months, and 14 = Every 2 Years.
49
+ goal_cadence_frequency (Union[None, Unset, int]): The goal cadence frequency. When goal_cadence is 0, 1, 2, or
50
+ 13, a goal's due date repeats every goal_cadence * goal_cadence_frequency. For example, goal_cadence 1 with
51
+ goal_cadence_frequency 2 means the goal is due every other month. When goal_cadence is 3-12 or 14,
52
+ goal_cadence_frequency is ignored.
53
+ goal_creation_month (Union[None, Unset, datetime.date]): The month a goal was created
54
+ goal_target (Union[None, Unset, int]): The goal target amount in milliunits
55
+ goal_target_month (Union[None, Unset, datetime.date]): The original target month for the goal to be completed.
56
+ Only some goal types specify this date.
57
+ goal_percentage_complete (Union[None, Unset, int]): The percentage completion of the goal
58
+ goal_months_to_budget (Union[None, Unset, int]): The number of months, including the current month, left in the
59
+ current goal period.
60
+ goal_under_funded (Union[None, Unset, int]): The amount of funding still needed in the current month to stay on
61
+ track towards completing the goal within the current goal period. This amount will generally correspond to the
62
+ 'Underfunded' amount in the web and mobile clients except when viewing a category with a Needed for Spending
63
+ Goal in a future month. The web and mobile clients will ignore any funding from a prior goal period when
64
+ viewing category with a Needed for Spending Goal in a future month.
65
+ goal_overall_funded (Union[None, Unset, int]): The total amount funded towards the goal within the current goal
66
+ period.
67
+ goal_overall_left (Union[None, Unset, int]): The amount of funding still needed to complete the goal within the
68
+ current goal period.
69
+ """
70
+
71
+ id: UUID
72
+ category_group_id: UUID
73
+ name: str
74
+ hidden: bool
75
+ budgeted: int
76
+ activity: int
77
+ balance: int
78
+ deleted: bool
79
+ category_group_name: Unset | str = UNSET
80
+ original_category_group_id: None | UUID | Unset = UNSET
81
+ note: None | Unset | str = UNSET
82
+ goal_type: CategoryGoalTypeType1 | CategoryGoalTypeType2Type1 | CategoryGoalTypeType3Type1 | None | Unset = UNSET
83
+ goal_needs_whole_amount: None | Unset | bool = UNSET
84
+ goal_day: None | Unset | int = UNSET
85
+ goal_cadence: None | Unset | int = UNSET
86
+ goal_cadence_frequency: None | Unset | int = UNSET
87
+ goal_creation_month: None | Unset | datetime.date = UNSET
88
+ goal_target: None | Unset | int = UNSET
89
+ goal_target_month: None | Unset | datetime.date = UNSET
90
+ goal_percentage_complete: None | Unset | int = UNSET
91
+ goal_months_to_budget: None | Unset | int = UNSET
92
+ goal_under_funded: None | Unset | int = UNSET
93
+ goal_overall_funded: None | Unset | int = UNSET
94
+ goal_overall_left: None | Unset | int = UNSET
95
+ additional_properties: dict[str, Any] = _attrs_field(init=False, factory=dict)
96
+
97
+ def to_dict(self) -> dict[str, Any]:
98
+ id = str(self.id)
99
+
100
+ category_group_id = str(self.category_group_id)
101
+
102
+ name = self.name
103
+
104
+ hidden = self.hidden
105
+
106
+ budgeted = self.budgeted
107
+
108
+ activity = self.activity
109
+
110
+ balance = self.balance
111
+
112
+ deleted = self.deleted
113
+
114
+ category_group_name = self.category_group_name
115
+
116
+ original_category_group_id: None | Unset | str
117
+ if isinstance(self.original_category_group_id, Unset):
118
+ original_category_group_id = UNSET
119
+ elif isinstance(self.original_category_group_id, UUID):
120
+ original_category_group_id = str(self.original_category_group_id)
121
+ else:
122
+ original_category_group_id = self.original_category_group_id
123
+
124
+ note: None | Unset | str
125
+ if isinstance(self.note, Unset):
126
+ note = UNSET
127
+ else:
128
+ note = self.note
129
+
130
+ goal_type: None | Unset | str
131
+ if isinstance(self.goal_type, Unset):
132
+ goal_type = UNSET
133
+ elif isinstance(self.goal_type, CategoryGoalTypeType1):
134
+ goal_type = self.goal_type.value
135
+ elif isinstance(self.goal_type, CategoryGoalTypeType2Type1):
136
+ goal_type = self.goal_type.value
137
+ elif isinstance(self.goal_type, CategoryGoalTypeType3Type1):
138
+ goal_type = self.goal_type.value
139
+ else:
140
+ goal_type = self.goal_type
141
+
142
+ goal_needs_whole_amount: None | Unset | bool
143
+ if isinstance(self.goal_needs_whole_amount, Unset):
144
+ goal_needs_whole_amount = UNSET
145
+ else:
146
+ goal_needs_whole_amount = self.goal_needs_whole_amount
147
+
148
+ goal_day: None | Unset | int
149
+ if isinstance(self.goal_day, Unset):
150
+ goal_day = UNSET
151
+ else:
152
+ goal_day = self.goal_day
153
+
154
+ goal_cadence: None | Unset | int
155
+ if isinstance(self.goal_cadence, Unset):
156
+ goal_cadence = UNSET
157
+ else:
158
+ goal_cadence = self.goal_cadence
159
+
160
+ goal_cadence_frequency: None | Unset | int
161
+ if isinstance(self.goal_cadence_frequency, Unset):
162
+ goal_cadence_frequency = UNSET
163
+ else:
164
+ goal_cadence_frequency = self.goal_cadence_frequency
165
+
166
+ goal_creation_month: None | Unset | str
167
+ if isinstance(self.goal_creation_month, Unset):
168
+ goal_creation_month = UNSET
169
+ elif isinstance(self.goal_creation_month, datetime.date):
170
+ goal_creation_month = self.goal_creation_month.isoformat()
171
+ else:
172
+ goal_creation_month = self.goal_creation_month
173
+
174
+ goal_target: None | Unset | int
175
+ if isinstance(self.goal_target, Unset):
176
+ goal_target = UNSET
177
+ else:
178
+ goal_target = self.goal_target
179
+
180
+ goal_target_month: None | Unset | str
181
+ if isinstance(self.goal_target_month, Unset):
182
+ goal_target_month = UNSET
183
+ elif isinstance(self.goal_target_month, datetime.date):
184
+ goal_target_month = self.goal_target_month.isoformat()
185
+ else:
186
+ goal_target_month = self.goal_target_month
187
+
188
+ goal_percentage_complete: None | Unset | int
189
+ if isinstance(self.goal_percentage_complete, Unset):
190
+ goal_percentage_complete = UNSET
191
+ else:
192
+ goal_percentage_complete = self.goal_percentage_complete
193
+
194
+ goal_months_to_budget: None | Unset | int
195
+ if isinstance(self.goal_months_to_budget, Unset):
196
+ goal_months_to_budget = UNSET
197
+ else:
198
+ goal_months_to_budget = self.goal_months_to_budget
199
+
200
+ goal_under_funded: None | Unset | int
201
+ if isinstance(self.goal_under_funded, Unset):
202
+ goal_under_funded = UNSET
203
+ else:
204
+ goal_under_funded = self.goal_under_funded
205
+
206
+ goal_overall_funded: None | Unset | int
207
+ if isinstance(self.goal_overall_funded, Unset):
208
+ goal_overall_funded = UNSET
209
+ else:
210
+ goal_overall_funded = self.goal_overall_funded
211
+
212
+ goal_overall_left: None | Unset | int
213
+ if isinstance(self.goal_overall_left, Unset):
214
+ goal_overall_left = UNSET
215
+ else:
216
+ goal_overall_left = self.goal_overall_left
217
+
218
+ field_dict: dict[str, Any] = {}
219
+ field_dict.update(self.additional_properties)
220
+ field_dict.update(
221
+ {
222
+ "id": id,
223
+ "category_group_id": category_group_id,
224
+ "name": name,
225
+ "hidden": hidden,
226
+ "budgeted": budgeted,
227
+ "activity": activity,
228
+ "balance": balance,
229
+ "deleted": deleted,
230
+ }
231
+ )
232
+ if category_group_name is not UNSET:
233
+ field_dict["category_group_name"] = category_group_name
234
+ if original_category_group_id is not UNSET:
235
+ field_dict["original_category_group_id"] = original_category_group_id
236
+ if note is not UNSET:
237
+ field_dict["note"] = note
238
+ if goal_type is not UNSET:
239
+ field_dict["goal_type"] = goal_type
240
+ if goal_needs_whole_amount is not UNSET:
241
+ field_dict["goal_needs_whole_amount"] = goal_needs_whole_amount
242
+ if goal_day is not UNSET:
243
+ field_dict["goal_day"] = goal_day
244
+ if goal_cadence is not UNSET:
245
+ field_dict["goal_cadence"] = goal_cadence
246
+ if goal_cadence_frequency is not UNSET:
247
+ field_dict["goal_cadence_frequency"] = goal_cadence_frequency
248
+ if goal_creation_month is not UNSET:
249
+ field_dict["goal_creation_month"] = goal_creation_month
250
+ if goal_target is not UNSET:
251
+ field_dict["goal_target"] = goal_target
252
+ if goal_target_month is not UNSET:
253
+ field_dict["goal_target_month"] = goal_target_month
254
+ if goal_percentage_complete is not UNSET:
255
+ field_dict["goal_percentage_complete"] = goal_percentage_complete
256
+ if goal_months_to_budget is not UNSET:
257
+ field_dict["goal_months_to_budget"] = goal_months_to_budget
258
+ if goal_under_funded is not UNSET:
259
+ field_dict["goal_under_funded"] = goal_under_funded
260
+ if goal_overall_funded is not UNSET:
261
+ field_dict["goal_overall_funded"] = goal_overall_funded
262
+ if goal_overall_left is not UNSET:
263
+ field_dict["goal_overall_left"] = goal_overall_left
264
+
265
+ return field_dict
266
+
267
+ @classmethod
268
+ def from_dict(cls: type[T], src_dict: Mapping[str, Any]) -> T:
269
+ d = dict(src_dict)
270
+ id = UUID(d.pop("id"))
271
+
272
+ category_group_id = UUID(d.pop("category_group_id"))
273
+
274
+ name = d.pop("name")
275
+
276
+ hidden = d.pop("hidden")
277
+
278
+ budgeted = d.pop("budgeted")
279
+
280
+ activity = d.pop("activity")
281
+
282
+ balance = d.pop("balance")
283
+
284
+ deleted = d.pop("deleted")
285
+
286
+ category_group_name = d.pop("category_group_name", UNSET)
287
+
288
+ def _parse_original_category_group_id(data: object) -> None | UUID | Unset:
289
+ if data is None:
290
+ return data
291
+ if isinstance(data, Unset):
292
+ return data
293
+ try:
294
+ if not isinstance(data, str):
295
+ raise TypeError()
296
+ original_category_group_id_type_0 = UUID(data)
297
+
298
+ return original_category_group_id_type_0
299
+ except: # noqa: E722
300
+ pass
301
+ return cast(None | UUID | Unset, data)
302
+
303
+ original_category_group_id = _parse_original_category_group_id(d.pop("original_category_group_id", UNSET))
304
+
305
+ def _parse_note(data: object) -> None | Unset | str:
306
+ if data is None:
307
+ return data
308
+ if isinstance(data, Unset):
309
+ return data
310
+ return cast(None | Unset | str, data)
311
+
312
+ note = _parse_note(d.pop("note", UNSET))
313
+
314
+ def _parse_goal_type(
315
+ data: object,
316
+ ) -> CategoryGoalTypeType1 | CategoryGoalTypeType2Type1 | CategoryGoalTypeType3Type1 | None | Unset:
317
+ if data is None:
318
+ return data
319
+ if isinstance(data, Unset):
320
+ return data
321
+ try:
322
+ if not isinstance(data, str):
323
+ raise TypeError()
324
+ goal_type_type_1 = CategoryGoalTypeType1(data)
325
+
326
+ return goal_type_type_1
327
+ except: # noqa: E722
328
+ pass
329
+ try:
330
+ if not isinstance(data, str):
331
+ raise TypeError()
332
+ goal_type_type_2_type_1 = CategoryGoalTypeType2Type1(data)
333
+
334
+ return goal_type_type_2_type_1
335
+ except: # noqa: E722
336
+ pass
337
+ try:
338
+ if not isinstance(data, str):
339
+ raise TypeError()
340
+ goal_type_type_3_type_1 = CategoryGoalTypeType3Type1(data)
341
+
342
+ return goal_type_type_3_type_1
343
+ except: # noqa: E722
344
+ pass
345
+ return cast(
346
+ CategoryGoalTypeType1 | CategoryGoalTypeType2Type1 | CategoryGoalTypeType3Type1 | None | Unset, data
347
+ )
348
+
349
+ goal_type = _parse_goal_type(d.pop("goal_type", UNSET))
350
+
351
+ def _parse_goal_needs_whole_amount(data: object) -> None | Unset | bool:
352
+ if data is None:
353
+ return data
354
+ if isinstance(data, Unset):
355
+ return data
356
+ return cast(None | Unset | bool, data)
357
+
358
+ goal_needs_whole_amount = _parse_goal_needs_whole_amount(d.pop("goal_needs_whole_amount", UNSET))
359
+
360
+ def _parse_goal_day(data: object) -> None | Unset | int:
361
+ if data is None:
362
+ return data
363
+ if isinstance(data, Unset):
364
+ return data
365
+ return cast(None | Unset | int, data)
366
+
367
+ goal_day = _parse_goal_day(d.pop("goal_day", UNSET))
368
+
369
+ def _parse_goal_cadence(data: object) -> None | Unset | int:
370
+ if data is None:
371
+ return data
372
+ if isinstance(data, Unset):
373
+ return data
374
+ return cast(None | Unset | int, data)
375
+
376
+ goal_cadence = _parse_goal_cadence(d.pop("goal_cadence", UNSET))
377
+
378
+ def _parse_goal_cadence_frequency(data: object) -> None | Unset | int:
379
+ if data is None:
380
+ return data
381
+ if isinstance(data, Unset):
382
+ return data
383
+ return cast(None | Unset | int, data)
384
+
385
+ goal_cadence_frequency = _parse_goal_cadence_frequency(d.pop("goal_cadence_frequency", UNSET))
386
+
387
+ def _parse_goal_creation_month(data: object) -> None | Unset | datetime.date:
388
+ if data is None:
389
+ return data
390
+ if isinstance(data, Unset):
391
+ return data
392
+ try:
393
+ if not isinstance(data, str):
394
+ raise TypeError()
395
+ goal_creation_month_type_0 = isoparse(data).date()
396
+
397
+ return goal_creation_month_type_0
398
+ except: # noqa: E722
399
+ pass
400
+ return cast(None | Unset | datetime.date, data)
401
+
402
+ goal_creation_month = _parse_goal_creation_month(d.pop("goal_creation_month", UNSET))
403
+
404
+ def _parse_goal_target(data: object) -> None | Unset | int:
405
+ if data is None:
406
+ return data
407
+ if isinstance(data, Unset):
408
+ return data
409
+ return cast(None | Unset | int, data)
410
+
411
+ goal_target = _parse_goal_target(d.pop("goal_target", UNSET))
412
+
413
+ def _parse_goal_target_month(data: object) -> None | Unset | datetime.date:
414
+ if data is None:
415
+ return data
416
+ if isinstance(data, Unset):
417
+ return data
418
+ try:
419
+ if not isinstance(data, str):
420
+ raise TypeError()
421
+ goal_target_month_type_0 = isoparse(data).date()
422
+
423
+ return goal_target_month_type_0
424
+ except: # noqa: E722
425
+ pass
426
+ return cast(None | Unset | datetime.date, data)
427
+
428
+ goal_target_month = _parse_goal_target_month(d.pop("goal_target_month", UNSET))
429
+
430
+ def _parse_goal_percentage_complete(data: object) -> None | Unset | int:
431
+ if data is None:
432
+ return data
433
+ if isinstance(data, Unset):
434
+ return data
435
+ return cast(None | Unset | int, data)
436
+
437
+ goal_percentage_complete = _parse_goal_percentage_complete(d.pop("goal_percentage_complete", UNSET))
438
+
439
+ def _parse_goal_months_to_budget(data: object) -> None | Unset | int:
440
+ if data is None:
441
+ return data
442
+ if isinstance(data, Unset):
443
+ return data
444
+ return cast(None | Unset | int, data)
445
+
446
+ goal_months_to_budget = _parse_goal_months_to_budget(d.pop("goal_months_to_budget", UNSET))
447
+
448
+ def _parse_goal_under_funded(data: object) -> None | Unset | int:
449
+ if data is None:
450
+ return data
451
+ if isinstance(data, Unset):
452
+ return data
453
+ return cast(None | Unset | int, data)
454
+
455
+ goal_under_funded = _parse_goal_under_funded(d.pop("goal_under_funded", UNSET))
456
+
457
+ def _parse_goal_overall_funded(data: object) -> None | Unset | int:
458
+ if data is None:
459
+ return data
460
+ if isinstance(data, Unset):
461
+ return data
462
+ return cast(None | Unset | int, data)
463
+
464
+ goal_overall_funded = _parse_goal_overall_funded(d.pop("goal_overall_funded", UNSET))
465
+
466
+ def _parse_goal_overall_left(data: object) -> None | Unset | int:
467
+ if data is None:
468
+ return data
469
+ if isinstance(data, Unset):
470
+ return data
471
+ return cast(None | Unset | int, data)
472
+
473
+ goal_overall_left = _parse_goal_overall_left(d.pop("goal_overall_left", UNSET))
474
+
475
+ category = cls(
476
+ id=id,
477
+ category_group_id=category_group_id,
478
+ name=name,
479
+ hidden=hidden,
480
+ budgeted=budgeted,
481
+ activity=activity,
482
+ balance=balance,
483
+ deleted=deleted,
484
+ category_group_name=category_group_name,
485
+ original_category_group_id=original_category_group_id,
486
+ note=note,
487
+ goal_type=goal_type,
488
+ goal_needs_whole_amount=goal_needs_whole_amount,
489
+ goal_day=goal_day,
490
+ goal_cadence=goal_cadence,
491
+ goal_cadence_frequency=goal_cadence_frequency,
492
+ goal_creation_month=goal_creation_month,
493
+ goal_target=goal_target,
494
+ goal_target_month=goal_target_month,
495
+ goal_percentage_complete=goal_percentage_complete,
496
+ goal_months_to_budget=goal_months_to_budget,
497
+ goal_under_funded=goal_under_funded,
498
+ goal_overall_funded=goal_overall_funded,
499
+ goal_overall_left=goal_overall_left,
500
+ )
501
+
502
+ category.additional_properties = d
503
+ return category
504
+
505
+ @property
506
+ def additional_keys(self) -> list[str]:
507
+ return list(self.additional_properties.keys())
508
+
509
+ def __getitem__(self, key: str) -> Any:
510
+ return self.additional_properties[key]
511
+
512
+ def __setitem__(self, key: str, value: Any) -> None:
513
+ self.additional_properties[key] = value
514
+
515
+ def __delitem__(self, key: str) -> None:
516
+ del self.additional_properties[key]
517
+
518
+ def __contains__(self, key: str) -> bool:
519
+ return key in self.additional_properties
@@ -0,0 +1,15 @@
1
+ from enum import Enum
2
+
3
+ from typing_extensions import override
4
+
5
+
6
+ class CategoryGoalTypeType1(str, Enum):
7
+ DEBT = "DEBT"
8
+ MF = "MF"
9
+ NEED = "NEED"
10
+ TB = "TB"
11
+ TBD = "TBD"
12
+
13
+ @override
14
+ def __str__(self) -> str:
15
+ return str(self.value)
@@ -0,0 +1,15 @@
1
+ from enum import Enum
2
+
3
+ from typing_extensions import override
4
+
5
+
6
+ class CategoryGoalTypeType2Type1(str, Enum):
7
+ DEBT = "DEBT"
8
+ MF = "MF"
9
+ NEED = "NEED"
10
+ TB = "TB"
11
+ TBD = "TBD"
12
+
13
+ @override
14
+ def __str__(self) -> str:
15
+ return str(self.value)
@@ -0,0 +1,15 @@
1
+ from enum import Enum
2
+
3
+ from typing_extensions import override
4
+
5
+
6
+ class CategoryGoalTypeType3Type1(str, Enum):
7
+ DEBT = "DEBT"
8
+ MF = "MF"
9
+ NEED = "NEED"
10
+ TB = "TB"
11
+ TBD = "TBD"
12
+
13
+ @override
14
+ def __str__(self) -> str:
15
+ return str(self.value)
@@ -0,0 +1,85 @@
1
+ from collections.abc import Mapping
2
+ from typing import Any, TypeVar
3
+ from uuid import UUID
4
+
5
+ from attrs import define as _attrs_define
6
+ from attrs import field as _attrs_field
7
+
8
+ T = TypeVar("T", bound="CategoryGroup")
9
+
10
+
11
+ @_attrs_define
12
+ class CategoryGroup:
13
+ """
14
+ Attributes:
15
+ id (UUID):
16
+ name (str):
17
+ hidden (bool): Whether or not the category group is hidden
18
+ deleted (bool): Whether or not the category group has been deleted. Deleted category groups will only be
19
+ included in delta requests.
20
+ """
21
+
22
+ id: UUID
23
+ name: str
24
+ hidden: bool
25
+ deleted: bool
26
+ additional_properties: dict[str, Any] = _attrs_field(init=False, factory=dict)
27
+
28
+ def to_dict(self) -> dict[str, Any]:
29
+ id = str(self.id)
30
+
31
+ name = self.name
32
+
33
+ hidden = self.hidden
34
+
35
+ deleted = self.deleted
36
+
37
+ field_dict: dict[str, Any] = {}
38
+ field_dict.update(self.additional_properties)
39
+ field_dict.update(
40
+ {
41
+ "id": id,
42
+ "name": name,
43
+ "hidden": hidden,
44
+ "deleted": deleted,
45
+ }
46
+ )
47
+
48
+ return field_dict
49
+
50
+ @classmethod
51
+ def from_dict(cls: type[T], src_dict: Mapping[str, Any]) -> T:
52
+ d = dict(src_dict)
53
+ id = UUID(d.pop("id"))
54
+
55
+ name = d.pop("name")
56
+
57
+ hidden = d.pop("hidden")
58
+
59
+ deleted = d.pop("deleted")
60
+
61
+ category_group = cls(
62
+ id=id,
63
+ name=name,
64
+ hidden=hidden,
65
+ deleted=deleted,
66
+ )
67
+
68
+ category_group.additional_properties = d
69
+ return category_group
70
+
71
+ @property
72
+ def additional_keys(self) -> list[str]:
73
+ return list(self.additional_properties.keys())
74
+
75
+ def __getitem__(self, key: str) -> Any:
76
+ return self.additional_properties[key]
77
+
78
+ def __setitem__(self, key: str, value: Any) -> None:
79
+ self.additional_properties[key] = value
80
+
81
+ def __delitem__(self, key: str) -> None:
82
+ del self.additional_properties[key]
83
+
84
+ def __contains__(self, key: str) -> bool:
85
+ return key in self.additional_properties