mbu-dev-shared-components 4.1.0__tar.gz → 4.2.1__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 (60) hide show
  1. {mbu_dev_shared_components-4.1.0 → mbu_dev_shared_components-4.2.1}/PKG-INFO +2 -1
  2. {mbu_dev_shared_components-4.1.0 → mbu_dev_shared_components-4.2.1}/mbu_dev_shared_components/database/utility.py +30 -15
  3. {mbu_dev_shared_components-4.1.0 → mbu_dev_shared_components-4.2.1}/mbu_dev_shared_components/solteqtand/application/app_handler.py +10 -1
  4. {mbu_dev_shared_components-4.1.0 → mbu_dev_shared_components-4.2.1}/mbu_dev_shared_components/solteqtand/application/base_ui.py +33 -12
  5. {mbu_dev_shared_components-4.1.0 → mbu_dev_shared_components-4.2.1}/mbu_dev_shared_components.egg-info/PKG-INFO +2 -1
  6. {mbu_dev_shared_components-4.1.0 → mbu_dev_shared_components-4.2.1}/mbu_dev_shared_components.egg-info/requires.txt +1 -0
  7. {mbu_dev_shared_components-4.1.0 → mbu_dev_shared_components-4.2.1}/pyproject.toml +2 -1
  8. {mbu_dev_shared_components-4.1.0 → mbu_dev_shared_components-4.2.1}/LICENSE +0 -0
  9. {mbu_dev_shared_components-4.1.0 → mbu_dev_shared_components-4.2.1}/README.md +0 -0
  10. {mbu_dev_shared_components-4.1.0 → mbu_dev_shared_components-4.2.1}/mbu_dev_shared_components/database/__init__.py +0 -0
  11. {mbu_dev_shared_components-4.1.0 → mbu_dev_shared_components-4.2.1}/mbu_dev_shared_components/database/connection.py +0 -0
  12. {mbu_dev_shared_components-4.1.0 → mbu_dev_shared_components-4.2.1}/mbu_dev_shared_components/database/constants.py +0 -0
  13. {mbu_dev_shared_components-4.1.0 → mbu_dev_shared_components-4.2.1}/mbu_dev_shared_components/database/logging.py +0 -0
  14. {mbu_dev_shared_components-4.1.0 → mbu_dev_shared_components-4.2.1}/mbu_dev_shared_components/getorganized/__init__.py +0 -0
  15. {mbu_dev_shared_components-4.1.0 → mbu_dev_shared_components-4.2.1}/mbu_dev_shared_components/getorganized/auth.py +0 -0
  16. {mbu_dev_shared_components-4.1.0 → mbu_dev_shared_components-4.2.1}/mbu_dev_shared_components/getorganized/cases.py +0 -0
  17. {mbu_dev_shared_components-4.1.0 → mbu_dev_shared_components-4.2.1}/mbu_dev_shared_components/getorganized/contacts.py +0 -0
  18. {mbu_dev_shared_components-4.1.0 → mbu_dev_shared_components-4.2.1}/mbu_dev_shared_components/getorganized/documents.py +0 -0
  19. {mbu_dev_shared_components-4.1.0 → mbu_dev_shared_components-4.2.1}/mbu_dev_shared_components/getorganized/objects.py +0 -0
  20. {mbu_dev_shared_components-4.1.0 → mbu_dev_shared_components-4.2.1}/mbu_dev_shared_components/google/__init__.py +0 -0
  21. {mbu_dev_shared_components-4.1.0 → mbu_dev_shared_components-4.2.1}/mbu_dev_shared_components/google/api/__init__.py +0 -0
  22. {mbu_dev_shared_components-4.1.0 → mbu_dev_shared_components-4.2.1}/mbu_dev_shared_components/google/api/auth.py +0 -0
  23. {mbu_dev_shared_components-4.1.0 → mbu_dev_shared_components-4.2.1}/mbu_dev_shared_components/google/workspace/__init__.py +0 -0
  24. {mbu_dev_shared_components-4.1.0 → mbu_dev_shared_components-4.2.1}/mbu_dev_shared_components/google/workspace/alerts.py +0 -0
  25. {mbu_dev_shared_components-4.1.0 → mbu_dev_shared_components-4.2.1}/mbu_dev_shared_components/msoffice365/__init__.py +0 -0
  26. {mbu_dev_shared_components-4.1.0 → mbu_dev_shared_components-4.2.1}/mbu_dev_shared_components/msoffice365/excel/__init__.py +0 -0
  27. {mbu_dev_shared_components-4.1.0 → mbu_dev_shared_components-4.2.1}/mbu_dev_shared_components/msoffice365/excel/excel_reader.py +0 -0
  28. {mbu_dev_shared_components-4.1.0 → mbu_dev_shared_components-4.2.1}/mbu_dev_shared_components/msoffice365/sharepoint_api/__init__.py +0 -0
  29. {mbu_dev_shared_components-4.1.0 → mbu_dev_shared_components-4.2.1}/mbu_dev_shared_components/msoffice365/sharepoint_api/files.py +0 -0
  30. {mbu_dev_shared_components-4.1.0 → mbu_dev_shared_components-4.2.1}/mbu_dev_shared_components/os2forms/__init__.py +0 -0
  31. {mbu_dev_shared_components-4.1.0 → mbu_dev_shared_components-4.2.1}/mbu_dev_shared_components/os2forms/documents.py +0 -0
  32. {mbu_dev_shared_components-4.1.0 → mbu_dev_shared_components-4.2.1}/mbu_dev_shared_components/os2forms/forms.py +0 -0
  33. {mbu_dev_shared_components-4.1.0 → mbu_dev_shared_components-4.2.1}/mbu_dev_shared_components/romexis/__init__.py +0 -0
  34. {mbu_dev_shared_components-4.1.0 → mbu_dev_shared_components-4.2.1}/mbu_dev_shared_components/romexis/db_handler.py +0 -0
  35. {mbu_dev_shared_components-4.1.0 → mbu_dev_shared_components-4.2.1}/mbu_dev_shared_components/romexis/helper_functions.py +0 -0
  36. {mbu_dev_shared_components-4.1.0 → mbu_dev_shared_components-4.2.1}/mbu_dev_shared_components/sap/__init__.py +0 -0
  37. {mbu_dev_shared_components-4.1.0 → mbu_dev_shared_components-4.2.1}/mbu_dev_shared_components/sap/create_invoice.py +0 -0
  38. {mbu_dev_shared_components-4.1.0 → mbu_dev_shared_components-4.2.1}/mbu_dev_shared_components/solteqtand/__init__.py +0 -0
  39. {mbu_dev_shared_components-4.1.0 → mbu_dev_shared_components-4.2.1}/mbu_dev_shared_components/solteqtand/application/__init__.py +0 -0
  40. {mbu_dev_shared_components-4.1.0 → mbu_dev_shared_components-4.2.1}/mbu_dev_shared_components/solteqtand/application/aftalebog.py +0 -0
  41. {mbu_dev_shared_components-4.1.0 → mbu_dev_shared_components-4.2.1}/mbu_dev_shared_components/solteqtand/application/appointment.py +0 -0
  42. {mbu_dev_shared_components-4.1.0 → mbu_dev_shared_components-4.2.1}/mbu_dev_shared_components/solteqtand/application/clinic.py +0 -0
  43. {mbu_dev_shared_components-4.1.0 → mbu_dev_shared_components-4.2.1}/mbu_dev_shared_components/solteqtand/application/document.py +0 -0
  44. {mbu_dev_shared_components-4.1.0 → mbu_dev_shared_components-4.2.1}/mbu_dev_shared_components/solteqtand/application/edi_portal.py +0 -0
  45. {mbu_dev_shared_components-4.1.0 → mbu_dev_shared_components-4.2.1}/mbu_dev_shared_components/solteqtand/application/event.py +0 -0
  46. {mbu_dev_shared_components-4.1.0 → mbu_dev_shared_components-4.2.1}/mbu_dev_shared_components/solteqtand/application/exceptions.py +0 -0
  47. {mbu_dev_shared_components-4.1.0 → mbu_dev_shared_components-4.2.1}/mbu_dev_shared_components/solteqtand/application/handler_base.py +0 -0
  48. {mbu_dev_shared_components-4.1.0 → mbu_dev_shared_components-4.2.1}/mbu_dev_shared_components/solteqtand/application/journal_note.py +0 -0
  49. {mbu_dev_shared_components-4.1.0 → mbu_dev_shared_components-4.2.1}/mbu_dev_shared_components/solteqtand/application/patient.py +0 -0
  50. {mbu_dev_shared_components-4.1.0 → mbu_dev_shared_components-4.2.1}/mbu_dev_shared_components/solteqtand/database/__init__.py +0 -0
  51. {mbu_dev_shared_components-4.1.0 → mbu_dev_shared_components-4.2.1}/mbu_dev_shared_components/solteqtand/database/db_handler.py +0 -0
  52. {mbu_dev_shared_components-4.1.0 → mbu_dev_shared_components-4.2.1}/mbu_dev_shared_components/utils/__init__.py +0 -0
  53. {mbu_dev_shared_components-4.1.0 → mbu_dev_shared_components-4.2.1}/mbu_dev_shared_components/utils/db_stored_procedure_executor.py +0 -0
  54. {mbu_dev_shared_components-4.1.0 → mbu_dev_shared_components-4.2.1}/mbu_dev_shared_components/utils/fernet_encryptor.py +0 -0
  55. {mbu_dev_shared_components-4.1.0 → mbu_dev_shared_components-4.2.1}/mbu_dev_shared_components/utils/file_handler.py +0 -0
  56. {mbu_dev_shared_components-4.1.0 → mbu_dev_shared_components-4.2.1}/mbu_dev_shared_components/utils/json_handler.py +0 -0
  57. {mbu_dev_shared_components-4.1.0 → mbu_dev_shared_components-4.2.1}/mbu_dev_shared_components.egg-info/SOURCES.txt +0 -0
  58. {mbu_dev_shared_components-4.1.0 → mbu_dev_shared_components-4.2.1}/mbu_dev_shared_components.egg-info/dependency_links.txt +0 -0
  59. {mbu_dev_shared_components-4.1.0 → mbu_dev_shared_components-4.2.1}/mbu_dev_shared_components.egg-info/top_level.txt +0 -0
  60. {mbu_dev_shared_components-4.1.0 → mbu_dev_shared_components-4.2.1}/setup.cfg +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: mbu_dev_shared_components
3
- Version: 4.1.0
3
+ Version: 4.2.1
4
4
  Summary: Shared components to use in RPA projects
5
5
  Author-email: MBU <rpa@mbu.aarhus.dk>
6
6
  License-Expression: MIT
@@ -12,6 +12,7 @@ License-File: LICENSE
12
12
  Requires-Dist: cryptography>=43.0.0
13
13
  Requires-Dist: pyodbc>=5.1.0
14
14
  Requires-Dist: python-dateutil==2.9.*
15
+ Requires-Dist: dotenv
15
16
  Provides-Extra: getorganized
16
17
  Requires-Dist: requests_ntlm>=1.2.0; extra == "getorganized"
17
18
  Provides-Extra: google
@@ -1,15 +1,17 @@
1
1
  """This module handles general database connection and calls"""
2
2
 
3
- import os
4
3
  import json
5
- from typing import Dict, Union, Tuple, Any
6
- from dateutil import parser
4
+ import os
5
+ from typing import Any, Dict, Tuple, Union
6
+
7
7
  import pyodbc
8
- from dotenv import load_dotenv
8
+ from dateutil import parser
9
+ from dotenv import load_dotenv
9
10
 
10
11
 
11
12
  class Utility:
12
13
  """Base class handling general utilities"""
14
+
13
15
  def connect_to_db(self, autocommit=True, db_env="PROD") -> pyodbc.Connection:
14
16
  """Establish connection to sql database
15
17
 
@@ -22,17 +24,24 @@ class Utility:
22
24
  rpa_conn = pyodbc.connect(rpa_conn_string, autocommit=autocommit)
23
25
  return rpa_conn
24
26
 
25
- def execute_query(self, query: str, params: list = None) -> pyodbc.Cursor:
27
+ def execute_query(
28
+ self, query: str, params: list = None, return_dict: bool = False
29
+ ) -> list | None:
26
30
  """Execute SQL query with pyodbc"""
27
31
  params = [] if not params else params
28
- is_select = query.strip().upper().startswith('SELECT')
32
+ is_select = query.strip().upper().startswith("SELECT")
29
33
  try:
30
34
  res = self.cursor.execute(query, params)
31
35
  if is_select:
32
- res = self.cursor.fetchall()
33
- if len(res) == 0:
36
+ rows = self.cursor.fetchall()
37
+ if len(rows) == 0:
34
38
  print("No results from query")
35
39
  return None
40
+ if return_dict:
41
+ columns = [column[0] for column in self.cursor.description]
42
+ res = [dict(zip(columns, row)) for row in rows]
43
+ else:
44
+ res = rows
36
45
  return res
37
46
  else:
38
47
  return None
@@ -44,15 +53,19 @@ class Utility:
44
53
  def fetch_env(self, db_env):
45
54
  """Get env variable based on context, PROD or TEST"""
46
55
  if db_env.upper() == "PROD":
47
- connection_env = "DBCONNECTIONSTRINGPROD"
56
+ connection_env = "DBCONNECTIONSTRINGPROD"
48
57
  return connection_env
49
58
  if db_env.upper() == "TEST":
50
- connection_env = "DBCONNECTIONSTRINGDEV"
59
+ connection_env = "DBCONNECTIONSTRINGDEV"
51
60
  return connection_env
52
61
 
53
- raise ValueError(f"arg db_env is {db_env.upper()} but should be 'PROD' or 'TEST'")
62
+ raise ValueError(
63
+ f"arg db_env is {db_env.upper()} but should be 'PROD' or 'TEST'"
64
+ )
54
65
 
55
- def execute_stored_procedure(self, stored_procedure: str, params: Dict[str, Tuple[type, Any]] | None = None) -> Dict[str, Union[bool, str, Any]]:
66
+ def execute_stored_procedure(
67
+ self, stored_procedure: str, params: Dict[str, Tuple[type, Any]] | None = None
68
+ ) -> Dict[str, Union[bool, str, Any]]:
56
69
  """
57
70
  Executes a stored procedure with the given parameters.
58
71
 
@@ -76,12 +89,12 @@ class Utility:
76
89
  "int": int,
77
90
  "float": float,
78
91
  "datetime": parser.isoparse,
79
- "json": lambda x: json.dumps(x, ensure_ascii=False)
92
+ "json": lambda x: json.dumps(x, ensure_ascii=False),
80
93
  }
81
94
 
82
95
  try:
83
96
  if params:
84
- param_placeholders = ', '.join([f"@{key} = ?" for key in params.keys()])
97
+ param_placeholders = ", ".join([f"@{key} = ?" for key in params.keys()])
85
98
  param_values = []
86
99
 
87
100
  for key, value in params.items():
@@ -92,7 +105,9 @@ class Utility:
92
105
  else:
93
106
  param_values.append(actual_value)
94
107
  else:
95
- raise ValueError("Each parameter value must be a tuple of (type, actual_value).")
108
+ raise ValueError(
109
+ "Each parameter value must be a tuple of (type, actual_value)."
110
+ )
96
111
 
97
112
  sql = f"EXEC {stored_procedure} {param_placeholders}"
98
113
  rows_updated = self.cursor.execute(sql, tuple(param_values))
@@ -2,6 +2,7 @@
2
2
 
3
3
  import os
4
4
 
5
+ import psutil
5
6
  import uiautomation as auto
6
7
 
7
8
  from .aftalebog import AftalebogHandler
@@ -158,6 +159,14 @@ class SolteqTandApp(
158
159
  try:
159
160
  if self.app_window:
160
161
  self.close_window(self.app_window)
162
+ print(
163
+ "\n".join([p.info["name"] for p in psutil.process_iter(["name"])])
164
+ )
165
+ assert "TMTand.exe" not in [
166
+ p.info["name"] for p in psutil.process_iter(["name"])
167
+ ]
161
168
  self.app_window = None
162
169
  except Exception as error:
163
- print(f"Error closing Solteq Tand application window: {error}")
170
+ raise RuntimeError(
171
+ f"Error closing Solteq Tand application window: {error}"
172
+ ) from error
@@ -1,12 +1,16 @@
1
1
  """Base UI-Automation helper methods for SolteqTand project."""
2
+
2
3
  import time
4
+
3
5
  import uiautomation as auto
4
6
 
5
7
 
6
8
  class BaseUI:
7
9
  """Base UI-Automation helper methods."""
8
10
 
9
- def find_element_by_property(self, control, control_type=None, automation_id=None, name=None, class_name=None) -> auto.Control:
11
+ def find_element_by_property(
12
+ self, control, control_type=None, automation_id=None, name=None, class_name=None
13
+ ) -> auto.Control:
10
14
  """
11
15
  Uses GetChildren to traverse through controls and find an element based on the specified properties.
12
16
 
@@ -24,20 +28,29 @@ class BaseUI:
24
28
 
25
29
  for child in children:
26
30
  if (
27
- (control_type is None or child.ControlType == control_type) and
28
- (automation_id is None or child.AutomationId == automation_id) and
29
- (name is None or child.Name == name) and
30
- (class_name is None or child.ClassName == class_name)
31
+ (control_type is None or child.ControlType == control_type)
32
+ and (automation_id is None or child.AutomationId == automation_id)
33
+ and (name is None or child.Name == name)
34
+ and (class_name is None or child.ClassName == class_name)
31
35
  ):
32
36
  return child
33
37
 
34
- found = self.find_element_by_property(child, control_type, automation_id, name, class_name)
38
+ found = self.find_element_by_property(
39
+ child, control_type, automation_id, name, class_name
40
+ )
35
41
  if found:
36
42
  return found
37
43
 
38
44
  return None
39
45
 
40
- def wait_for_control(self, control_type, search_params, search_depth=1, timeout=30, retry_interval=0.5):
46
+ def wait_for_control(
47
+ self,
48
+ control_type,
49
+ search_params,
50
+ search_depth=1,
51
+ timeout=30,
52
+ retry_interval=0.5,
53
+ ):
41
54
  """
42
55
  Waits for a given control type to become available with the specified search parameters.
43
56
 
@@ -67,9 +80,13 @@ class BaseUI:
67
80
  time.sleep(retry_interval)
68
81
  print(f"Retrying to find control: {search_params}...")
69
82
 
70
- raise TimeoutError(f"Control with parameters {search_params} was not found within the {timeout} second timeout.")
83
+ raise TimeoutError(
84
+ f"Control with parameters {search_params} was not found within the {timeout} second timeout."
85
+ )
71
86
 
72
- def wait_for_control_to_disappear(self, control_type, search_params, search_depth=1, timeout=30):
87
+ def wait_for_control_to_disappear(
88
+ self, control_type, search_params, search_depth=1, timeout=30
89
+ ):
73
90
  """
74
91
  Waits for a given control type to disappear with the specified search parameters.
75
92
 
@@ -95,7 +112,9 @@ class BaseUI:
95
112
  time.sleep(0.5)
96
113
  print(f"Retrying to find control: {search_params}...")
97
114
 
98
- raise TimeoutError(f"Control with parameters {search_params} did not disappear within the timeout period.")
115
+ raise TimeoutError(
116
+ f"Control with parameters {search_params} did not disappear within the timeout period."
117
+ )
99
118
 
100
119
  def close_window(self, window_to_close: auto.WindowControl) -> None:
101
120
  """Closes specified window."""
@@ -105,7 +124,6 @@ class BaseUI:
105
124
 
106
125
  # Handle popup when closin main window
107
126
  if window_name.lower().startswith("hovedvindue"):
108
-
109
127
  pop_up_window = window_to_close.WindowControl(Name="TMT - Afslut")
110
128
  pop_up_window.SetFocus()
111
129
  pop_up_window.ButtonControl(Name="Ja").Click(simulateMove=False, waitTime=0)
@@ -113,4 +131,7 @@ class BaseUI:
113
131
  time.sleep(2)
114
132
 
115
133
  else:
116
- self.app_window = self.wait_for_control(search_params={'AutomationId': 'FormFront'}, control_type=auto.WindowControl)
134
+ self.app_window = self.wait_for_control(
135
+ search_params={"AutomationId": "FormFront"},
136
+ control_type=auto.WindowControl,
137
+ )
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: mbu_dev_shared_components
3
- Version: 4.1.0
3
+ Version: 4.2.1
4
4
  Summary: Shared components to use in RPA projects
5
5
  Author-email: MBU <rpa@mbu.aarhus.dk>
6
6
  License-Expression: MIT
@@ -12,6 +12,7 @@ License-File: LICENSE
12
12
  Requires-Dist: cryptography>=43.0.0
13
13
  Requires-Dist: pyodbc>=5.1.0
14
14
  Requires-Dist: python-dateutil==2.9.*
15
+ Requires-Dist: dotenv
15
16
  Provides-Extra: getorganized
16
17
  Requires-Dist: requests_ntlm>=1.2.0; extra == "getorganized"
17
18
  Provides-Extra: google
@@ -1,6 +1,7 @@
1
1
  cryptography>=43.0.0
2
2
  pyodbc>=5.1.0
3
3
  python-dateutil==2.9.*
4
+ dotenv
4
5
 
5
6
  [dev]
6
7
  pylint
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "mbu_dev_shared_components"
7
- version = "4.1.0"
7
+ version = "4.2.1"
8
8
  authors = [
9
9
  { name="MBU", email="rpa@mbu.aarhus.dk" },
10
10
  ]
@@ -20,6 +20,7 @@ dependencies = [
20
20
  "cryptography >= 43.0.0",
21
21
  "pyodbc >= 5.1.0",
22
22
  "python-dateutil == 2.9.*",
23
+ "dotenv",
23
24
  ]
24
25
 
25
26
  [project.optional-dependencies]