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,145 @@
1
+ import datetime
2
+ from collections.abc import Mapping
3
+ from typing import Any, TypeVar, cast
4
+
5
+ from attrs import define as _attrs_define
6
+ from attrs import field as _attrs_field
7
+ from dateutil.parser import isoparse
8
+
9
+ from ynab_cli.adapters.ynab.types import UNSET, Unset
10
+
11
+ T = TypeVar("T", bound="MonthSummary")
12
+
13
+
14
+ @_attrs_define
15
+ class MonthSummary:
16
+ """
17
+ Attributes:
18
+ month (datetime.date):
19
+ income (int): The total amount of transactions categorized to 'Inflow: Ready to Assign' in the month
20
+ budgeted (int): The total amount budgeted in the month
21
+ activity (int): The total amount of transactions in the month, excluding those categorized to 'Inflow: Ready to
22
+ Assign'
23
+ to_be_budgeted (int): The available amount for 'Ready to Assign'
24
+ deleted (bool): Whether or not the month has been deleted. Deleted months will only be included in delta
25
+ requests.
26
+ note (Union[None, Unset, str]):
27
+ age_of_money (Union[None, Unset, int]): The Age of Money as of the month
28
+ """
29
+
30
+ month: datetime.date
31
+ income: int
32
+ budgeted: int
33
+ activity: int
34
+ to_be_budgeted: int
35
+ deleted: bool
36
+ note: None | Unset | str = UNSET
37
+ age_of_money: None | Unset | int = UNSET
38
+ additional_properties: dict[str, Any] = _attrs_field(init=False, factory=dict)
39
+
40
+ def to_dict(self) -> dict[str, Any]:
41
+ month = self.month.isoformat()
42
+
43
+ income = self.income
44
+
45
+ budgeted = self.budgeted
46
+
47
+ activity = self.activity
48
+
49
+ to_be_budgeted = self.to_be_budgeted
50
+
51
+ deleted = self.deleted
52
+
53
+ note: None | Unset | str
54
+ if isinstance(self.note, Unset):
55
+ note = UNSET
56
+ else:
57
+ note = self.note
58
+
59
+ age_of_money: None | Unset | int
60
+ if isinstance(self.age_of_money, Unset):
61
+ age_of_money = UNSET
62
+ else:
63
+ age_of_money = self.age_of_money
64
+
65
+ field_dict: dict[str, Any] = {}
66
+ field_dict.update(self.additional_properties)
67
+ field_dict.update(
68
+ {
69
+ "month": month,
70
+ "income": income,
71
+ "budgeted": budgeted,
72
+ "activity": activity,
73
+ "to_be_budgeted": to_be_budgeted,
74
+ "deleted": deleted,
75
+ }
76
+ )
77
+ if note is not UNSET:
78
+ field_dict["note"] = note
79
+ if age_of_money is not UNSET:
80
+ field_dict["age_of_money"] = age_of_money
81
+
82
+ return field_dict
83
+
84
+ @classmethod
85
+ def from_dict(cls: type[T], src_dict: Mapping[str, Any]) -> T:
86
+ d = dict(src_dict)
87
+ month = isoparse(d.pop("month")).date()
88
+
89
+ income = d.pop("income")
90
+
91
+ budgeted = d.pop("budgeted")
92
+
93
+ activity = d.pop("activity")
94
+
95
+ to_be_budgeted = d.pop("to_be_budgeted")
96
+
97
+ deleted = d.pop("deleted")
98
+
99
+ def _parse_note(data: object) -> None | Unset | str:
100
+ if data is None:
101
+ return data
102
+ if isinstance(data, Unset):
103
+ return data
104
+ return cast(None | Unset | str, data)
105
+
106
+ note = _parse_note(d.pop("note", UNSET))
107
+
108
+ def _parse_age_of_money(data: object) -> None | Unset | int:
109
+ if data is None:
110
+ return data
111
+ if isinstance(data, Unset):
112
+ return data
113
+ return cast(None | Unset | int, data)
114
+
115
+ age_of_money = _parse_age_of_money(d.pop("age_of_money", UNSET))
116
+
117
+ month_summary = cls(
118
+ month=month,
119
+ income=income,
120
+ budgeted=budgeted,
121
+ activity=activity,
122
+ to_be_budgeted=to_be_budgeted,
123
+ deleted=deleted,
124
+ note=note,
125
+ age_of_money=age_of_money,
126
+ )
127
+
128
+ month_summary.additional_properties = d
129
+ return month_summary
130
+
131
+ @property
132
+ def additional_keys(self) -> list[str]:
133
+ return list(self.additional_properties.keys())
134
+
135
+ def __getitem__(self, key: str) -> Any:
136
+ return self.additional_properties[key]
137
+
138
+ def __setitem__(self, key: str, value: Any) -> None:
139
+ self.additional_properties[key] = value
140
+
141
+ def __delitem__(self, key: str) -> None:
142
+ del self.additional_properties[key]
143
+
144
+ def __contains__(self, key: str) -> bool:
145
+ return key in self.additional_properties
@@ -0,0 +1,352 @@
1
+ import datetime
2
+ from collections.abc import Mapping
3
+ from typing import TYPE_CHECKING, 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.transaction_cleared_status import TransactionClearedStatus
11
+ from ynab_cli.adapters.ynab.models.transaction_flag_color_type_1 import TransactionFlagColorType1
12
+ from ynab_cli.adapters.ynab.models.transaction_flag_color_type_2_type_1 import TransactionFlagColorType2Type1
13
+ from ynab_cli.adapters.ynab.models.transaction_flag_color_type_3_type_1 import TransactionFlagColorType3Type1
14
+ from ynab_cli.adapters.ynab.types import UNSET, Unset
15
+
16
+ if TYPE_CHECKING:
17
+ from ynab_cli.adapters.ynab.models.save_sub_transaction import SaveSubTransaction
18
+
19
+
20
+ T = TypeVar("T", bound="NewTransaction")
21
+
22
+
23
+ @_attrs_define
24
+ class NewTransaction:
25
+ """
26
+ Attributes:
27
+ account_id (Union[Unset, UUID]):
28
+ date (Union[Unset, datetime.date]): The transaction date in ISO format (e.g. 2016-12-01). Future dates
29
+ (scheduled transactions) are not permitted. Split transaction dates cannot be changed and if a different date
30
+ is supplied it will be ignored.
31
+ amount (Union[Unset, int]): The transaction amount in milliunits format. Split transaction amounts cannot be
32
+ changed and if a different amount is supplied it will be ignored.
33
+ payee_id (Union[None, UUID, Unset]): The payee for the transaction. To create a transfer between two accounts,
34
+ use the account transfer payee pointing to the target account. Account transfer payees are specified as
35
+ `transfer_payee_id` on the account resource.
36
+ payee_name (Union[None, Unset, str]): The payee name. If a `payee_name` value is provided and `payee_id` has a
37
+ null value, the `payee_name` value will be used to resolve the payee by either (1) a matching payee rename rule
38
+ (only if `import_id` is also specified) or (2) a payee with the same name or (3) creation of a new payee.
39
+ category_id (Union[None, UUID, Unset]): The category for the transaction. To configure a split transaction, you
40
+ can specify null for `category_id` and provide a `subtransactions` array as part of the transaction object. If
41
+ an existing transaction is a split, the `category_id` cannot be changed. Credit Card Payment categories are not
42
+ permitted and will be ignored if supplied.
43
+ memo (Union[None, Unset, str]):
44
+ cleared (Union[Unset, TransactionClearedStatus]): The cleared status of the transaction
45
+ approved (Union[Unset, bool]): Whether or not the transaction is approved. If not supplied, transaction will be
46
+ unapproved by default.
47
+ flag_color (Union[None, TransactionFlagColorType1, TransactionFlagColorType2Type1,
48
+ TransactionFlagColorType3Type1, Unset]): The transaction flag
49
+ subtransactions (Union[Unset, list['SaveSubTransaction']]): An array of subtransactions to configure a
50
+ transaction as a split. Updating `subtransactions` on an existing split transaction is not supported.
51
+ import_id (Union[None, Unset, str]): If specified, a new transaction will be assigned this `import_id` and
52
+ considered "imported". We will also attempt to match this imported transaction to an existing "user-entered"
53
+ transaction on the same account, with the same amount, and with a date +/-10 days from the imported transaction
54
+ date.<br><br>Transactions imported through File Based Import or Direct Import (not through the API) are assigned
55
+ an import_id in the format: 'YNAB:[milliunit_amount]:[iso_date]:[occurrence]'. For example, a transaction dated
56
+ 2015-12-30 in the amount of -$294.23 USD would have an import_id of 'YNAB:-294230:2015-12-30:1'. If a second
57
+ transaction on the same account was imported and had the same date and same amount, its import_id would be
58
+ 'YNAB:-294230:2015-12-30:2'. Using a consistent format will prevent duplicates through Direct Import and File
59
+ Based Import.<br><br>If import_id is omitted or specified as null, the transaction will be treated as a "user-
60
+ entered" transaction. As such, it will be eligible to be matched against transactions later being imported (via
61
+ DI, FBI, or API).
62
+ """
63
+
64
+ account_id: Unset | UUID = UNSET
65
+ date: Unset | datetime.date = UNSET
66
+ amount: Unset | int = UNSET
67
+ payee_id: None | UUID | Unset = UNSET
68
+ payee_name: None | Unset | str = UNSET
69
+ category_id: None | UUID | Unset = UNSET
70
+ memo: None | Unset | str = UNSET
71
+ cleared: Unset | TransactionClearedStatus = UNSET
72
+ approved: Unset | bool = UNSET
73
+ flag_color: (
74
+ None | TransactionFlagColorType1 | TransactionFlagColorType2Type1 | TransactionFlagColorType3Type1 | Unset
75
+ ) = UNSET
76
+ subtransactions: Unset | list["SaveSubTransaction"] = UNSET
77
+ import_id: None | Unset | str = UNSET
78
+ additional_properties: dict[str, Any] = _attrs_field(init=False, factory=dict)
79
+
80
+ def to_dict(self) -> dict[str, Any]:
81
+ account_id: Unset | str = UNSET
82
+ if not isinstance(self.account_id, Unset):
83
+ account_id = str(self.account_id)
84
+
85
+ date: Unset | str = UNSET
86
+ if not isinstance(self.date, Unset):
87
+ date = self.date.isoformat()
88
+
89
+ amount = self.amount
90
+
91
+ payee_id: None | Unset | str
92
+ if isinstance(self.payee_id, Unset):
93
+ payee_id = UNSET
94
+ elif isinstance(self.payee_id, UUID):
95
+ payee_id = str(self.payee_id)
96
+ else:
97
+ payee_id = self.payee_id
98
+
99
+ payee_name: None | Unset | str
100
+ if isinstance(self.payee_name, Unset):
101
+ payee_name = UNSET
102
+ else:
103
+ payee_name = self.payee_name
104
+
105
+ category_id: None | Unset | str
106
+ if isinstance(self.category_id, Unset):
107
+ category_id = UNSET
108
+ elif isinstance(self.category_id, UUID):
109
+ category_id = str(self.category_id)
110
+ else:
111
+ category_id = self.category_id
112
+
113
+ memo: None | Unset | str
114
+ if isinstance(self.memo, Unset):
115
+ memo = UNSET
116
+ else:
117
+ memo = self.memo
118
+
119
+ cleared: Unset | str = UNSET
120
+ if not isinstance(self.cleared, Unset):
121
+ cleared = self.cleared.value
122
+
123
+ approved = self.approved
124
+
125
+ flag_color: None | Unset | str
126
+ if isinstance(self.flag_color, Unset):
127
+ flag_color = UNSET
128
+ elif isinstance(self.flag_color, TransactionFlagColorType1):
129
+ flag_color = self.flag_color.value
130
+ elif isinstance(self.flag_color, TransactionFlagColorType2Type1):
131
+ flag_color = self.flag_color.value
132
+ elif isinstance(self.flag_color, TransactionFlagColorType3Type1):
133
+ flag_color = self.flag_color.value
134
+ else:
135
+ flag_color = self.flag_color
136
+
137
+ subtransactions: Unset | list[dict[str, Any]] = UNSET
138
+ if not isinstance(self.subtransactions, Unset):
139
+ subtransactions = []
140
+ for subtransactions_item_data in self.subtransactions:
141
+ subtransactions_item = subtransactions_item_data.to_dict()
142
+ subtransactions.append(subtransactions_item)
143
+
144
+ import_id: None | Unset | str
145
+ if isinstance(self.import_id, Unset):
146
+ import_id = UNSET
147
+ else:
148
+ import_id = self.import_id
149
+
150
+ field_dict: dict[str, Any] = {}
151
+ field_dict.update(self.additional_properties)
152
+ field_dict.update({})
153
+ if account_id is not UNSET:
154
+ field_dict["account_id"] = account_id
155
+ if date is not UNSET:
156
+ field_dict["date"] = date
157
+ if amount is not UNSET:
158
+ field_dict["amount"] = amount
159
+ if payee_id is not UNSET:
160
+ field_dict["payee_id"] = payee_id
161
+ if payee_name is not UNSET:
162
+ field_dict["payee_name"] = payee_name
163
+ if category_id is not UNSET:
164
+ field_dict["category_id"] = category_id
165
+ if memo is not UNSET:
166
+ field_dict["memo"] = memo
167
+ if cleared is not UNSET:
168
+ field_dict["cleared"] = cleared
169
+ if approved is not UNSET:
170
+ field_dict["approved"] = approved
171
+ if flag_color is not UNSET:
172
+ field_dict["flag_color"] = flag_color
173
+ if subtransactions is not UNSET:
174
+ field_dict["subtransactions"] = subtransactions
175
+ if import_id is not UNSET:
176
+ field_dict["import_id"] = import_id
177
+
178
+ return field_dict
179
+
180
+ @classmethod
181
+ def from_dict(cls: type[T], src_dict: Mapping[str, Any]) -> T:
182
+ from ynab_cli.adapters.ynab.models.save_sub_transaction import SaveSubTransaction
183
+
184
+ d = dict(src_dict)
185
+ _account_id = d.pop("account_id", UNSET)
186
+ account_id: Unset | UUID
187
+ if isinstance(_account_id, Unset):
188
+ account_id = UNSET
189
+ else:
190
+ account_id = UUID(_account_id)
191
+
192
+ _date = d.pop("date", UNSET)
193
+ date: Unset | datetime.date
194
+ if isinstance(_date, Unset):
195
+ date = UNSET
196
+ else:
197
+ date = isoparse(_date).date()
198
+
199
+ amount = d.pop("amount", UNSET)
200
+
201
+ def _parse_payee_id(data: object) -> None | UUID | Unset:
202
+ if data is None:
203
+ return data
204
+ if isinstance(data, Unset):
205
+ return data
206
+ try:
207
+ if not isinstance(data, str):
208
+ raise TypeError()
209
+ payee_id_type_0 = UUID(data)
210
+
211
+ return payee_id_type_0
212
+ except: # noqa: E722
213
+ pass
214
+ return cast(None | UUID | Unset, data)
215
+
216
+ payee_id = _parse_payee_id(d.pop("payee_id", UNSET))
217
+
218
+ def _parse_payee_name(data: object) -> None | Unset | str:
219
+ if data is None:
220
+ return data
221
+ if isinstance(data, Unset):
222
+ return data
223
+ return cast(None | Unset | str, data)
224
+
225
+ payee_name = _parse_payee_name(d.pop("payee_name", UNSET))
226
+
227
+ def _parse_category_id(data: object) -> None | UUID | Unset:
228
+ if data is None:
229
+ return data
230
+ if isinstance(data, Unset):
231
+ return data
232
+ try:
233
+ if not isinstance(data, str):
234
+ raise TypeError()
235
+ category_id_type_0 = UUID(data)
236
+
237
+ return category_id_type_0
238
+ except: # noqa: E722
239
+ pass
240
+ return cast(None | UUID | Unset, data)
241
+
242
+ category_id = _parse_category_id(d.pop("category_id", UNSET))
243
+
244
+ def _parse_memo(data: object) -> None | Unset | str:
245
+ if data is None:
246
+ return data
247
+ if isinstance(data, Unset):
248
+ return data
249
+ return cast(None | Unset | str, data)
250
+
251
+ memo = _parse_memo(d.pop("memo", UNSET))
252
+
253
+ _cleared = d.pop("cleared", UNSET)
254
+ cleared: Unset | TransactionClearedStatus
255
+ if isinstance(_cleared, Unset):
256
+ cleared = UNSET
257
+ else:
258
+ cleared = TransactionClearedStatus(_cleared)
259
+
260
+ approved = d.pop("approved", UNSET)
261
+
262
+ def _parse_flag_color(
263
+ data: object,
264
+ ) -> None | TransactionFlagColorType1 | TransactionFlagColorType2Type1 | TransactionFlagColorType3Type1 | Unset:
265
+ if data is None:
266
+ return data
267
+ if isinstance(data, Unset):
268
+ return data
269
+ try:
270
+ if not isinstance(data, str):
271
+ raise TypeError()
272
+ componentsschemas_transaction_flag_color_type_1 = TransactionFlagColorType1(data)
273
+
274
+ return componentsschemas_transaction_flag_color_type_1
275
+ except: # noqa: E722
276
+ pass
277
+ try:
278
+ if not isinstance(data, str):
279
+ raise TypeError()
280
+ componentsschemas_transaction_flag_color_type_2_type_1 = TransactionFlagColorType2Type1(data)
281
+
282
+ return componentsschemas_transaction_flag_color_type_2_type_1
283
+ except: # noqa: E722
284
+ pass
285
+ try:
286
+ if not isinstance(data, str):
287
+ raise TypeError()
288
+ componentsschemas_transaction_flag_color_type_3_type_1 = TransactionFlagColorType3Type1(data)
289
+
290
+ return componentsschemas_transaction_flag_color_type_3_type_1
291
+ except: # noqa: E722
292
+ pass
293
+ return cast(
294
+ None
295
+ | TransactionFlagColorType1
296
+ | TransactionFlagColorType2Type1
297
+ | TransactionFlagColorType3Type1
298
+ | Unset,
299
+ data,
300
+ )
301
+
302
+ flag_color = _parse_flag_color(d.pop("flag_color", UNSET))
303
+
304
+ subtransactions = []
305
+ _subtransactions = d.pop("subtransactions", UNSET)
306
+ for subtransactions_item_data in _subtransactions or []:
307
+ subtransactions_item = SaveSubTransaction.from_dict(subtransactions_item_data)
308
+
309
+ subtransactions.append(subtransactions_item)
310
+
311
+ def _parse_import_id(data: object) -> None | Unset | str:
312
+ if data is None:
313
+ return data
314
+ if isinstance(data, Unset):
315
+ return data
316
+ return cast(None | Unset | str, data)
317
+
318
+ import_id = _parse_import_id(d.pop("import_id", UNSET))
319
+
320
+ new_transaction = cls(
321
+ account_id=account_id,
322
+ date=date,
323
+ amount=amount,
324
+ payee_id=payee_id,
325
+ payee_name=payee_name,
326
+ category_id=category_id,
327
+ memo=memo,
328
+ cleared=cleared,
329
+ approved=approved,
330
+ flag_color=flag_color,
331
+ subtransactions=subtransactions,
332
+ import_id=import_id,
333
+ )
334
+
335
+ new_transaction.additional_properties = d
336
+ return new_transaction
337
+
338
+ @property
339
+ def additional_keys(self) -> list[str]:
340
+ return list(self.additional_properties.keys())
341
+
342
+ def __getitem__(self, key: str) -> Any:
343
+ return self.additional_properties[key]
344
+
345
+ def __setitem__(self, key: str, value: Any) -> None:
346
+ self.additional_properties[key] = value
347
+
348
+ def __delitem__(self, key: str) -> None:
349
+ del self.additional_properties[key]
350
+
351
+ def __contains__(self, key: str) -> bool:
352
+ return key in self.additional_properties
@@ -0,0 +1,65 @@
1
+ from collections.abc import Mapping
2
+ from typing import TYPE_CHECKING, Any, TypeVar
3
+
4
+ from attrs import define as _attrs_define
5
+ from attrs import field as _attrs_field
6
+
7
+ if TYPE_CHECKING:
8
+ from ynab_cli.adapters.ynab.models.save_category import SaveCategory
9
+
10
+
11
+ T = TypeVar("T", bound="PatchCategoryWrapper")
12
+
13
+
14
+ @_attrs_define
15
+ class PatchCategoryWrapper:
16
+ """
17
+ Attributes:
18
+ category (SaveCategory):
19
+ """
20
+
21
+ category: "SaveCategory"
22
+ additional_properties: dict[str, Any] = _attrs_field(init=False, factory=dict)
23
+
24
+ def to_dict(self) -> dict[str, Any]:
25
+ category = self.category.to_dict()
26
+
27
+ field_dict: dict[str, Any] = {}
28
+ field_dict.update(self.additional_properties)
29
+ field_dict.update(
30
+ {
31
+ "category": category,
32
+ }
33
+ )
34
+
35
+ return field_dict
36
+
37
+ @classmethod
38
+ def from_dict(cls: type[T], src_dict: Mapping[str, Any]) -> T:
39
+ from ynab_cli.adapters.ynab.models.save_category import SaveCategory
40
+
41
+ d = dict(src_dict)
42
+ category = SaveCategory.from_dict(d.pop("category"))
43
+
44
+ patch_category_wrapper = cls(
45
+ category=category,
46
+ )
47
+
48
+ patch_category_wrapper.additional_properties = d
49
+ return patch_category_wrapper
50
+
51
+ @property
52
+ def additional_keys(self) -> list[str]:
53
+ return list(self.additional_properties.keys())
54
+
55
+ def __getitem__(self, key: str) -> Any:
56
+ return self.additional_properties[key]
57
+
58
+ def __setitem__(self, key: str, value: Any) -> None:
59
+ self.additional_properties[key] = value
60
+
61
+ def __delitem__(self, key: str) -> None:
62
+ del self.additional_properties[key]
63
+
64
+ def __contains__(self, key: str) -> bool:
65
+ return key in self.additional_properties
@@ -0,0 +1,65 @@
1
+ from collections.abc import Mapping
2
+ from typing import TYPE_CHECKING, Any, TypeVar
3
+
4
+ from attrs import define as _attrs_define
5
+ from attrs import field as _attrs_field
6
+
7
+ if TYPE_CHECKING:
8
+ from ynab_cli.adapters.ynab.models.save_month_category import SaveMonthCategory
9
+
10
+
11
+ T = TypeVar("T", bound="PatchMonthCategoryWrapper")
12
+
13
+
14
+ @_attrs_define
15
+ class PatchMonthCategoryWrapper:
16
+ """
17
+ Attributes:
18
+ category (SaveMonthCategory):
19
+ """
20
+
21
+ category: "SaveMonthCategory"
22
+ additional_properties: dict[str, Any] = _attrs_field(init=False, factory=dict)
23
+
24
+ def to_dict(self) -> dict[str, Any]:
25
+ category = self.category.to_dict()
26
+
27
+ field_dict: dict[str, Any] = {}
28
+ field_dict.update(self.additional_properties)
29
+ field_dict.update(
30
+ {
31
+ "category": category,
32
+ }
33
+ )
34
+
35
+ return field_dict
36
+
37
+ @classmethod
38
+ def from_dict(cls: type[T], src_dict: Mapping[str, Any]) -> T:
39
+ from ynab_cli.adapters.ynab.models.save_month_category import SaveMonthCategory
40
+
41
+ d = dict(src_dict)
42
+ category = SaveMonthCategory.from_dict(d.pop("category"))
43
+
44
+ patch_month_category_wrapper = cls(
45
+ category=category,
46
+ )
47
+
48
+ patch_month_category_wrapper.additional_properties = d
49
+ return patch_month_category_wrapper
50
+
51
+ @property
52
+ def additional_keys(self) -> list[str]:
53
+ return list(self.additional_properties.keys())
54
+
55
+ def __getitem__(self, key: str) -> Any:
56
+ return self.additional_properties[key]
57
+
58
+ def __setitem__(self, key: str, value: Any) -> None:
59
+ self.additional_properties[key] = value
60
+
61
+ def __delitem__(self, key: str) -> None:
62
+ del self.additional_properties[key]
63
+
64
+ def __contains__(self, key: str) -> bool:
65
+ return key in self.additional_properties
@@ -0,0 +1,65 @@
1
+ from collections.abc import Mapping
2
+ from typing import TYPE_CHECKING, Any, TypeVar
3
+
4
+ from attrs import define as _attrs_define
5
+ from attrs import field as _attrs_field
6
+
7
+ if TYPE_CHECKING:
8
+ from ynab_cli.adapters.ynab.models.save_payee import SavePayee
9
+
10
+
11
+ T = TypeVar("T", bound="PatchPayeeWrapper")
12
+
13
+
14
+ @_attrs_define
15
+ class PatchPayeeWrapper:
16
+ """
17
+ Attributes:
18
+ payee (SavePayee):
19
+ """
20
+
21
+ payee: "SavePayee"
22
+ additional_properties: dict[str, Any] = _attrs_field(init=False, factory=dict)
23
+
24
+ def to_dict(self) -> dict[str, Any]:
25
+ payee = self.payee.to_dict()
26
+
27
+ field_dict: dict[str, Any] = {}
28
+ field_dict.update(self.additional_properties)
29
+ field_dict.update(
30
+ {
31
+ "payee": payee,
32
+ }
33
+ )
34
+
35
+ return field_dict
36
+
37
+ @classmethod
38
+ def from_dict(cls: type[T], src_dict: Mapping[str, Any]) -> T:
39
+ from ynab_cli.adapters.ynab.models.save_payee import SavePayee
40
+
41
+ d = dict(src_dict)
42
+ payee = SavePayee.from_dict(d.pop("payee"))
43
+
44
+ patch_payee_wrapper = cls(
45
+ payee=payee,
46
+ )
47
+
48
+ patch_payee_wrapper.additional_properties = d
49
+ return patch_payee_wrapper
50
+
51
+ @property
52
+ def additional_keys(self) -> list[str]:
53
+ return list(self.additional_properties.keys())
54
+
55
+ def __getitem__(self, key: str) -> Any:
56
+ return self.additional_properties[key]
57
+
58
+ def __setitem__(self, key: str, value: Any) -> None:
59
+ self.additional_properties[key] = value
60
+
61
+ def __delitem__(self, key: str) -> None:
62
+ del self.additional_properties[key]
63
+
64
+ def __contains__(self, key: str) -> bool:
65
+ return key in self.additional_properties