python-casahome 0.2.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.
- casahome/__init__.py +30 -0
- casahome/_base_http.py +21 -0
- casahome/api.py +1135 -0
- casahome/auth.py +199 -0
- casahome/client.py +168 -0
- casahome/const.py +34 -0
- casahome/exceptions.py +52 -0
- casahome/models/__init__.py +477 -0
- casahome/models/_base.py +25 -0
- casahome/models/ai.py +58 -0
- casahome/models/assets.py +123 -0
- casahome/models/availability.py +39 -0
- casahome/models/bootstrap.py +134 -0
- casahome/models/calendar.py +33 -0
- casahome/models/catalogs.py +73 -0
- casahome/models/credits.py +29 -0
- casahome/models/documents.py +127 -0
- casahome/models/enums.py +183 -0
- casahome/models/feed.py +30 -0
- casahome/models/help_center.py +45 -0
- casahome/models/home.py +175 -0
- casahome/models/images.py +48 -0
- casahome/models/mailbox.py +160 -0
- casahome/models/maintenance.py +200 -0
- casahome/models/membership.py +65 -0
- casahome/models/paint.py +56 -0
- casahome/models/preferences.py +104 -0
- casahome/models/purchases.py +106 -0
- casahome/models/read_todos.py +22 -0
- casahome/models/referral.py +21 -0
- casahome/models/requests.py +149 -0
- casahome/models/tasks.py +77 -0
- casahome/models/taxes.py +47 -0
- casahome/models/todos.py +52 -0
- casahome/models/visits.py +158 -0
- casahome/models/write_contracts.py +147 -0
- casahome/py.typed +0 -0
- casahome/streaming.py +278 -0
- python_casahome-0.2.0.dist-info/METADATA +272 -0
- python_casahome-0.2.0.dist-info/RECORD +42 -0
- python_casahome-0.2.0.dist-info/WHEEL +4 -0
- python_casahome-0.2.0.dist-info/licenses/LICENSE +21 -0
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
"""Populated preferences and onboarding responses, plus calendar sync metadata."""
|
|
2
|
+
|
|
3
|
+
from pydantic import JsonValue
|
|
4
|
+
|
|
5
|
+
from casahome.models._base import CasaModel
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
class SchedulingDay(CasaModel):
|
|
9
|
+
day_of_week: int
|
|
10
|
+
label: str
|
|
11
|
+
enabled: bool
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
class SchedulingTimeOfDay(CasaModel):
|
|
15
|
+
id: str
|
|
16
|
+
window_title: str
|
|
17
|
+
window_time_range: str
|
|
18
|
+
enabled: bool
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
class SchedulePreferencesResponse(CasaModel):
|
|
22
|
+
days_of_week: list[SchedulingDay]
|
|
23
|
+
times_of_day: list[SchedulingTimeOfDay]
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
class NotificationChannel(CasaModel):
|
|
27
|
+
channel: str
|
|
28
|
+
enabled: bool
|
|
29
|
+
default_enabled: bool
|
|
30
|
+
required: bool
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
class NotificationType(CasaModel):
|
|
34
|
+
key: str
|
|
35
|
+
display_name: str
|
|
36
|
+
description: str
|
|
37
|
+
sort_order: int
|
|
38
|
+
channels: list[NotificationChannel]
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
class NotificationGroup(CasaModel):
|
|
42
|
+
key: str
|
|
43
|
+
display_name: str
|
|
44
|
+
sort_order: int
|
|
45
|
+
types: list[NotificationType]
|
|
46
|
+
|
|
47
|
+
|
|
48
|
+
class NotificationSettingsResponse(CasaModel):
|
|
49
|
+
groups: list[NotificationGroup]
|
|
50
|
+
|
|
51
|
+
|
|
52
|
+
class OnboardingSlot(CasaModel):
|
|
53
|
+
start_time: int
|
|
54
|
+
vendor_ids: list[str]
|
|
55
|
+
|
|
56
|
+
|
|
57
|
+
class OnboardingAvailabilityResponse(CasaModel):
|
|
58
|
+
message: str
|
|
59
|
+
number_of_required_vendors: int
|
|
60
|
+
estimated_visit_duration_seconds: int
|
|
61
|
+
timezone: str | None = None
|
|
62
|
+
available_slots: list[OnboardingSlot]
|
|
63
|
+
|
|
64
|
+
|
|
65
|
+
class OnboardingEvent(CasaModel):
|
|
66
|
+
id: str
|
|
67
|
+
start_at: int
|
|
68
|
+
end_at: int
|
|
69
|
+
|
|
70
|
+
|
|
71
|
+
class OnboardingDetailsResponse(CasaModel):
|
|
72
|
+
calendar_events: list[OnboardingEvent]
|
|
73
|
+
|
|
74
|
+
|
|
75
|
+
class AccessPreferencesResponse(CasaModel):
|
|
76
|
+
home_id: str
|
|
77
|
+
general_instructions: str | None = None
|
|
78
|
+
package_pickup_method: str | None = None
|
|
79
|
+
package_pickup_spot: str | None = None
|
|
80
|
+
package_pickup_call_home_member_id: str | None = None
|
|
81
|
+
package_pickup_general_instructions: str | None = None
|
|
82
|
+
|
|
83
|
+
|
|
84
|
+
class CalendarOption(CasaModel):
|
|
85
|
+
"""UNVERIFIED item. Available/display calendars were empty."""
|
|
86
|
+
|
|
87
|
+
id: str | None = None
|
|
88
|
+
summary: str | None = None
|
|
89
|
+
color: str | None = None
|
|
90
|
+
|
|
91
|
+
|
|
92
|
+
class CalendarSyncResponse(CasaModel):
|
|
93
|
+
home_id: str
|
|
94
|
+
user_oauth_connected: bool
|
|
95
|
+
user_oauth_insufficient_scope: bool
|
|
96
|
+
calendar_sync_active: bool
|
|
97
|
+
has_active_syncs_in_other_homes: bool
|
|
98
|
+
available_calendars: list[CalendarOption]
|
|
99
|
+
display_calendars: list[CalendarOption]
|
|
100
|
+
user_oauth_email: str | None = None
|
|
101
|
+
google_calendar_id: str | None = None
|
|
102
|
+
google_calendar_summary: str | None = None
|
|
103
|
+
sync_status: str | None = None
|
|
104
|
+
sync_progress: JsonValue = None # Only null observed, no static structure.
|
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
"""Read-only purchases. All item lists were empty, item fields are static.
|
|
2
|
+
|
|
3
|
+
Invoice payment structures, pricing summaries, and return info stay opaque JSON.
|
|
4
|
+
No payment or purchase mutation is exposed by these models.
|
|
5
|
+
"""
|
|
6
|
+
|
|
7
|
+
from pydantic import JsonValue
|
|
8
|
+
|
|
9
|
+
from casahome.models._base import CasaModel
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
class PurchaseVendor(CasaModel):
|
|
13
|
+
id: str | None = None
|
|
14
|
+
name: str | None = None
|
|
15
|
+
image_url: str | None = None
|
|
16
|
+
image_url_cache_key: str | None = None
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
class PurchaseApproval(CasaModel):
|
|
20
|
+
id: str | None = None
|
|
21
|
+
home_id: str | None = None
|
|
22
|
+
title: str | None = None
|
|
23
|
+
image_url: str | None = None
|
|
24
|
+
image_cache_key: str | None = None
|
|
25
|
+
vendor: PurchaseVendor | None = None
|
|
26
|
+
unit_price_usd_cents: int | None = None
|
|
27
|
+
max_approved_unit_price_usd_cents: int | None = None
|
|
28
|
+
quantity: int | None = None
|
|
29
|
+
estimated_shipping_price_usd_cents: int | None = None
|
|
30
|
+
estimated_return_window_days: int | None = None
|
|
31
|
+
return_policy_notes: str | None = None
|
|
32
|
+
purchase_link: str | None = None
|
|
33
|
+
member_pricing_summary: JsonValue = None
|
|
34
|
+
updated_at: int | None = None
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
class ApprovedPurchase(PurchaseApproval):
|
|
38
|
+
item_id: str | None = None
|
|
39
|
+
approved_at: int | None = None
|
|
40
|
+
is_voided: bool | None = None
|
|
41
|
+
|
|
42
|
+
|
|
43
|
+
class PurchasedItem(CasaModel):
|
|
44
|
+
id: str | None = None
|
|
45
|
+
home_id: str | None = None
|
|
46
|
+
title: str | None = None
|
|
47
|
+
image_url: str | None = None
|
|
48
|
+
image_cache_key: str | None = None
|
|
49
|
+
vendor: PurchaseVendor | None = None
|
|
50
|
+
unit_price_usd_cents: int | None = None
|
|
51
|
+
return_policy_notes: str | None = None
|
|
52
|
+
purchase_link: str | None = None
|
|
53
|
+
updated_at: int | None = None
|
|
54
|
+
quantity: int | None = None
|
|
55
|
+
invoice_id: str | None = None
|
|
56
|
+
return_by_date: int | None = None
|
|
57
|
+
purchased_at: int | None = None
|
|
58
|
+
return_info: JsonValue = None
|
|
59
|
+
|
|
60
|
+
|
|
61
|
+
class PurchaseInvoice(CasaModel):
|
|
62
|
+
"""Minimal static SimpleInvoice fields. Non-purchase wire items unobserved."""
|
|
63
|
+
|
|
64
|
+
id: str | None = None
|
|
65
|
+
date: str | None = None
|
|
66
|
+
date_display: str | None = None
|
|
67
|
+
date_epoch_seconds: int | None = None
|
|
68
|
+
amount: float | None = None
|
|
69
|
+
vendor_name: str | None = None
|
|
70
|
+
status: str | None = None
|
|
71
|
+
type: str | None = None
|
|
72
|
+
member_payment: JsonValue = None
|
|
73
|
+
vendor_payment: JsonValue = None
|
|
74
|
+
|
|
75
|
+
|
|
76
|
+
class PurchasesResponse(CasaModel):
|
|
77
|
+
context_title: str | None = None
|
|
78
|
+
pending_purchase_approvals: list[PurchaseApproval]
|
|
79
|
+
approved_purchases: list[ApprovedPurchase]
|
|
80
|
+
purchased_items: list[PurchasedItem]
|
|
81
|
+
non_purchase_invoices: list[PurchaseInvoice]
|
|
82
|
+
next_package_pickup_by: int | None = None
|
|
83
|
+
|
|
84
|
+
|
|
85
|
+
class ScopedPurchasesResponse(CasaModel):
|
|
86
|
+
"""Provisional request/visit linkage to PurchasesResponse (static only).
|
|
87
|
+
|
|
88
|
+
Unlike the observed home response, the app model doesn't require
|
|
89
|
+
non_purchase_invoices. Unknown additions still survive as model_extra.
|
|
90
|
+
Scoped route envelopes and populated items remain UNVERIFIED.
|
|
91
|
+
"""
|
|
92
|
+
|
|
93
|
+
context_title: str | None = None
|
|
94
|
+
pending_purchase_approvals: list[PurchaseApproval]
|
|
95
|
+
approved_purchases: list[ApprovedPurchase]
|
|
96
|
+
purchased_items: list[PurchasedItem]
|
|
97
|
+
next_package_pickup_by: int | None = None
|
|
98
|
+
|
|
99
|
+
|
|
100
|
+
class RequestPurchase(CasaModel):
|
|
101
|
+
"""Static preview within visit detail."""
|
|
102
|
+
|
|
103
|
+
id: str
|
|
104
|
+
image_url: str | None = None
|
|
105
|
+
image_cache_key: str | None = None
|
|
106
|
+
status: str
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
"""Typed read envelopes without changing the existing create_todo return model."""
|
|
2
|
+
|
|
3
|
+
from pydantic import Field
|
|
4
|
+
|
|
5
|
+
from casahome.models._base import CasaModel
|
|
6
|
+
from casahome.models.images import MediaAttachment
|
|
7
|
+
from casahome.models.todos import TodoDetail
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
class TodoReadDetail(TodoDetail):
|
|
11
|
+
"""Populated core fields and attachments observed. Other nested fields static."""
|
|
12
|
+
|
|
13
|
+
flagged_for_support: bool = False
|
|
14
|
+
attachments: list[MediaAttachment] = Field(default_factory=list)
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
class TodoDetailsResponse(CasaModel):
|
|
18
|
+
todo: TodoReadDetail
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
class SuggestedTodosResponse(CasaModel):
|
|
22
|
+
suggested_todos: list[TodoReadDetail]
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
"""Member referral code, ``/protected/member/referral_code/v2``.
|
|
2
|
+
|
|
3
|
+
The envelope and top-level ``referral_code`` keys were VERIFIED by a live
|
|
4
|
+
GET (2026-10). Display keys and referred-home item shapes aren't pinned, so
|
|
5
|
+
they stay ``JsonValue``. Unknown fields ride along in ``model_extra``.
|
|
6
|
+
"""
|
|
7
|
+
|
|
8
|
+
from pydantic import JsonValue
|
|
9
|
+
|
|
10
|
+
from casahome.models._base import CasaModel
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
class ReferralCode(CasaModel):
|
|
14
|
+
code: str
|
|
15
|
+
referral_url: str
|
|
16
|
+
display: dict[str, JsonValue]
|
|
17
|
+
referred_homes: list[JsonValue]
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
class ReferralCodeResponse(CasaModel):
|
|
21
|
+
referral_code: ReferralCode
|
|
@@ -0,0 +1,149 @@
|
|
|
1
|
+
"""Requests tab, request threads, and vendor visit models (UNVERIFIED endpoints)."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
from datetime import datetime
|
|
6
|
+
from typing import Any
|
|
7
|
+
|
|
8
|
+
from pydantic import Field
|
|
9
|
+
|
|
10
|
+
from ._base import CasaModel, epoch_to_dt
|
|
11
|
+
from .enums import (
|
|
12
|
+
RequestStatusField,
|
|
13
|
+
RequestTypeField,
|
|
14
|
+
SenderRoleField,
|
|
15
|
+
VendorVisitStatusField,
|
|
16
|
+
VisitTypeField,
|
|
17
|
+
)
|
|
18
|
+
from .todos import TodoLaneCard
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
class Pagination(CasaModel):
|
|
22
|
+
page: int
|
|
23
|
+
page_size: int
|
|
24
|
+
total_count: int
|
|
25
|
+
total_pages: int
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
class RequestCard(CasaModel):
|
|
29
|
+
id: str
|
|
30
|
+
type: RequestTypeField
|
|
31
|
+
title: str
|
|
32
|
+
emoji: str
|
|
33
|
+
updated_at: int
|
|
34
|
+
latest_message_preview: str | None = None
|
|
35
|
+
has_unread_messages: bool = False
|
|
36
|
+
pending_invoice_count: int = 0
|
|
37
|
+
pending_purchase_count: int = 0
|
|
38
|
+
pending_schedule_prompt_count: int = 0
|
|
39
|
+
concierge_awaiting_reply: bool = False
|
|
40
|
+
vendor_visits: list[Any] = Field(default_factory=list)
|
|
41
|
+
|
|
42
|
+
@property
|
|
43
|
+
def updated_at_dt(self) -> datetime | None:
|
|
44
|
+
return epoch_to_dt(self.updated_at)
|
|
45
|
+
|
|
46
|
+
|
|
47
|
+
class RequestsSectionPresentation(CasaModel):
|
|
48
|
+
title: str
|
|
49
|
+
symbol: str | None = None
|
|
50
|
+
|
|
51
|
+
|
|
52
|
+
class RequestsLaneSection(CasaModel):
|
|
53
|
+
name: str
|
|
54
|
+
title: str
|
|
55
|
+
symbol: str | None = None
|
|
56
|
+
count: int | None = None
|
|
57
|
+
items: list[RequestCard] = Field(default_factory=list)
|
|
58
|
+
|
|
59
|
+
|
|
60
|
+
class RequestsLane(CasaModel):
|
|
61
|
+
needs_review: list[RequestCard] = Field(default_factory=list)
|
|
62
|
+
completed: RequestsSectionPresentation | None = None
|
|
63
|
+
completed_count: int = 0
|
|
64
|
+
sections: list[RequestsLaneSection] = Field(default_factory=list)
|
|
65
|
+
|
|
66
|
+
|
|
67
|
+
class TasksLaneSection(CasaModel):
|
|
68
|
+
name: str
|
|
69
|
+
title: str
|
|
70
|
+
symbol: str | None = None
|
|
71
|
+
count: int | None = None
|
|
72
|
+
items: list[Any] = Field(default_factory=list) # TaskCard, not yet modeled
|
|
73
|
+
|
|
74
|
+
|
|
75
|
+
class TasksLane(CasaModel):
|
|
76
|
+
sections: list[TasksLaneSection] = Field(default_factory=list)
|
|
77
|
+
|
|
78
|
+
|
|
79
|
+
class TodosLaneSection(CasaModel):
|
|
80
|
+
name: str
|
|
81
|
+
title: str
|
|
82
|
+
items: list[TodoLaneCard] = Field(default_factory=list)
|
|
83
|
+
order_revision: int | None = None
|
|
84
|
+
|
|
85
|
+
|
|
86
|
+
class TodosLane(CasaModel):
|
|
87
|
+
sections: list[TodosLaneSection] = Field(default_factory=list)
|
|
88
|
+
|
|
89
|
+
|
|
90
|
+
class RequestsResponse(CasaModel):
|
|
91
|
+
requests: RequestsLane
|
|
92
|
+
tasks: TasksLane
|
|
93
|
+
todos: TodosLane | None = None
|
|
94
|
+
|
|
95
|
+
|
|
96
|
+
class RequestMessage(CasaModel):
|
|
97
|
+
id: str
|
|
98
|
+
created_at: int
|
|
99
|
+
sender_role: SenderRoleField
|
|
100
|
+
sender_name: str
|
|
101
|
+
content: str | None = None
|
|
102
|
+
attachments: list[Any] = Field(default_factory=list)
|
|
103
|
+
scheduling_prompt: Any | None = None
|
|
104
|
+
availability_request: Any | None = None
|
|
105
|
+
invoice: Any | None = None
|
|
106
|
+
purchase_approval_requests: list[Any] | None = None
|
|
107
|
+
|
|
108
|
+
@property
|
|
109
|
+
def created_at_dt(self) -> datetime | None:
|
|
110
|
+
return epoch_to_dt(self.created_at)
|
|
111
|
+
|
|
112
|
+
|
|
113
|
+
class RequestDetails(CasaModel):
|
|
114
|
+
id: str
|
|
115
|
+
type: RequestTypeField
|
|
116
|
+
status: RequestStatusField
|
|
117
|
+
title: str
|
|
118
|
+
emoji: str
|
|
119
|
+
created_at: int
|
|
120
|
+
updated_at: int
|
|
121
|
+
has_unread_messages: bool = False
|
|
122
|
+
summary: dict[str, Any] = Field(default_factory=dict)
|
|
123
|
+
messages: list[RequestMessage] = Field(default_factory=list)
|
|
124
|
+
visits: list[Any] = Field(default_factory=list)
|
|
125
|
+
invoices: list[Any] = Field(default_factory=list)
|
|
126
|
+
purchases: list[Any] = Field(default_factory=list)
|
|
127
|
+
feedback: Any | None = None
|
|
128
|
+
|
|
129
|
+
|
|
130
|
+
class VendorVisitCalendarEvent(CasaModel):
|
|
131
|
+
id: str
|
|
132
|
+
start_time: int
|
|
133
|
+
end_time: int
|
|
134
|
+
|
|
135
|
+
|
|
136
|
+
class VendorVisit(CasaModel):
|
|
137
|
+
id: str
|
|
138
|
+
type: VisitTypeField
|
|
139
|
+
status: VendorVisitStatusField
|
|
140
|
+
request: dict[str, Any] = Field(default_factory=dict)
|
|
141
|
+
calendar_event: VendorVisitCalendarEvent | None = None
|
|
142
|
+
vendors: list[Any] = Field(default_factory=list)
|
|
143
|
+
task_items: list[Any] = Field(default_factory=list)
|
|
144
|
+
invoices: list[Any] = Field(default_factory=list)
|
|
145
|
+
purchases: list[Any] = Field(default_factory=list)
|
|
146
|
+
can_add_remove_items: bool = False
|
|
147
|
+
can_cancel: bool = False
|
|
148
|
+
feedback: Any | None = None
|
|
149
|
+
conversation: Any | None = None
|
casahome/models/tasks.py
ADDED
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
"""Static task detail and grouped visit-plan fields remain UNVERIFIED.
|
|
2
|
+
|
|
3
|
+
Fields inferred from the app. GroupedTaskDetails.tasks uses GroupedTaskItem.
|
|
4
|
+
Bookable's envelope was observed live, but tagged items remain JsonValue.
|
|
5
|
+
Swift case names aren't wire tags.
|
|
6
|
+
"""
|
|
7
|
+
|
|
8
|
+
from pydantic import JsonValue
|
|
9
|
+
|
|
10
|
+
from casahome.models._base import CasaModel
|
|
11
|
+
from casahome.models.images import MediaAttachment
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
class BookableHandymanTasksResponse(CasaModel):
|
|
15
|
+
items: list[JsonValue]
|
|
16
|
+
current_vendor_additional_availability_minutes: int | None = None
|
|
17
|
+
total_additional_availability_minutes: int | None = None
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
class TaskDetailsVisit(CasaModel):
|
|
21
|
+
id: str
|
|
22
|
+
start_time: int
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
class TaskUpdate(CasaModel):
|
|
26
|
+
id: str
|
|
27
|
+
message: str
|
|
28
|
+
sender_name: str
|
|
29
|
+
sender_avatar_url: str | None = None
|
|
30
|
+
sender_avatar_cache_key: str | None = None
|
|
31
|
+
sent_at: int
|
|
32
|
+
attachments: list[MediaAttachment] | None = None
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
class TaskDetails(CasaModel):
|
|
36
|
+
id: str
|
|
37
|
+
title: str
|
|
38
|
+
description: str
|
|
39
|
+
emoji: str
|
|
40
|
+
status: str
|
|
41
|
+
visit: TaskDetailsVisit | None = None
|
|
42
|
+
updates: list[TaskUpdate]
|
|
43
|
+
attachments: list[MediaAttachment] | None = None
|
|
44
|
+
can_schedule_handyman_vendor_visit: bool
|
|
45
|
+
can_chat_with_concierge: bool
|
|
46
|
+
can_edit: bool
|
|
47
|
+
can_delete: bool
|
|
48
|
+
|
|
49
|
+
|
|
50
|
+
class VendorVisitAutopilotPlan(CasaModel):
|
|
51
|
+
id: str
|
|
52
|
+
title: str
|
|
53
|
+
description: str
|
|
54
|
+
emoji: str
|
|
55
|
+
|
|
56
|
+
|
|
57
|
+
class VendorVisitAutopilotTaskTarget(CasaModel):
|
|
58
|
+
id: str
|
|
59
|
+
kind: str
|
|
60
|
+
primary_label: str
|
|
61
|
+
secondary_label: str
|
|
62
|
+
symbol_name: str
|
|
63
|
+
image_url: str | None = None
|
|
64
|
+
image_cache_key: str | None = None
|
|
65
|
+
|
|
66
|
+
|
|
67
|
+
class GroupedTaskItem(CasaModel):
|
|
68
|
+
id: str
|
|
69
|
+
status: str
|
|
70
|
+
target: VendorVisitAutopilotTaskTarget | None = None
|
|
71
|
+
updates: list[TaskUpdate]
|
|
72
|
+
|
|
73
|
+
|
|
74
|
+
class GroupedTaskDetails(CasaModel):
|
|
75
|
+
plan: VendorVisitAutopilotPlan
|
|
76
|
+
visit: TaskDetailsVisit | None = None
|
|
77
|
+
tasks: list[GroupedTaskItem]
|
casahome/models/taxes.py
ADDED
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
"""Property tax reads. Only refresh metadata and an empty reports list observed."""
|
|
2
|
+
|
|
3
|
+
from pydantic import Field
|
|
4
|
+
|
|
5
|
+
from casahome.models._base import CasaModel
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
class PropertyTaxRefresh(CasaModel):
|
|
9
|
+
status: str
|
|
10
|
+
next_fetch_at: int | None = None
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
class PropertyTaxSpecialAssessment(CasaModel):
|
|
14
|
+
id: str | None = None
|
|
15
|
+
name: str | None = None
|
|
16
|
+
amount: float | None = None
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
class PropertyTaxInstallment(CasaModel):
|
|
20
|
+
id: str | None = None
|
|
21
|
+
total: float | None = None
|
|
22
|
+
due_date: int | None = None
|
|
23
|
+
payment_amount: float | None = None
|
|
24
|
+
payment_date: int | None = None
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
class PropertyTaxReport(CasaModel):
|
|
28
|
+
id: str | None = None
|
|
29
|
+
report_id: str | None = None
|
|
30
|
+
issued_at: int | None = None
|
|
31
|
+
agency_name: str | None = None
|
|
32
|
+
tax_collector_url: str | None = None
|
|
33
|
+
tax_year_start: int | None = None
|
|
34
|
+
tax_year_end: int | None = None
|
|
35
|
+
land_value: float | None = None
|
|
36
|
+
improvement_value: float | None = None
|
|
37
|
+
total_assessed_value: float | None = None
|
|
38
|
+
total_taxable_value: float | None = None
|
|
39
|
+
total_tax_due: float | None = None
|
|
40
|
+
special_assessments: list[PropertyTaxSpecialAssessment] = Field(default_factory=list)
|
|
41
|
+
installments: list[PropertyTaxInstallment] = Field(default_factory=list)
|
|
42
|
+
|
|
43
|
+
|
|
44
|
+
class PropertyTaxesResponse(CasaModel):
|
|
45
|
+
next_tax_bill_release_at: int | None = None
|
|
46
|
+
refresh: PropertyTaxRefresh | None = None
|
|
47
|
+
reports: list[PropertyTaxReport]
|
casahome/models/todos.py
ADDED
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
"""To-do models (UNVERIFIED endpoints)."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
from typing import Any
|
|
6
|
+
|
|
7
|
+
from pydantic import Field
|
|
8
|
+
|
|
9
|
+
from ._base import CasaModel
|
|
10
|
+
from .enums import (
|
|
11
|
+
TodoCreatorRoleField,
|
|
12
|
+
TodoLaneCardKindField,
|
|
13
|
+
TodoLaneCardStateField,
|
|
14
|
+
TodoStatusField,
|
|
15
|
+
)
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
class AttachMediaPayload(CasaModel):
|
|
19
|
+
upload_ids: list[str] = Field(default_factory=list)
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
class CreateTodoBody(CasaModel):
|
|
23
|
+
content: str
|
|
24
|
+
attachments: AttachMediaPayload | None = None
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
class TodoLaneCard(CasaModel):
|
|
28
|
+
kind: TodoLaneCardKindField
|
|
29
|
+
id: str
|
|
30
|
+
title: str
|
|
31
|
+
emoji: str
|
|
32
|
+
updated_at: int
|
|
33
|
+
state: TodoLaneCardStateField
|
|
34
|
+
origin_todo_id: str | None = None
|
|
35
|
+
can_delete: bool = False
|
|
36
|
+
|
|
37
|
+
|
|
38
|
+
class TodoDetail(CasaModel):
|
|
39
|
+
id: str
|
|
40
|
+
title: str
|
|
41
|
+
emoji: str
|
|
42
|
+
original_text: str
|
|
43
|
+
prepared_brief: str
|
|
44
|
+
status: TodoStatusField
|
|
45
|
+
creator_role: TodoCreatorRoleField
|
|
46
|
+
created_at: int
|
|
47
|
+
updated_at: int
|
|
48
|
+
can_delete: bool = False
|
|
49
|
+
is_suggested: bool = False
|
|
50
|
+
attachments: list[Any] = Field(default_factory=list)
|
|
51
|
+
question_rounds: list[Any] = Field(default_factory=list)
|
|
52
|
+
destination: Any | None = None
|