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.
Files changed (42) hide show
  1. {mbu_dev_shared_components-0.0.53 → mbu_dev_shared_components-0.0.55}/PKG-INFO +1 -1
  2. {mbu_dev_shared_components-0.0.53 → mbu_dev_shared_components-0.0.55}/mbu_dev_shared_components/solteqtand/app_handler.py +123 -17
  3. {mbu_dev_shared_components-0.0.53 → mbu_dev_shared_components-0.0.55}/mbu_dev_shared_components.egg-info/PKG-INFO +1 -1
  4. {mbu_dev_shared_components-0.0.53 → mbu_dev_shared_components-0.0.55}/.github/workflows/pylint.yml +0 -0
  5. {mbu_dev_shared_components-0.0.53 → mbu_dev_shared_components-0.0.55}/.gitignore +0 -0
  6. {mbu_dev_shared_components-0.0.53 → mbu_dev_shared_components-0.0.55}/.pylintrc +0 -0
  7. {mbu_dev_shared_components-0.0.53 → mbu_dev_shared_components-0.0.55}/LICENSE +0 -0
  8. {mbu_dev_shared_components-0.0.53 → mbu_dev_shared_components-0.0.55}/README.md +0 -0
  9. {mbu_dev_shared_components-0.0.53 → mbu_dev_shared_components-0.0.55}/mbu_dev_shared_components/getorganized/__init__.py +0 -0
  10. {mbu_dev_shared_components-0.0.53 → mbu_dev_shared_components-0.0.55}/mbu_dev_shared_components/getorganized/auth.py +0 -0
  11. {mbu_dev_shared_components-0.0.53 → mbu_dev_shared_components-0.0.55}/mbu_dev_shared_components/getorganized/cases.py +0 -0
  12. {mbu_dev_shared_components-0.0.53 → mbu_dev_shared_components-0.0.55}/mbu_dev_shared_components/getorganized/contacts.py +0 -0
  13. {mbu_dev_shared_components-0.0.53 → mbu_dev_shared_components-0.0.55}/mbu_dev_shared_components/getorganized/documents.py +0 -0
  14. {mbu_dev_shared_components-0.0.53 → mbu_dev_shared_components-0.0.55}/mbu_dev_shared_components/getorganized/objects.py +0 -0
  15. {mbu_dev_shared_components-0.0.53 → mbu_dev_shared_components-0.0.55}/mbu_dev_shared_components/google/__init__.py +0 -0
  16. {mbu_dev_shared_components-0.0.53 → mbu_dev_shared_components-0.0.55}/mbu_dev_shared_components/google/api/__init__.py +0 -0
  17. {mbu_dev_shared_components-0.0.53 → mbu_dev_shared_components-0.0.55}/mbu_dev_shared_components/google/api/auth.py +0 -0
  18. {mbu_dev_shared_components-0.0.53 → mbu_dev_shared_components-0.0.55}/mbu_dev_shared_components/google/workspace/__init__.py +0 -0
  19. {mbu_dev_shared_components-0.0.53 → mbu_dev_shared_components-0.0.55}/mbu_dev_shared_components/google/workspace/alerts.py +0 -0
  20. {mbu_dev_shared_components-0.0.53 → mbu_dev_shared_components-0.0.55}/mbu_dev_shared_components/msoffice365/__init__.py +0 -0
  21. {mbu_dev_shared_components-0.0.53 → mbu_dev_shared_components-0.0.55}/mbu_dev_shared_components/msoffice365/excel/__init__.py +0 -0
  22. {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
  23. {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
  24. {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
  25. {mbu_dev_shared_components-0.0.53 → mbu_dev_shared_components-0.0.55}/mbu_dev_shared_components/os2forms/__init__.py +0 -0
  26. {mbu_dev_shared_components-0.0.53 → mbu_dev_shared_components-0.0.55}/mbu_dev_shared_components/os2forms/documents.py +0 -0
  27. {mbu_dev_shared_components-0.0.53 → mbu_dev_shared_components-0.0.55}/mbu_dev_shared_components/os2forms/forms.py +0 -0
  28. {mbu_dev_shared_components-0.0.53 → mbu_dev_shared_components-0.0.55}/mbu_dev_shared_components/sap/__init__.py +0 -0
  29. {mbu_dev_shared_components-0.0.53 → mbu_dev_shared_components-0.0.55}/mbu_dev_shared_components/sap/create_invoice.py +0 -0
  30. {mbu_dev_shared_components-0.0.53 → mbu_dev_shared_components-0.0.55}/mbu_dev_shared_components/solteqtand/__init__.py +0 -0
  31. {mbu_dev_shared_components-0.0.53 → mbu_dev_shared_components-0.0.55}/mbu_dev_shared_components/solteqtand/db_handler.py +0 -0
  32. {mbu_dev_shared_components-0.0.53 → mbu_dev_shared_components-0.0.55}/mbu_dev_shared_components/utils/__init__.py +0 -0
  33. {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
  34. {mbu_dev_shared_components-0.0.53 → mbu_dev_shared_components-0.0.55}/mbu_dev_shared_components/utils/fernet_encryptor.py +0 -0
  35. {mbu_dev_shared_components-0.0.53 → mbu_dev_shared_components-0.0.55}/mbu_dev_shared_components/utils/file_handler.py +0 -0
  36. {mbu_dev_shared_components-0.0.53 → mbu_dev_shared_components-0.0.55}/mbu_dev_shared_components/utils/json_handler.py +0 -0
  37. {mbu_dev_shared_components-0.0.53 → mbu_dev_shared_components-0.0.55}/mbu_dev_shared_components.egg-info/SOURCES.txt +0 -0
  38. {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
  39. {mbu_dev_shared_components-0.0.53 → mbu_dev_shared_components-0.0.55}/mbu_dev_shared_components.egg-info/requires.txt +0 -0
  40. {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
  41. {mbu_dev_shared_components-0.0.53 → mbu_dev_shared_components-0.0.55}/pyproject.toml +0 -0
  42. {mbu_dev_shared_components-0.0.53 → mbu_dev_shared_components-0.0.55}/setup.cfg +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: mbu_dev_shared_components
3
- Version: 0.0.53
3
+ Version: 0.0.55
4
4
  Summary: Shared components to use in RPA projects
5
5
  Author-email: MBU <rpa@mbu.aarhus.dk>
6
6
  Classifier: Programming Language :: Python :: 3
@@ -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, ssn):
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
- The keys must match the properties used in the control type, e.g., 'AutomationId', 'Name'.
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
- Control: The control object if found, otherwise None.
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 control
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} was not found within the timeout period.")
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=self.ssn)
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
+ )
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: mbu_dev_shared_components
3
- Version: 0.0.53
3
+ Version: 0.0.55
4
4
  Summary: Shared components to use in RPA projects
5
5
  Author-email: MBU <rpa@mbu.aarhus.dk>
6
6
  Classifier: Programming Language :: Python :: 3