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,252 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Task and process retrieval operations
|
|
3
|
+
"""
|
|
4
|
+
|
|
5
|
+
from typing import List, Optional
|
|
6
|
+
from .base import TaskManagerBase
|
|
7
|
+
from ..models import Task, Run, TasksList, RunsList, TallyfyError
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
class TaskRetrieval(TaskManagerBase):
|
|
11
|
+
"""Handles task and process retrieval operations"""
|
|
12
|
+
|
|
13
|
+
def get_my_tasks(self, org_id: str, page: int = 1, per_page: int = 100) -> TasksList:
|
|
14
|
+
"""
|
|
15
|
+
Get all tasks assigned to the current user in the organization.
|
|
16
|
+
|
|
17
|
+
Args:
|
|
18
|
+
org_id: Organization ID
|
|
19
|
+
page: Page number (default: 1)
|
|
20
|
+
per_page: Number of results per page (default: 100)
|
|
21
|
+
|
|
22
|
+
Returns:
|
|
23
|
+
TasksList object containing tasks and pagination metadata (total count, etc.)
|
|
24
|
+
|
|
25
|
+
Raises:
|
|
26
|
+
TallyfyError: If the request fails
|
|
27
|
+
"""
|
|
28
|
+
self._validate_org_id(org_id)
|
|
29
|
+
|
|
30
|
+
try:
|
|
31
|
+
endpoint = f"organizations/{org_id}/me/tasks"
|
|
32
|
+
params = self._build_query_params(page=page, per_page=per_page)
|
|
33
|
+
response_data = self.sdk._make_request('GET', endpoint, params=params)
|
|
34
|
+
|
|
35
|
+
# Return the structured response with pagination
|
|
36
|
+
return TasksList.from_dict(response_data)
|
|
37
|
+
|
|
38
|
+
except TallyfyError:
|
|
39
|
+
raise
|
|
40
|
+
except Exception as e:
|
|
41
|
+
self._handle_api_error(e, "get my tasks", org_id=org_id)
|
|
42
|
+
|
|
43
|
+
def get_user_tasks(self, org_id: str, user_id: int, page: int = 1, per_page: int = 100,
|
|
44
|
+
sort_by: str = 'newest', status: str = 'all') -> TasksList:
|
|
45
|
+
"""
|
|
46
|
+
Get all tasks assigned to the given user in the organization.
|
|
47
|
+
|
|
48
|
+
Args:
|
|
49
|
+
org_id: Organization ID
|
|
50
|
+
user_id: User ID
|
|
51
|
+
page: Page number (default: 1)
|
|
52
|
+
per_page: Number of results per page (default: 100)
|
|
53
|
+
sort_by: Sort order (default: 'newest')
|
|
54
|
+
status: Task status filter (default: 'all')
|
|
55
|
+
|
|
56
|
+
Returns:
|
|
57
|
+
TasksList object containing tasks and pagination metadata (total count, etc.)
|
|
58
|
+
|
|
59
|
+
Raises:
|
|
60
|
+
TallyfyError: If the request fails
|
|
61
|
+
"""
|
|
62
|
+
self._validate_org_id(org_id)
|
|
63
|
+
self._validate_user_id(user_id)
|
|
64
|
+
|
|
65
|
+
try:
|
|
66
|
+
endpoint = f"organizations/{org_id}/users/{user_id}/tasks"
|
|
67
|
+
params = {
|
|
68
|
+
'page': str(page),
|
|
69
|
+
'per_page': str(per_page),
|
|
70
|
+
'sort_by': sort_by,
|
|
71
|
+
'status': status,
|
|
72
|
+
'with': 'run,threads_count,step,tags,folders,member_watchers.watcher'
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
response_data = self.sdk._make_request('GET', endpoint, params=params)
|
|
76
|
+
|
|
77
|
+
# Return the structured response with pagination
|
|
78
|
+
return TasksList.from_dict(response_data)
|
|
79
|
+
|
|
80
|
+
except TallyfyError:
|
|
81
|
+
raise
|
|
82
|
+
except Exception as e:
|
|
83
|
+
self._handle_api_error(e, "get user tasks", org_id=org_id, user_id=user_id)
|
|
84
|
+
|
|
85
|
+
def get_tasks_for_process(self, org_id: str, process_id: Optional[str] = None, process_name: Optional[str] = None,
|
|
86
|
+
status: Optional[str] = None, sort: Optional[str] = None, with_: Optional[str] = None,
|
|
87
|
+
owners: Optional[str] = None, groups: Optional[str] = None, guests: Optional[str] = None,
|
|
88
|
+
page: int = 1, per_page: int = 100, current_task: Optional[str] = None,
|
|
89
|
+
replace_page: Optional[int] = None, without_pagination: str = "false",
|
|
90
|
+
deadline_start_range: Optional[str] = None, deadline_end_range: Optional[str] = None,
|
|
91
|
+
unassigned: Optional[bool] = None) -> TasksList:
|
|
92
|
+
"""
|
|
93
|
+
Get all tasks for a given process (run).
|
|
94
|
+
|
|
95
|
+
Args:
|
|
96
|
+
org_id: Organization ID
|
|
97
|
+
process_id: Process (run) ID to get tasks for
|
|
98
|
+
process_name: Process (run) name to get tasks for (alternative to process_id)
|
|
99
|
+
status: Filter by task status (complete, hasproblem, overdue, due_soon, active, active_visible, incomplete, inprogress, not-started)
|
|
100
|
+
sort: Sort by position or deadline (position, deadline, -position, -deadline)
|
|
101
|
+
with_: Additional data to retrieve (activities, run, run.checklist, step, form_fields, threads, comments, assets, summary)
|
|
102
|
+
owners: Search tasks assigned to specific members (comma-separated member IDs)
|
|
103
|
+
groups: Filter by Group ID
|
|
104
|
+
guests: Search tasks assigned to specific group (comma-separated group IDs)
|
|
105
|
+
page: Results page to retrieve (default: 1)
|
|
106
|
+
per_page: Tasks per page (default: 100)
|
|
107
|
+
current_task: Task ID
|
|
108
|
+
replace_page: Replace page
|
|
109
|
+
without_pagination: Results without pagination (true/false, default: false)
|
|
110
|
+
deadline_start_range: Deadline range starting date
|
|
111
|
+
deadline_end_range: Deadline range ending date
|
|
112
|
+
unassigned: Filter tasks with nobody assigned
|
|
113
|
+
|
|
114
|
+
Returns:
|
|
115
|
+
TasksList object containing tasks and pagination metadata (total count, etc.)
|
|
116
|
+
|
|
117
|
+
Raises:
|
|
118
|
+
TallyfyError: If the request fails
|
|
119
|
+
ValueError: If neither process_id nor process_name is provided
|
|
120
|
+
"""
|
|
121
|
+
self._validate_org_id(org_id)
|
|
122
|
+
|
|
123
|
+
if not process_id and not process_name:
|
|
124
|
+
raise ValueError("Either process_id or process_name must be provided")
|
|
125
|
+
|
|
126
|
+
try:
|
|
127
|
+
# If process_name is provided but not process_id, search for the process first
|
|
128
|
+
if process_name and not process_id:
|
|
129
|
+
# We need to import TaskSearch here to avoid circular imports
|
|
130
|
+
from .search import TaskSearch
|
|
131
|
+
search = TaskSearch(self.sdk)
|
|
132
|
+
process_id = search.search_processes_by_name(org_id, process_name)
|
|
133
|
+
|
|
134
|
+
self._validate_process_id(process_id)
|
|
135
|
+
|
|
136
|
+
endpoint = f"organizations/{org_id}/runs/{process_id}/tasks"
|
|
137
|
+
|
|
138
|
+
# Build parameters using base class helper
|
|
139
|
+
params = self._build_query_params(
|
|
140
|
+
status=status,
|
|
141
|
+
sort=sort,
|
|
142
|
+
owners=owners,
|
|
143
|
+
groups=groups,
|
|
144
|
+
guests=guests,
|
|
145
|
+
page=page,
|
|
146
|
+
per_page=per_page,
|
|
147
|
+
currentTask=current_task,
|
|
148
|
+
replace_page=replace_page,
|
|
149
|
+
without_pagination=without_pagination,
|
|
150
|
+
deadline_start_range=deadline_start_range,
|
|
151
|
+
deadline_end_range=deadline_end_range,
|
|
152
|
+
unassigned=unassigned
|
|
153
|
+
)
|
|
154
|
+
|
|
155
|
+
# Handle the 'with' parameter specially due to Python keyword conflict
|
|
156
|
+
if with_:
|
|
157
|
+
params['with'] = with_
|
|
158
|
+
|
|
159
|
+
response_data = self.sdk._make_request('GET', endpoint, params=params)
|
|
160
|
+
|
|
161
|
+
# Return the structured response with pagination
|
|
162
|
+
return TasksList.from_dict(response_data)
|
|
163
|
+
|
|
164
|
+
except TallyfyError:
|
|
165
|
+
raise
|
|
166
|
+
except Exception as e:
|
|
167
|
+
self._handle_api_error(e, "get tasks for process", org_id=org_id, process_id=process_id, process_name=process_name)
|
|
168
|
+
|
|
169
|
+
def get_organization_runs(self, org_id: str, per_page: int = 100, page: int = 1, with_data: Optional[str] = None,
|
|
170
|
+
form_fields_values: Optional[bool] = None,
|
|
171
|
+
owners: Optional[str] = None, task_status: Optional[str] = None,
|
|
172
|
+
groups: Optional[str] = None, status: Optional[str] = None,
|
|
173
|
+
folder: Optional[str] = None, checklist_id: Optional[str] = None,
|
|
174
|
+
starred: Optional[bool] = None, run_type: Optional[str] = None,
|
|
175
|
+
tag: Optional[str] = None, sort: Optional[str] = None) -> RunsList:
|
|
176
|
+
"""
|
|
177
|
+
Get all processes (runs) in the organization.
|
|
178
|
+
|
|
179
|
+
Args:
|
|
180
|
+
org_id: Organization ID
|
|
181
|
+
per_page: Results per page (default: 100)
|
|
182
|
+
page: Results page to retrieve (default: 1)
|
|
183
|
+
with_data: Comma-separated data to include (e.g., 'checklist,tasks,assets,tags')
|
|
184
|
+
form_fields_values: Include form field values
|
|
185
|
+
owners: Filter by specific member IDs
|
|
186
|
+
task_status: Filter by task status ('all', 'in-progress', 'completed')
|
|
187
|
+
groups: Filter by group IDs
|
|
188
|
+
status: Filter by process status ('active', 'problem', 'delayed', 'complete', 'archived')
|
|
189
|
+
folder: Filter by folder ID
|
|
190
|
+
checklist_id: Filter by template ID
|
|
191
|
+
starred: Filter by starred status
|
|
192
|
+
run_type: Filter by type ('procedure', 'form', 'document')
|
|
193
|
+
tag: Filter by tag ID
|
|
194
|
+
sort: Sort by creation date ('created_at', '-created_at')
|
|
195
|
+
|
|
196
|
+
Returns:
|
|
197
|
+
RunsList object containing runs and pagination metadata (total count, etc.)
|
|
198
|
+
|
|
199
|
+
Raises:
|
|
200
|
+
TallyfyError: If the request fails
|
|
201
|
+
"""
|
|
202
|
+
self._validate_org_id(org_id)
|
|
203
|
+
|
|
204
|
+
try:
|
|
205
|
+
endpoint = f"organizations/{org_id}/runs"
|
|
206
|
+
|
|
207
|
+
# Build parameters using base class helper
|
|
208
|
+
params = self._build_query_params(
|
|
209
|
+
with_=with_data, # Use with_ to avoid Python keyword conflict
|
|
210
|
+
form_fields_values=form_fields_values,
|
|
211
|
+
owners=owners,
|
|
212
|
+
task_status=task_status,
|
|
213
|
+
groups=groups,
|
|
214
|
+
status=status,
|
|
215
|
+
folder=folder,
|
|
216
|
+
checklist_id=checklist_id,
|
|
217
|
+
starred=starred,
|
|
218
|
+
type=run_type, # API expects 'type' parameter
|
|
219
|
+
tag=tag,
|
|
220
|
+
sort=sort,
|
|
221
|
+
per_page=per_page,
|
|
222
|
+
page=page
|
|
223
|
+
)
|
|
224
|
+
|
|
225
|
+
# Handle the 'with' parameter specially due to Python keyword conflict
|
|
226
|
+
if with_data:
|
|
227
|
+
params['with'] = with_data
|
|
228
|
+
if 'with_' in params:
|
|
229
|
+
del params['with_']
|
|
230
|
+
|
|
231
|
+
response_data = self.sdk._make_request('GET', endpoint, params=params)
|
|
232
|
+
|
|
233
|
+
# Return the structured response with pagination
|
|
234
|
+
return RunsList.from_dict(response_data)
|
|
235
|
+
|
|
236
|
+
except TallyfyError:
|
|
237
|
+
raise
|
|
238
|
+
except Exception as e:
|
|
239
|
+
self._handle_api_error(e, "get organization runs", org_id=org_id)
|
|
240
|
+
|
|
241
|
+
def get_organization_processes(self, org_id: str, **kwargs) -> RunsList:
|
|
242
|
+
"""
|
|
243
|
+
Alias for get_organization_runs for better naming consistency.
|
|
244
|
+
|
|
245
|
+
Args:
|
|
246
|
+
org_id: Organization ID
|
|
247
|
+
**kwargs: Same parameters as get_organization_runs
|
|
248
|
+
|
|
249
|
+
Returns:
|
|
250
|
+
RunsList object containing runs and pagination metadata (total count, etc.)
|
|
251
|
+
"""
|
|
252
|
+
return self.get_organization_runs(org_id, **kwargs)
|
|
@@ -0,0 +1,198 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Task and process search operations
|
|
3
|
+
"""
|
|
4
|
+
|
|
5
|
+
from typing import List
|
|
6
|
+
from .base import TaskManagerBase
|
|
7
|
+
from ..models import SearchResult, SearchResultsList, TallyfyError
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
class TaskSearch(TaskManagerBase):
|
|
11
|
+
"""Handles task and process search operations"""
|
|
12
|
+
|
|
13
|
+
def search_processes_by_name(self, org_id: str, process_name: str) -> str:
|
|
14
|
+
"""
|
|
15
|
+
Search for processes by name using the search endpoint.
|
|
16
|
+
|
|
17
|
+
Args:
|
|
18
|
+
org_id: Organization ID
|
|
19
|
+
process_name: Name or partial name of the process to search for
|
|
20
|
+
|
|
21
|
+
Returns:
|
|
22
|
+
Process ID of the found process
|
|
23
|
+
|
|
24
|
+
Raises:
|
|
25
|
+
TallyfyError: If no process found, multiple matches, or search fails
|
|
26
|
+
"""
|
|
27
|
+
self._validate_org_id(org_id)
|
|
28
|
+
|
|
29
|
+
if not process_name or not isinstance(process_name, str):
|
|
30
|
+
raise ValueError("Process name must be a non-empty string")
|
|
31
|
+
|
|
32
|
+
try:
|
|
33
|
+
search_endpoint = f"organizations/{org_id}/search"
|
|
34
|
+
search_params = {
|
|
35
|
+
'on': 'process',
|
|
36
|
+
'per_page': '20',
|
|
37
|
+
'search': process_name
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
search_response = self.sdk._make_request('GET', search_endpoint, params=search_params)
|
|
41
|
+
|
|
42
|
+
if isinstance(search_response, dict) and 'process' in search_response:
|
|
43
|
+
process_data = search_response['process']
|
|
44
|
+
if 'data' in process_data and process_data['data']:
|
|
45
|
+
processes = process_data['data']
|
|
46
|
+
|
|
47
|
+
# First try exact match (case-insensitive)
|
|
48
|
+
exact_matches = [p for p in processes if p['name'].lower() == process_name.lower()]
|
|
49
|
+
if exact_matches:
|
|
50
|
+
return exact_matches[0]['id']
|
|
51
|
+
elif len(processes) == 1:
|
|
52
|
+
# Single search result, use it
|
|
53
|
+
return processes[0]['id']
|
|
54
|
+
else:
|
|
55
|
+
# Multiple matches found, provide helpful error with options
|
|
56
|
+
match_names = [f"'{p['name']}'" for p in processes[:5]] # Show max 5
|
|
57
|
+
raise TallyfyError(f"Multiple processes found matching '{process_name}': {', '.join(match_names)}. Please be more specific.")
|
|
58
|
+
else:
|
|
59
|
+
raise TallyfyError(f"No process found matching name: {process_name}")
|
|
60
|
+
else:
|
|
61
|
+
raise TallyfyError(f"Search failed for process name: {process_name}")
|
|
62
|
+
|
|
63
|
+
except TallyfyError:
|
|
64
|
+
raise
|
|
65
|
+
except Exception as e:
|
|
66
|
+
self._handle_api_error(e, "search processes by name", org_id=org_id, process_name=process_name)
|
|
67
|
+
|
|
68
|
+
def search(self, org_id: str, search_query: str, search_type: str = "process",
|
|
69
|
+
page: int = 1, per_page: int = 20) -> SearchResultsList:
|
|
70
|
+
"""
|
|
71
|
+
Search for processes, templates, or tasks in the organization.
|
|
72
|
+
|
|
73
|
+
Args:
|
|
74
|
+
org_id: Organization ID
|
|
75
|
+
search_query: Text to search for
|
|
76
|
+
search_type: Type of search - 'process', 'blueprint', or 'task' (default: 'process'). blueprint equals template
|
|
77
|
+
page: Page number (default: 1)
|
|
78
|
+
per_page: Number of results per page (default: 20)
|
|
79
|
+
|
|
80
|
+
Returns:
|
|
81
|
+
SearchResultsList object containing results and pagination metadata (total count, etc.)
|
|
82
|
+
|
|
83
|
+
Raises:
|
|
84
|
+
TallyfyError: If the request fails
|
|
85
|
+
ValueError: If search_type is not valid
|
|
86
|
+
"""
|
|
87
|
+
self._validate_org_id(org_id)
|
|
88
|
+
|
|
89
|
+
if not search_query or not isinstance(search_query, str):
|
|
90
|
+
raise ValueError("Search query must be a non-empty string")
|
|
91
|
+
|
|
92
|
+
# Validate search type
|
|
93
|
+
valid_types = ["process", "blueprint", "task"]
|
|
94
|
+
if search_type not in valid_types:
|
|
95
|
+
raise ValueError(f"Search type must be one of: {', '.join(valid_types)}")
|
|
96
|
+
|
|
97
|
+
if per_page <= 0 or per_page > 100:
|
|
98
|
+
raise ValueError("per_page must be between 1 and 100")
|
|
99
|
+
|
|
100
|
+
try:
|
|
101
|
+
endpoint = f"organizations/{org_id}/search"
|
|
102
|
+
params = {
|
|
103
|
+
'on': search_type,
|
|
104
|
+
'page': str(page),
|
|
105
|
+
'per_page': str(per_page),
|
|
106
|
+
'search': search_query
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
response_data = self.sdk._make_request('GET', endpoint, params=params)
|
|
110
|
+
|
|
111
|
+
# Return the structured response with pagination
|
|
112
|
+
return SearchResultsList.from_dict(response_data, search_type)
|
|
113
|
+
|
|
114
|
+
except TallyfyError:
|
|
115
|
+
raise
|
|
116
|
+
except Exception as e:
|
|
117
|
+
self._handle_api_error(e, "search", org_id=org_id, search_query=search_query, search_type=search_type)
|
|
118
|
+
|
|
119
|
+
def search_processes(self, org_id: str, search_query: str, page: int = 1, per_page: int = 20) -> SearchResultsList:
|
|
120
|
+
"""
|
|
121
|
+
Search for processes in the organization.
|
|
122
|
+
|
|
123
|
+
Args:
|
|
124
|
+
org_id: Organization ID
|
|
125
|
+
search_query: Text to search for
|
|
126
|
+
page: Page number (default: 1)
|
|
127
|
+
per_page: Number of results per page (default: 20)
|
|
128
|
+
|
|
129
|
+
Returns:
|
|
130
|
+
SearchResultsList object containing results and pagination metadata (total count, etc.)
|
|
131
|
+
|
|
132
|
+
Raises:
|
|
133
|
+
TallyfyError: If the request fails
|
|
134
|
+
"""
|
|
135
|
+
return self.search(org_id, search_query, "process", page, per_page)
|
|
136
|
+
|
|
137
|
+
def search_templates(self, org_id: str, search_query: str, page: int = 1, per_page: int = 20) -> SearchResultsList:
|
|
138
|
+
"""
|
|
139
|
+
Search for templates (blueprints) in the organization.
|
|
140
|
+
|
|
141
|
+
Args:
|
|
142
|
+
org_id: Organization ID
|
|
143
|
+
search_query: Text to search for
|
|
144
|
+
page: Page number (default: 1)
|
|
145
|
+
per_page: Number of results per page (default: 20)
|
|
146
|
+
|
|
147
|
+
Returns:
|
|
148
|
+
SearchResultsList object containing results and pagination metadata (total count, etc.)
|
|
149
|
+
|
|
150
|
+
Raises:
|
|
151
|
+
TallyfyError: If the request fails
|
|
152
|
+
"""
|
|
153
|
+
return self.search(org_id, search_query, "blueprint", page, per_page)
|
|
154
|
+
|
|
155
|
+
def search_tasks(self, org_id: str, search_query: str, page: int = 1, per_page: int = 20) -> SearchResultsList:
|
|
156
|
+
"""
|
|
157
|
+
Search for tasks in the organization.
|
|
158
|
+
|
|
159
|
+
Args:
|
|
160
|
+
org_id: Organization ID
|
|
161
|
+
search_query: Text to search for
|
|
162
|
+
page: Page number (default: 1)
|
|
163
|
+
per_page: Number of results per page (default: 20)
|
|
164
|
+
|
|
165
|
+
Returns:
|
|
166
|
+
SearchResultsList object containing results and pagination metadata (total count, etc.)
|
|
167
|
+
|
|
168
|
+
Raises:
|
|
169
|
+
TallyfyError: If the request fails
|
|
170
|
+
"""
|
|
171
|
+
return self.search(org_id, search_query, "task", page, per_page)
|
|
172
|
+
|
|
173
|
+
def find_process_by_name(self, org_id: str, process_name: str, exact_match: bool = True) -> List[SearchResult]:
|
|
174
|
+
"""
|
|
175
|
+
Find processes by name with flexible matching options.
|
|
176
|
+
|
|
177
|
+
Args:
|
|
178
|
+
org_id: Organization ID
|
|
179
|
+
process_name: Name of the process to search for
|
|
180
|
+
exact_match: If True, only return exact matches (case-insensitive)
|
|
181
|
+
|
|
182
|
+
Returns:
|
|
183
|
+
List of SearchResult objects matching the criteria
|
|
184
|
+
|
|
185
|
+
Raises:
|
|
186
|
+
TallyfyError: If the request fails
|
|
187
|
+
"""
|
|
188
|
+
results_list = self.search_processes(org_id, process_name)
|
|
189
|
+
|
|
190
|
+
if exact_match:
|
|
191
|
+
# Filter for exact matches (case-insensitive)
|
|
192
|
+
exact_results = []
|
|
193
|
+
for result in results_list.data:
|
|
194
|
+
if hasattr(result, 'name') and result.name.lower() == process_name.lower():
|
|
195
|
+
exact_results.append(result)
|
|
196
|
+
return exact_results
|
|
197
|
+
|
|
198
|
+
return results_list.data
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Template Management Package
|
|
3
|
+
|
|
4
|
+
This package provides a refactored, modular approach to template management
|
|
5
|
+
functionality, breaking down the monolithic TemplateManagement class into
|
|
6
|
+
specialized components for better maintainability and separation of concerns.
|
|
7
|
+
|
|
8
|
+
Classes:
|
|
9
|
+
TemplateBasicOperations: CRUD operations for templates
|
|
10
|
+
TemplateAnalysis: Analysis and insights for templates
|
|
11
|
+
TemplateAutomation: Automation rule management
|
|
12
|
+
TemplateHealthAssessment: Comprehensive template health checks
|
|
13
|
+
TemplateManager: Unified interface combining all functionality
|
|
14
|
+
"""
|
|
15
|
+
|
|
16
|
+
from .base import TemplateManagerBase
|
|
17
|
+
from .basic_operations import TemplateBasicOperations
|
|
18
|
+
from .analysis import TemplateAnalysis
|
|
19
|
+
from .automation import TemplateAutomation
|
|
20
|
+
from .health_assessment import TemplateHealthAssessment
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
class TemplateManager:
|
|
24
|
+
"""
|
|
25
|
+
Unified interface for template management functionality.
|
|
26
|
+
|
|
27
|
+
This class provides access to all template management capabilities
|
|
28
|
+
through a single interface while maintaining the modular structure
|
|
29
|
+
underneath.
|
|
30
|
+
"""
|
|
31
|
+
|
|
32
|
+
def __init__(self, sdk):
|
|
33
|
+
"""
|
|
34
|
+
Initialize template manager with SDK instance.
|
|
35
|
+
|
|
36
|
+
Args:
|
|
37
|
+
sdk: Main SDK instance
|
|
38
|
+
"""
|
|
39
|
+
self.basic_operations = TemplateBasicOperations(sdk)
|
|
40
|
+
self.analysis = TemplateAnalysis(sdk)
|
|
41
|
+
self.automation = TemplateAutomation(sdk)
|
|
42
|
+
self.health_assessment = TemplateHealthAssessment(sdk)
|
|
43
|
+
|
|
44
|
+
# For backward compatibility, expose common methods at the top level
|
|
45
|
+
self.search_templates_by_name = self.basic_operations.search_templates_by_name
|
|
46
|
+
self.get_template = self.basic_operations.get_template
|
|
47
|
+
self.get_all_templates = self.basic_operations.get_all_templates
|
|
48
|
+
self.update_template_metadata = self.basic_operations.update_template_metadata
|
|
49
|
+
self.get_template_with_steps = self.basic_operations.get_template_with_steps
|
|
50
|
+
self.duplicate_template = self.basic_operations.duplicate_template
|
|
51
|
+
self.get_template_steps = self.basic_operations.get_template_steps
|
|
52
|
+
self.edit_description_on_step = self.basic_operations.edit_description_on_step
|
|
53
|
+
self.add_step_to_template = self.basic_operations.add_step_to_template
|
|
54
|
+
|
|
55
|
+
# Analysis methods
|
|
56
|
+
self.get_step_dependencies = self.analysis.get_step_dependencies
|
|
57
|
+
self.suggest_step_deadline = self.analysis.suggest_step_deadline
|
|
58
|
+
self.get_step_visibility_conditions = self.analysis.get_step_visibility_conditions
|
|
59
|
+
self.suggest_kickoff_fields = self.analysis.suggest_kickoff_fields
|
|
60
|
+
self.suggest_automation_consolidation = self.analysis.suggest_automation_consolidation
|
|
61
|
+
|
|
62
|
+
# Automation methods
|
|
63
|
+
self.create_automation_rule = self.automation.create_automation_rule
|
|
64
|
+
self.update_automation_rule = self.automation.update_automation_rule
|
|
65
|
+
self.delete_automation_rule = self.automation.delete_automation_rule
|
|
66
|
+
self.consolidate_automation_rules = self.automation.consolidate_automation_rules
|
|
67
|
+
self.add_assignees_to_step = self.automation.add_assignees_to_step
|
|
68
|
+
self.analyze_template_automations = self.automation.analyze_template_automations
|
|
69
|
+
|
|
70
|
+
# Health assessment method
|
|
71
|
+
self.assess_template_health = self.health_assessment.assess_template_health
|
|
72
|
+
|
|
73
|
+
|
|
74
|
+
# For backward compatibility, create an alias
|
|
75
|
+
TemplateManagement = TemplateManager
|
|
76
|
+
|
|
77
|
+
__all__ = [
|
|
78
|
+
'TemplateManagerBase',
|
|
79
|
+
'TemplateBasicOperations',
|
|
80
|
+
'TemplateAnalysis',
|
|
81
|
+
'TemplateAutomation',
|
|
82
|
+
'TemplateHealthAssessment',
|
|
83
|
+
'TemplateManager',
|
|
84
|
+
'TemplateManagement' # Backward compatibility alias
|
|
85
|
+
]
|