mbu-dev-shared-components 0.0.53__tar.gz → 0.0.55__tar.gz
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.
- {mbu_dev_shared_components-0.0.53 → mbu_dev_shared_components-0.0.55}/PKG-INFO +1 -1
- {mbu_dev_shared_components-0.0.53 → mbu_dev_shared_components-0.0.55}/mbu_dev_shared_components/solteqtand/app_handler.py +123 -17
- {mbu_dev_shared_components-0.0.53 → mbu_dev_shared_components-0.0.55}/mbu_dev_shared_components.egg-info/PKG-INFO +1 -1
- {mbu_dev_shared_components-0.0.53 → mbu_dev_shared_components-0.0.55}/.github/workflows/pylint.yml +0 -0
- {mbu_dev_shared_components-0.0.53 → mbu_dev_shared_components-0.0.55}/.gitignore +0 -0
- {mbu_dev_shared_components-0.0.53 → mbu_dev_shared_components-0.0.55}/.pylintrc +0 -0
- {mbu_dev_shared_components-0.0.53 → mbu_dev_shared_components-0.0.55}/LICENSE +0 -0
- {mbu_dev_shared_components-0.0.53 → mbu_dev_shared_components-0.0.55}/README.md +0 -0
- {mbu_dev_shared_components-0.0.53 → mbu_dev_shared_components-0.0.55}/mbu_dev_shared_components/getorganized/__init__.py +0 -0
- {mbu_dev_shared_components-0.0.53 → mbu_dev_shared_components-0.0.55}/mbu_dev_shared_components/getorganized/auth.py +0 -0
- {mbu_dev_shared_components-0.0.53 → mbu_dev_shared_components-0.0.55}/mbu_dev_shared_components/getorganized/cases.py +0 -0
- {mbu_dev_shared_components-0.0.53 → mbu_dev_shared_components-0.0.55}/mbu_dev_shared_components/getorganized/contacts.py +0 -0
- {mbu_dev_shared_components-0.0.53 → mbu_dev_shared_components-0.0.55}/mbu_dev_shared_components/getorganized/documents.py +0 -0
- {mbu_dev_shared_components-0.0.53 → mbu_dev_shared_components-0.0.55}/mbu_dev_shared_components/getorganized/objects.py +0 -0
- {mbu_dev_shared_components-0.0.53 → mbu_dev_shared_components-0.0.55}/mbu_dev_shared_components/google/__init__.py +0 -0
- {mbu_dev_shared_components-0.0.53 → mbu_dev_shared_components-0.0.55}/mbu_dev_shared_components/google/api/__init__.py +0 -0
- {mbu_dev_shared_components-0.0.53 → mbu_dev_shared_components-0.0.55}/mbu_dev_shared_components/google/api/auth.py +0 -0
- {mbu_dev_shared_components-0.0.53 → mbu_dev_shared_components-0.0.55}/mbu_dev_shared_components/google/workspace/__init__.py +0 -0
- {mbu_dev_shared_components-0.0.53 → mbu_dev_shared_components-0.0.55}/mbu_dev_shared_components/google/workspace/alerts.py +0 -0
- {mbu_dev_shared_components-0.0.53 → mbu_dev_shared_components-0.0.55}/mbu_dev_shared_components/msoffice365/__init__.py +0 -0
- {mbu_dev_shared_components-0.0.53 → mbu_dev_shared_components-0.0.55}/mbu_dev_shared_components/msoffice365/excel/__init__.py +0 -0
- {mbu_dev_shared_components-0.0.53 → mbu_dev_shared_components-0.0.55}/mbu_dev_shared_components/msoffice365/excel/excel_reader.py +0 -0
- {mbu_dev_shared_components-0.0.53 → mbu_dev_shared_components-0.0.55}/mbu_dev_shared_components/msoffice365/sharepoint_api/__init__.py +0 -0
- {mbu_dev_shared_components-0.0.53 → mbu_dev_shared_components-0.0.55}/mbu_dev_shared_components/msoffice365/sharepoint_api/files.py +0 -0
- {mbu_dev_shared_components-0.0.53 → mbu_dev_shared_components-0.0.55}/mbu_dev_shared_components/os2forms/__init__.py +0 -0
- {mbu_dev_shared_components-0.0.53 → mbu_dev_shared_components-0.0.55}/mbu_dev_shared_components/os2forms/documents.py +0 -0
- {mbu_dev_shared_components-0.0.53 → mbu_dev_shared_components-0.0.55}/mbu_dev_shared_components/os2forms/forms.py +0 -0
- {mbu_dev_shared_components-0.0.53 → mbu_dev_shared_components-0.0.55}/mbu_dev_shared_components/sap/__init__.py +0 -0
- {mbu_dev_shared_components-0.0.53 → mbu_dev_shared_components-0.0.55}/mbu_dev_shared_components/sap/create_invoice.py +0 -0
- {mbu_dev_shared_components-0.0.53 → mbu_dev_shared_components-0.0.55}/mbu_dev_shared_components/solteqtand/__init__.py +0 -0
- {mbu_dev_shared_components-0.0.53 → mbu_dev_shared_components-0.0.55}/mbu_dev_shared_components/solteqtand/db_handler.py +0 -0
- {mbu_dev_shared_components-0.0.53 → mbu_dev_shared_components-0.0.55}/mbu_dev_shared_components/utils/__init__.py +0 -0
- {mbu_dev_shared_components-0.0.53 → mbu_dev_shared_components-0.0.55}/mbu_dev_shared_components/utils/db_stored_procedure_executor.py +0 -0
- {mbu_dev_shared_components-0.0.53 → mbu_dev_shared_components-0.0.55}/mbu_dev_shared_components/utils/fernet_encryptor.py +0 -0
- {mbu_dev_shared_components-0.0.53 → mbu_dev_shared_components-0.0.55}/mbu_dev_shared_components/utils/file_handler.py +0 -0
- {mbu_dev_shared_components-0.0.53 → mbu_dev_shared_components-0.0.55}/mbu_dev_shared_components/utils/json_handler.py +0 -0
- {mbu_dev_shared_components-0.0.53 → mbu_dev_shared_components-0.0.55}/mbu_dev_shared_components.egg-info/SOURCES.txt +0 -0
- {mbu_dev_shared_components-0.0.53 → mbu_dev_shared_components-0.0.55}/mbu_dev_shared_components.egg-info/dependency_links.txt +0 -0
- {mbu_dev_shared_components-0.0.53 → mbu_dev_shared_components-0.0.55}/mbu_dev_shared_components.egg-info/requires.txt +0 -0
- {mbu_dev_shared_components-0.0.53 → mbu_dev_shared_components-0.0.55}/mbu_dev_shared_components.egg-info/top_level.txt +0 -0
- {mbu_dev_shared_components-0.0.53 → mbu_dev_shared_components-0.0.55}/pyproject.toml +0 -0
- {mbu_dev_shared_components-0.0.53 → mbu_dev_shared_components-0.0.55}/setup.cfg +0 -0
|
@@ -6,11 +6,19 @@ import time
|
|
|
6
6
|
import uiautomation as auto
|
|
7
7
|
|
|
8
8
|
|
|
9
|
+
class ManualProcessingRequiredError(Exception):
|
|
10
|
+
"""
|
|
11
|
+
Custom exception raised when the patient cannot be opened due incorrect SSN.
|
|
12
|
+
"""
|
|
13
|
+
def __init__(self, message="Error occurred while opening the patient. There is no patient with the provided CPR number."):
|
|
14
|
+
super().__init__(message)
|
|
15
|
+
|
|
16
|
+
|
|
9
17
|
class SolteqTandApp:
|
|
10
18
|
"""
|
|
11
19
|
A class to automate interactions with the SolteqTand application.
|
|
12
20
|
"""
|
|
13
|
-
def __init__(self, app_path, username, password
|
|
21
|
+
def __init__(self, app_path, username, password):
|
|
14
22
|
"""
|
|
15
23
|
Initializes the SolteqTandApp object.
|
|
16
24
|
|
|
@@ -23,7 +31,6 @@ class SolteqTandApp:
|
|
|
23
31
|
self.app_path = app_path
|
|
24
32
|
self.username = username
|
|
25
33
|
self.password = password
|
|
26
|
-
self.ssn = ssn
|
|
27
34
|
self.app_window = None
|
|
28
35
|
|
|
29
36
|
def find_element_by_property(self, control, control_type=None, automation_id=None, name=None, class_name=None) -> auto.Control:
|
|
@@ -55,27 +62,59 @@ class SolteqTandApp:
|
|
|
55
62
|
|
|
56
63
|
return None
|
|
57
64
|
|
|
58
|
-
def wait_for_control(self, control_type, search_params, search_depth=1, timeout=30):
|
|
65
|
+
def wait_for_control(self, control_type, search_params, search_depth=1, timeout=30, retry_interval=0.5):
|
|
59
66
|
"""
|
|
60
67
|
Waits for a given control type to become available with the specified search parameters.
|
|
61
68
|
|
|
62
69
|
Args:
|
|
63
70
|
control_type: The type of control, e.g., auto.WindowControl, auto.ButtonControl, etc.
|
|
64
71
|
search_params (dict): Search parameters used to identify the control.
|
|
65
|
-
|
|
72
|
+
The keys must match the properties used in the control type, e.g., 'AutomationId', 'Name'.
|
|
73
|
+
search_depth (int): How deep to search in the user interface.
|
|
74
|
+
timeout (int): Maximum time to wait for the control, in seconds.
|
|
75
|
+
retry_interval (float): Time to wait between retries, in seconds.
|
|
76
|
+
|
|
77
|
+
Returns:
|
|
78
|
+
Control: The control object if found, otherwise raises TimeoutError.
|
|
79
|
+
|
|
80
|
+
Raises:
|
|
81
|
+
TimeoutError: If the control is not found within the timeout period.
|
|
82
|
+
"""
|
|
83
|
+
end_time = time.time() + timeout
|
|
84
|
+
while time.time() < end_time:
|
|
85
|
+
try:
|
|
86
|
+
control = control_type(searchDepth=search_depth, **search_params)
|
|
87
|
+
if control.Exists(0, 0):
|
|
88
|
+
return control
|
|
89
|
+
except Exception as e:
|
|
90
|
+
print(f"Error while searching for control: {e}")
|
|
91
|
+
|
|
92
|
+
time.sleep(retry_interval)
|
|
93
|
+
print(f"Retrying to find control: {search_params}...")
|
|
94
|
+
|
|
95
|
+
raise TimeoutError(f"Control with parameters {search_params} was not found within the {timeout} second timeout.")
|
|
96
|
+
|
|
97
|
+
def wait_for_control_to_disappear(self, control_type, search_params, search_depth=1, timeout=30):
|
|
98
|
+
"""
|
|
99
|
+
Waits for a given control type to disappear with the specified search parameters.
|
|
100
|
+
|
|
101
|
+
Args:
|
|
102
|
+
control_type: The type of control, e.g., auto.WindowControl, auto.ButtonControl, etc.
|
|
103
|
+
search_params (dict): Search parameters used to identify the control.
|
|
104
|
+
The keys must match the properties used in the control type, e.g., 'AutomationId', 'Name'.
|
|
66
105
|
search_depth (int): How deep to search in the user interface.
|
|
67
106
|
timeout (int): How long to wait, in seconds.
|
|
68
107
|
|
|
69
108
|
Returns:
|
|
70
|
-
|
|
109
|
+
bool: True if the control disappeared within the timeout period, otherwise False.
|
|
71
110
|
"""
|
|
72
111
|
end_time = time.time() + timeout
|
|
73
112
|
while time.time() < end_time:
|
|
74
113
|
control = control_type(searchDepth=search_depth, **search_params)
|
|
75
|
-
if control.Exists(0, 0):
|
|
76
|
-
return
|
|
114
|
+
if not control.Exists(0, 0):
|
|
115
|
+
return True
|
|
77
116
|
time.sleep(0.5)
|
|
78
|
-
raise TimeoutError(f"Control with parameters {search_params}
|
|
117
|
+
raise TimeoutError(f"Control with parameters {search_params} did not disappear within the timeout period.")
|
|
79
118
|
|
|
80
119
|
def start_application(self):
|
|
81
120
|
"""
|
|
@@ -114,11 +153,18 @@ class SolteqTandApp:
|
|
|
114
153
|
timeout=60
|
|
115
154
|
)
|
|
116
155
|
|
|
117
|
-
def open_patient(self):
|
|
156
|
+
def open_patient(self, ssn):
|
|
118
157
|
"""
|
|
119
158
|
When the main window is open, presses Ctrl + O to open the 'Open Patient' window,
|
|
120
159
|
searches for the SSN, and opens the patient.
|
|
121
160
|
"""
|
|
161
|
+
self.app_window = self.wait_for_control(
|
|
162
|
+
auto.WindowControl,
|
|
163
|
+
{'AutomationId': 'FormFront'},
|
|
164
|
+
search_depth=2,
|
|
165
|
+
timeout=5
|
|
166
|
+
)
|
|
167
|
+
|
|
122
168
|
self.app_window.SetFocus()
|
|
123
169
|
self.app_window.SendKeys('{Ctrl}o', waitTime=0)
|
|
124
170
|
|
|
@@ -132,14 +178,34 @@ class SolteqTandApp:
|
|
|
132
178
|
ssn_input = open_patient_window.EditControl(AutomationId="TextBoxCpr")
|
|
133
179
|
search_button = open_patient_window.PaneControl(AutomationId="ButtonOk")
|
|
134
180
|
|
|
135
|
-
ssn_input.SendKeys(text=
|
|
181
|
+
ssn_input.SendKeys(text=ssn)
|
|
136
182
|
search_button.SetFocus()
|
|
137
183
|
search_button.SendKeys('{ENTER}')
|
|
138
184
|
|
|
185
|
+
try:
|
|
186
|
+
error_window = self.wait_for_control(
|
|
187
|
+
auto.WindowControl,
|
|
188
|
+
{'Name': 'TMT - Åbn patient'},
|
|
189
|
+
search_depth=2,
|
|
190
|
+
timeout=10
|
|
191
|
+
)
|
|
192
|
+
|
|
193
|
+
if error_window is not None:
|
|
194
|
+
error_window_button = error_window.ButtonControl(Name="OK")
|
|
195
|
+
error_window_button.SetFocus()
|
|
196
|
+
error_window_button.Click(simulateMove=False, waitTime=0)
|
|
197
|
+
|
|
198
|
+
raise ManualProcessingRequiredError
|
|
199
|
+
|
|
200
|
+
except TimeoutError:
|
|
201
|
+
pass
|
|
202
|
+
|
|
139
203
|
self.app_window = self.wait_for_control(
|
|
140
204
|
auto.WindowControl,
|
|
141
|
-
{'AutomationId': 'FormPatient'}
|
|
205
|
+
{'AutomationId': 'FormPatient'},
|
|
206
|
+
timeout=10
|
|
142
207
|
)
|
|
208
|
+
|
|
143
209
|
self.app_window.Maximize()
|
|
144
210
|
|
|
145
211
|
def open_sub_tab(self, sub_tab_name: str):
|
|
@@ -198,12 +264,7 @@ class SolteqTandApp:
|
|
|
198
264
|
control_type=auto.ControlType.ListControl,
|
|
199
265
|
automation_id="cleverListView1"
|
|
200
266
|
)
|
|
201
|
-
|
|
202
|
-
list_items = self.find_element_by_property(
|
|
203
|
-
control=document_list,
|
|
204
|
-
control_type=auto.ControlType.ListItemControl
|
|
205
|
-
)
|
|
206
|
-
list_items.RightClick(simulateMove=False, waitTime=0)
|
|
267
|
+
document_list.RightClick(simulateMove=False, waitTime=0)
|
|
207
268
|
|
|
208
269
|
document_list_menu = self.wait_for_control(
|
|
209
270
|
auto.MenuControl,
|
|
@@ -314,6 +375,7 @@ class SolteqTandApp:
|
|
|
314
375
|
note_message (str): The note message.
|
|
315
376
|
checkmark_in_complete (bool): Checks the checkmark in 'Afslut'.
|
|
316
377
|
"""
|
|
378
|
+
print(note_message)
|
|
317
379
|
self.open_tab("Journal")
|
|
318
380
|
|
|
319
381
|
self.wait_for_control(
|
|
@@ -334,3 +396,47 @@ class SolteqTandApp:
|
|
|
334
396
|
save_button = self.app_window.PaneControl(AutomationId="buttonSave")
|
|
335
397
|
save_button.SetFocus()
|
|
336
398
|
save_button.Click(simulateMove=False, waitTime=0)
|
|
399
|
+
|
|
400
|
+
def close_patient_window(self):
|
|
401
|
+
"""MISSING"""
|
|
402
|
+
|
|
403
|
+
title_bar_window = self.app_window.TitleBarControl()
|
|
404
|
+
title_bar_window.ButtonControl(Name="Luk").Click(simulateMove=False, waitTime=0)
|
|
405
|
+
|
|
406
|
+
self.app_window = self.wait_for_control_to_disappear(
|
|
407
|
+
auto.WindowControl,
|
|
408
|
+
{'AutomationId': 'FormPatient'},
|
|
409
|
+
search_depth=2
|
|
410
|
+
)
|
|
411
|
+
|
|
412
|
+
self.app_window = self.wait_for_control(
|
|
413
|
+
auto.WindowControl,
|
|
414
|
+
{'AutomationId': 'FormFront'},
|
|
415
|
+
search_depth=2,
|
|
416
|
+
timeout=5
|
|
417
|
+
)
|
|
418
|
+
|
|
419
|
+
def close_solteq_tand(self):
|
|
420
|
+
"""MISSING"""
|
|
421
|
+
self.app_window = self.wait_for_control(
|
|
422
|
+
auto.WindowControl,
|
|
423
|
+
{'AutomationId': 'FormFront'},
|
|
424
|
+
search_depth=2
|
|
425
|
+
)
|
|
426
|
+
self.app_window.SetFocus()
|
|
427
|
+
title_bar_window = self.app_window.TitleBarControl()
|
|
428
|
+
title_bar_window.ButtonControl(Name="Luk").Click(simulateMove=False, waitTime=0)
|
|
429
|
+
|
|
430
|
+
self.app_window = self.wait_for_control(
|
|
431
|
+
auto.ButtonControl,
|
|
432
|
+
{'Name': 'Ja'},
|
|
433
|
+
search_depth=3
|
|
434
|
+
)
|
|
435
|
+
|
|
436
|
+
self.app_window.Click(simulateMove=False)
|
|
437
|
+
|
|
438
|
+
self.app_window = self.wait_for_control_to_disappear(
|
|
439
|
+
auto.WindowControl,
|
|
440
|
+
{'AutomationId': 'FormFront'},
|
|
441
|
+
search_depth=2
|
|
442
|
+
)
|
{mbu_dev_shared_components-0.0.53 → mbu_dev_shared_components-0.0.55}/.github/workflows/pylint.yml
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|