tallyfy 1.0.16__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.
- tallyfy/__init__.py +27 -0
- tallyfy/__pycache__/__init__.cpython-310.pyc +0 -0
- tallyfy/__pycache__/core.cpython-310.pyc +0 -0
- tallyfy/__pycache__/form_fields_management.cpython-310.pyc +0 -0
- tallyfy/__pycache__/models.cpython-310.pyc +0 -0
- tallyfy/__pycache__/task_management.cpython-310.pyc +0 -0
- tallyfy/__pycache__/template_management.cpython-310.pyc +0 -0
- tallyfy/__pycache__/user_management.cpython-310.pyc +0 -0
- tallyfy/core.py +361 -0
- tallyfy/form_fields_management/__init__.py +70 -0
- tallyfy/form_fields_management/__pycache__/__init__.cpython-310.pyc +0 -0
- tallyfy/form_fields_management/__pycache__/base.cpython-310.pyc +0 -0
- tallyfy/form_fields_management/__pycache__/crud_operations.cpython-310.pyc +0 -0
- tallyfy/form_fields_management/__pycache__/options_management.cpython-310.pyc +0 -0
- tallyfy/form_fields_management/__pycache__/suggestions.cpython-310.pyc +0 -0
- tallyfy/form_fields_management/base.py +109 -0
- tallyfy/form_fields_management/crud_operations.py +234 -0
- tallyfy/form_fields_management/options_management.py +222 -0
- tallyfy/form_fields_management/suggestions.py +411 -0
- tallyfy/models.py +1464 -0
- tallyfy/organization_management/__init__.py +26 -0
- tallyfy/organization_management/base.py +76 -0
- tallyfy/organization_management/retrieval.py +39 -0
- tallyfy/task_management/__init__.py +81 -0
- tallyfy/task_management/__pycache__/__init__.cpython-310.pyc +0 -0
- tallyfy/task_management/__pycache__/base.cpython-310.pyc +0 -0
- tallyfy/task_management/__pycache__/creation.cpython-310.pyc +0 -0
- tallyfy/task_management/__pycache__/retrieval.cpython-310.pyc +0 -0
- tallyfy/task_management/__pycache__/search.cpython-310.pyc +0 -0
- tallyfy/task_management/base.py +125 -0
- tallyfy/task_management/creation.py +221 -0
- tallyfy/task_management/retrieval.py +252 -0
- tallyfy/task_management/search.py +198 -0
- tallyfy/template_management/__init__.py +85 -0
- tallyfy/template_management/analysis.py +1099 -0
- tallyfy/template_management/automation.py +469 -0
- tallyfy/template_management/base.py +56 -0
- tallyfy/template_management/basic_operations.py +479 -0
- tallyfy/template_management/health_assessment.py +793 -0
- tallyfy/user_management/__init__.py +70 -0
- tallyfy/user_management/__pycache__/__init__.cpython-310.pyc +0 -0
- tallyfy/user_management/__pycache__/base.cpython-310.pyc +0 -0
- tallyfy/user_management/__pycache__/invitation.cpython-310.pyc +0 -0
- tallyfy/user_management/__pycache__/retrieval.cpython-310.pyc +0 -0
- tallyfy/user_management/base.py +146 -0
- tallyfy/user_management/invitation.py +286 -0
- tallyfy/user_management/retrieval.py +381 -0
- tallyfy-1.0.16.dist-info/METADATA +742 -0
- tallyfy-1.0.16.dist-info/RECORD +52 -0
- tallyfy-1.0.16.dist-info/WHEEL +5 -0
- tallyfy-1.0.16.dist-info/licenses/LICENSE +21 -0
- tallyfy-1.0.16.dist-info/top_level.txt +1 -0
|
@@ -0,0 +1,234 @@
|
|
|
1
|
+
"""
|
|
2
|
+
CRUD operations for form field management
|
|
3
|
+
"""
|
|
4
|
+
|
|
5
|
+
from typing import Dict, Any, Optional
|
|
6
|
+
from .base import FormFieldManagerBase
|
|
7
|
+
from ..models import Capture, Step, TallyfyError
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
class FormFieldCRUD(FormFieldManagerBase):
|
|
11
|
+
"""Handles basic CRUD operations for form fields"""
|
|
12
|
+
|
|
13
|
+
def add_form_field_to_step(self, org_id: str, template_id: str, step_id: str, field_data: Dict[str, Any]) -> Optional[Capture]:
|
|
14
|
+
"""
|
|
15
|
+
Add form fields (text, dropdown, date, etc.) to a step.
|
|
16
|
+
|
|
17
|
+
Args:
|
|
18
|
+
org_id: Organization ID
|
|
19
|
+
template_id: Template ID
|
|
20
|
+
step_id: Step ID
|
|
21
|
+
field_data: Form field creation data including field_type, label, required, etc.
|
|
22
|
+
|
|
23
|
+
Returns:
|
|
24
|
+
Created Capture object or None if creation failed
|
|
25
|
+
|
|
26
|
+
Raises:
|
|
27
|
+
TallyfyError: If the request fails
|
|
28
|
+
"""
|
|
29
|
+
self._validate_org_id(org_id)
|
|
30
|
+
self._validate_template_id(template_id)
|
|
31
|
+
self._validate_step_id(step_id)
|
|
32
|
+
|
|
33
|
+
try:
|
|
34
|
+
endpoint = f"organizations/{org_id}/checklists/{template_id}/steps/{step_id}/captures"
|
|
35
|
+
|
|
36
|
+
# Validate required fields
|
|
37
|
+
required_fields = ['field_type', 'label']
|
|
38
|
+
for field in required_fields:
|
|
39
|
+
if field not in field_data:
|
|
40
|
+
raise ValueError(f"Missing required field: {field}")
|
|
41
|
+
|
|
42
|
+
# Set defaults for optional fields
|
|
43
|
+
capture_data = {
|
|
44
|
+
'field_type': field_data['field_type'],
|
|
45
|
+
'label': field_data['label'],
|
|
46
|
+
'required': field_data.get('required', True),
|
|
47
|
+
'position': field_data.get('position', 1)
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
# Add optional fields if provided
|
|
51
|
+
optional_fields = ['guidance', 'options', 'default_value', 'default_value_enabled']
|
|
52
|
+
for field in optional_fields:
|
|
53
|
+
if field in field_data:
|
|
54
|
+
capture_data[field] = field_data[field]
|
|
55
|
+
|
|
56
|
+
response_data = self.sdk._make_request('POST', endpoint, data=capture_data)
|
|
57
|
+
|
|
58
|
+
extracted_data = self._extract_data(response_data)
|
|
59
|
+
if extracted_data:
|
|
60
|
+
return Capture.from_dict(extracted_data)
|
|
61
|
+
else:
|
|
62
|
+
self.sdk.logger.warning("Unexpected response format for form field creation")
|
|
63
|
+
return None
|
|
64
|
+
|
|
65
|
+
except TallyfyError:
|
|
66
|
+
raise
|
|
67
|
+
except Exception as e:
|
|
68
|
+
self._handle_api_error(e, "add form field to step", org_id=org_id, template_id=template_id, step_id=step_id)
|
|
69
|
+
|
|
70
|
+
def update_form_field(self, org_id: str, template_id: str, step_id: str, field_id: str, **kwargs) -> Optional[Capture]:
|
|
71
|
+
"""
|
|
72
|
+
Update form field properties, validation, options.
|
|
73
|
+
|
|
74
|
+
Args:
|
|
75
|
+
org_id: Organization ID
|
|
76
|
+
template_id: Template ID
|
|
77
|
+
step_id: Step ID
|
|
78
|
+
field_id: Form field ID
|
|
79
|
+
**kwargs: Form field properties to update
|
|
80
|
+
|
|
81
|
+
Returns:
|
|
82
|
+
Updated Capture object or None if update failed
|
|
83
|
+
|
|
84
|
+
Raises:
|
|
85
|
+
TallyfyError: If the request fails
|
|
86
|
+
"""
|
|
87
|
+
self._validate_org_id(org_id)
|
|
88
|
+
self._validate_template_id(template_id)
|
|
89
|
+
self._validate_step_id(step_id)
|
|
90
|
+
self._validate_field_id(field_id)
|
|
91
|
+
|
|
92
|
+
try:
|
|
93
|
+
endpoint = f"organizations/{org_id}/checklists/{template_id}/steps/{step_id}/captures/{field_id}"
|
|
94
|
+
|
|
95
|
+
# Build update data from kwargs
|
|
96
|
+
update_data = {}
|
|
97
|
+
allowed_fields = [
|
|
98
|
+
'field_type', 'label', 'guidance', 'position', 'required',
|
|
99
|
+
'options', 'default_value', 'default_value_enabled'
|
|
100
|
+
]
|
|
101
|
+
|
|
102
|
+
for field, value in kwargs.items():
|
|
103
|
+
if field in allowed_fields:
|
|
104
|
+
update_data[field] = value
|
|
105
|
+
else:
|
|
106
|
+
self.sdk.logger.warning(f"Ignoring unknown form field: {field}")
|
|
107
|
+
|
|
108
|
+
if not update_data:
|
|
109
|
+
raise ValueError("No valid form field properties provided for update")
|
|
110
|
+
|
|
111
|
+
response_data = self.sdk._make_request('PUT', endpoint, data=update_data)
|
|
112
|
+
|
|
113
|
+
extracted_data = self._extract_data(response_data)
|
|
114
|
+
if extracted_data:
|
|
115
|
+
return Capture.from_dict(extracted_data)
|
|
116
|
+
else:
|
|
117
|
+
self.sdk.logger.warning("Unexpected response format for form field update")
|
|
118
|
+
return None
|
|
119
|
+
|
|
120
|
+
except TallyfyError:
|
|
121
|
+
raise
|
|
122
|
+
except Exception as e:
|
|
123
|
+
self._handle_api_error(e, "update form field", org_id=org_id, template_id=template_id, step_id=step_id, field_id=field_id)
|
|
124
|
+
|
|
125
|
+
def move_form_field(self, org_id: str, template_id: str, from_step: str, field_id: str, to_step: str, position: int = 1) -> bool:
|
|
126
|
+
"""
|
|
127
|
+
Move form field between steps.
|
|
128
|
+
|
|
129
|
+
Args:
|
|
130
|
+
org_id: Organization ID
|
|
131
|
+
template_id: Template ID
|
|
132
|
+
from_step: Source step ID
|
|
133
|
+
field_id: Form field ID to move
|
|
134
|
+
to_step: Target step ID
|
|
135
|
+
position: Position in target step (default: 1)
|
|
136
|
+
|
|
137
|
+
Returns:
|
|
138
|
+
True if move was successful
|
|
139
|
+
|
|
140
|
+
Raises:
|
|
141
|
+
TallyfyError: If the request fails
|
|
142
|
+
"""
|
|
143
|
+
self._validate_org_id(org_id)
|
|
144
|
+
self._validate_template_id(template_id)
|
|
145
|
+
self._validate_step_id(from_step)
|
|
146
|
+
self._validate_field_id(field_id)
|
|
147
|
+
self._validate_step_id(to_step)
|
|
148
|
+
|
|
149
|
+
try:
|
|
150
|
+
endpoint = f"organizations/{org_id}/checklists/{template_id}/steps/{from_step}/captures/{field_id}/move"
|
|
151
|
+
|
|
152
|
+
move_data = {
|
|
153
|
+
'to_step_id': to_step,
|
|
154
|
+
'position': position
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
response_data = self.sdk._make_request('POST', endpoint, data=move_data)
|
|
158
|
+
|
|
159
|
+
# Check if move was successful
|
|
160
|
+
return isinstance(response_data, dict) and response_data.get('success', False)
|
|
161
|
+
|
|
162
|
+
except TallyfyError:
|
|
163
|
+
raise
|
|
164
|
+
except Exception as e:
|
|
165
|
+
self._handle_api_error(e, "move form field", org_id=org_id, template_id=template_id, from_step=from_step, field_id=field_id, to_step=to_step)
|
|
166
|
+
|
|
167
|
+
def delete_form_field(self, org_id: str, template_id: str, step_id: str, field_id: str) -> bool:
|
|
168
|
+
"""
|
|
169
|
+
Delete a form field from a step.
|
|
170
|
+
|
|
171
|
+
Args:
|
|
172
|
+
org_id: Organization ID
|
|
173
|
+
template_id: Template ID
|
|
174
|
+
step_id: Step ID
|
|
175
|
+
field_id: Form field ID
|
|
176
|
+
|
|
177
|
+
Returns:
|
|
178
|
+
True if deletion was successful
|
|
179
|
+
|
|
180
|
+
Raises:
|
|
181
|
+
TallyfyError: If the request fails
|
|
182
|
+
"""
|
|
183
|
+
self._validate_org_id(org_id)
|
|
184
|
+
self._validate_template_id(template_id)
|
|
185
|
+
self._validate_step_id(step_id)
|
|
186
|
+
self._validate_field_id(field_id)
|
|
187
|
+
|
|
188
|
+
try:
|
|
189
|
+
endpoint = f"organizations/{org_id}/checklists/{template_id}/steps/{step_id}/captures/{field_id}"
|
|
190
|
+
|
|
191
|
+
response_data = self.sdk._make_request('DELETE', endpoint)
|
|
192
|
+
|
|
193
|
+
# Check if deletion was successful
|
|
194
|
+
return isinstance(response_data, dict) and response_data.get('success', False)
|
|
195
|
+
|
|
196
|
+
except TallyfyError:
|
|
197
|
+
raise
|
|
198
|
+
except Exception as e:
|
|
199
|
+
self._handle_api_error(e, "delete form field", org_id=org_id, template_id=template_id, step_id=step_id, field_id=field_id)
|
|
200
|
+
|
|
201
|
+
def get_step(self, org_id: str, template_id: str, step_id: str) -> Optional[Step]:
|
|
202
|
+
"""
|
|
203
|
+
Get a specific step with its details.
|
|
204
|
+
|
|
205
|
+
Args:
|
|
206
|
+
org_id: Organization ID
|
|
207
|
+
template_id: Template ID
|
|
208
|
+
step_id: Step ID
|
|
209
|
+
|
|
210
|
+
Returns:
|
|
211
|
+
Step object or None if not found
|
|
212
|
+
|
|
213
|
+
Raises:
|
|
214
|
+
TallyfyError: If the request fails
|
|
215
|
+
"""
|
|
216
|
+
self._validate_org_id(org_id)
|
|
217
|
+
self._validate_template_id(template_id)
|
|
218
|
+
self._validate_step_id(step_id)
|
|
219
|
+
|
|
220
|
+
try:
|
|
221
|
+
endpoint = f"organizations/{org_id}/checklists/{template_id}/steps/{step_id}"
|
|
222
|
+
response_data = self.sdk._make_request('GET', endpoint)
|
|
223
|
+
|
|
224
|
+
extracted_data = self._extract_data(response_data)
|
|
225
|
+
if extracted_data:
|
|
226
|
+
return Step.from_dict(extracted_data)
|
|
227
|
+
else:
|
|
228
|
+
self.sdk.logger.warning("Unexpected response format for step")
|
|
229
|
+
return None
|
|
230
|
+
|
|
231
|
+
except TallyfyError:
|
|
232
|
+
raise
|
|
233
|
+
except Exception as e:
|
|
234
|
+
self._handle_api_error(e, "get step", org_id=org_id, template_id=template_id, step_id=step_id)
|
|
@@ -0,0 +1,222 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Dropdown options management for form fields
|
|
3
|
+
"""
|
|
4
|
+
|
|
5
|
+
from typing import List, Dict, Any, Optional
|
|
6
|
+
from .base import FormFieldManagerBase
|
|
7
|
+
from ..models import TallyfyError
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
class FormFieldOptions(FormFieldManagerBase):
|
|
11
|
+
"""Handles dropdown options management for form fields"""
|
|
12
|
+
|
|
13
|
+
def get_dropdown_options(self, org_id: str, template_id: str, step_id: str, field_id: str) -> List[str]:
|
|
14
|
+
"""
|
|
15
|
+
Get current dropdown options for analysis.
|
|
16
|
+
|
|
17
|
+
Args:
|
|
18
|
+
org_id: Organization ID
|
|
19
|
+
template_id: Template ID
|
|
20
|
+
step_id: Step ID
|
|
21
|
+
field_id: Form field ID
|
|
22
|
+
|
|
23
|
+
Returns:
|
|
24
|
+
List of dropdown option strings
|
|
25
|
+
|
|
26
|
+
Raises:
|
|
27
|
+
TallyfyError: If the request fails
|
|
28
|
+
"""
|
|
29
|
+
self._validate_org_id(org_id)
|
|
30
|
+
self._validate_template_id(template_id)
|
|
31
|
+
self._validate_step_id(step_id)
|
|
32
|
+
self._validate_field_id(field_id)
|
|
33
|
+
|
|
34
|
+
try:
|
|
35
|
+
endpoint = f"organizations/{org_id}/checklists/{template_id}/steps/{step_id}/captures/{field_id}"
|
|
36
|
+
|
|
37
|
+
response_data = self.sdk._make_request('GET', endpoint)
|
|
38
|
+
|
|
39
|
+
extracted_data = self._extract_data(response_data)
|
|
40
|
+
if extracted_data:
|
|
41
|
+
options = extracted_data.get('options', [])
|
|
42
|
+
|
|
43
|
+
# Extract option values/labels
|
|
44
|
+
if isinstance(options, list):
|
|
45
|
+
return [
|
|
46
|
+
opt.get('label', opt.get('value', str(opt))) if isinstance(opt, dict) else str(opt)
|
|
47
|
+
for opt in options
|
|
48
|
+
]
|
|
49
|
+
else:
|
|
50
|
+
return []
|
|
51
|
+
else:
|
|
52
|
+
self.sdk.logger.warning("Unexpected response format for form field options")
|
|
53
|
+
return []
|
|
54
|
+
|
|
55
|
+
except TallyfyError:
|
|
56
|
+
raise
|
|
57
|
+
except Exception as e:
|
|
58
|
+
self._handle_api_error(e, "get dropdown options", org_id=org_id, template_id=template_id, step_id=step_id, field_id=field_id)
|
|
59
|
+
|
|
60
|
+
def update_dropdown_options(self, org_id: str, template_id: str, step_id: str, field_id: str, options: List[str]) -> bool:
|
|
61
|
+
"""
|
|
62
|
+
Update dropdown options (for external data integration).
|
|
63
|
+
|
|
64
|
+
Args:
|
|
65
|
+
org_id: Organization ID
|
|
66
|
+
template_id: Template ID
|
|
67
|
+
step_id: Step ID
|
|
68
|
+
field_id: Form field ID
|
|
69
|
+
options: List of new option strings
|
|
70
|
+
|
|
71
|
+
Returns:
|
|
72
|
+
True if update was successful
|
|
73
|
+
|
|
74
|
+
Raises:
|
|
75
|
+
TallyfyError: If the request fails
|
|
76
|
+
"""
|
|
77
|
+
self._validate_org_id(org_id)
|
|
78
|
+
self._validate_template_id(template_id)
|
|
79
|
+
self._validate_step_id(step_id)
|
|
80
|
+
self._validate_field_id(field_id)
|
|
81
|
+
|
|
82
|
+
try:
|
|
83
|
+
# Format options for API
|
|
84
|
+
formatted_options = []
|
|
85
|
+
for i, option in enumerate(options):
|
|
86
|
+
if isinstance(option, str):
|
|
87
|
+
formatted_options.append({
|
|
88
|
+
'value': option.lower().replace(' ', '_'),
|
|
89
|
+
'label': option,
|
|
90
|
+
'position': i + 1
|
|
91
|
+
})
|
|
92
|
+
elif isinstance(option, dict):
|
|
93
|
+
formatted_options.append(option)
|
|
94
|
+
else:
|
|
95
|
+
formatted_options.append({
|
|
96
|
+
'value': str(option),
|
|
97
|
+
'label': str(option),
|
|
98
|
+
'position': i + 1
|
|
99
|
+
})
|
|
100
|
+
|
|
101
|
+
# Update the field with new options using CRUD operations
|
|
102
|
+
# We need to import FormFieldCRUD here to avoid circular imports
|
|
103
|
+
from .crud_operations import FormFieldCRUD
|
|
104
|
+
crud = FormFieldCRUD(self.sdk)
|
|
105
|
+
|
|
106
|
+
updated_capture = crud.update_form_field(
|
|
107
|
+
org_id, template_id, step_id, field_id,
|
|
108
|
+
options=formatted_options
|
|
109
|
+
)
|
|
110
|
+
|
|
111
|
+
return updated_capture is not None
|
|
112
|
+
|
|
113
|
+
except TallyfyError:
|
|
114
|
+
raise
|
|
115
|
+
except Exception as e:
|
|
116
|
+
self._handle_api_error(e, "update dropdown options", org_id=org_id, template_id=template_id, step_id=step_id, field_id=field_id)
|
|
117
|
+
|
|
118
|
+
def add_dropdown_option(self, org_id: str, template_id: str, step_id: str, field_id: str, new_option: str, position: Optional[int] = None) -> bool:
|
|
119
|
+
"""
|
|
120
|
+
Add a single new option to an existing dropdown field.
|
|
121
|
+
|
|
122
|
+
Args:
|
|
123
|
+
org_id: Organization ID
|
|
124
|
+
template_id: Template ID
|
|
125
|
+
step_id: Step ID
|
|
126
|
+
field_id: Form field ID
|
|
127
|
+
new_option: New option to add
|
|
128
|
+
position: Position to insert the option (None = append to end)
|
|
129
|
+
|
|
130
|
+
Returns:
|
|
131
|
+
True if addition was successful
|
|
132
|
+
|
|
133
|
+
Raises:
|
|
134
|
+
TallyfyError: If the request fails
|
|
135
|
+
"""
|
|
136
|
+
try:
|
|
137
|
+
# Get current options
|
|
138
|
+
current_options = self.get_dropdown_options(org_id, template_id, step_id, field_id)
|
|
139
|
+
|
|
140
|
+
# Add new option at specified position or end
|
|
141
|
+
if position is not None and 0 <= position <= len(current_options):
|
|
142
|
+
current_options.insert(position, new_option)
|
|
143
|
+
else:
|
|
144
|
+
current_options.append(new_option)
|
|
145
|
+
|
|
146
|
+
# Update with new options list
|
|
147
|
+
return self.update_dropdown_options(org_id, template_id, step_id, field_id, current_options)
|
|
148
|
+
|
|
149
|
+
except TallyfyError:
|
|
150
|
+
raise
|
|
151
|
+
except Exception as e:
|
|
152
|
+
self._handle_api_error(e, "add dropdown option", org_id=org_id, template_id=template_id, step_id=step_id, field_id=field_id)
|
|
153
|
+
|
|
154
|
+
def remove_dropdown_option(self, org_id: str, template_id: str, step_id: str, field_id: str, option_to_remove: str) -> bool:
|
|
155
|
+
"""
|
|
156
|
+
Remove a specific option from a dropdown field.
|
|
157
|
+
|
|
158
|
+
Args:
|
|
159
|
+
org_id: Organization ID
|
|
160
|
+
template_id: Template ID
|
|
161
|
+
step_id: Step ID
|
|
162
|
+
field_id: Form field ID
|
|
163
|
+
option_to_remove: Option to remove
|
|
164
|
+
|
|
165
|
+
Returns:
|
|
166
|
+
True if removal was successful
|
|
167
|
+
|
|
168
|
+
Raises:
|
|
169
|
+
TallyfyError: If the request fails
|
|
170
|
+
"""
|
|
171
|
+
try:
|
|
172
|
+
# Get current options
|
|
173
|
+
current_options = self.get_dropdown_options(org_id, template_id, step_id, field_id)
|
|
174
|
+
|
|
175
|
+
# Remove the specified option if it exists
|
|
176
|
+
if option_to_remove in current_options:
|
|
177
|
+
current_options.remove(option_to_remove)
|
|
178
|
+
|
|
179
|
+
# Update with modified options list
|
|
180
|
+
return self.update_dropdown_options(org_id, template_id, step_id, field_id, current_options)
|
|
181
|
+
else:
|
|
182
|
+
self.sdk.logger.warning(f"Option '{option_to_remove}' not found in dropdown field {field_id}")
|
|
183
|
+
return False
|
|
184
|
+
|
|
185
|
+
except TallyfyError:
|
|
186
|
+
raise
|
|
187
|
+
except Exception as e:
|
|
188
|
+
self._handle_api_error(e, "remove dropdown option", org_id=org_id, template_id=template_id, step_id=step_id, field_id=field_id)
|
|
189
|
+
|
|
190
|
+
def reorder_dropdown_options(self, org_id: str, template_id: str, step_id: str, field_id: str, ordered_options: List[str]) -> bool:
|
|
191
|
+
"""
|
|
192
|
+
Reorder dropdown options to match the provided list.
|
|
193
|
+
|
|
194
|
+
Args:
|
|
195
|
+
org_id: Organization ID
|
|
196
|
+
template_id: Template ID
|
|
197
|
+
step_id: Step ID
|
|
198
|
+
field_id: Form field ID
|
|
199
|
+
ordered_options: List of options in desired order
|
|
200
|
+
|
|
201
|
+
Returns:
|
|
202
|
+
True if reordering was successful
|
|
203
|
+
|
|
204
|
+
Raises:
|
|
205
|
+
TallyfyError: If the request fails
|
|
206
|
+
"""
|
|
207
|
+
try:
|
|
208
|
+
# Get current options to validate
|
|
209
|
+
current_options = self.get_dropdown_options(org_id, template_id, step_id, field_id)
|
|
210
|
+
|
|
211
|
+
# Validate that all provided options exist in current options
|
|
212
|
+
missing_options = set(ordered_options) - set(current_options)
|
|
213
|
+
if missing_options:
|
|
214
|
+
raise ValueError(f"Cannot reorder: options not found in field: {missing_options}")
|
|
215
|
+
|
|
216
|
+
# Update with reordered options
|
|
217
|
+
return self.update_dropdown_options(org_id, template_id, step_id, field_id, ordered_options)
|
|
218
|
+
|
|
219
|
+
except TallyfyError:
|
|
220
|
+
raise
|
|
221
|
+
except Exception as e:
|
|
222
|
+
self._handle_api_error(e, "reorder dropdown options", org_id=org_id, template_id=template_id, step_id=step_id, field_id=field_id)
|