Skip to content

Commit 6c2d70b

Browse files
authored
Merge pull request #116 from itk-dev-rpa/feature/eflyt-letter
Added script for handling eflyt letters
2 parents fd46874 + 084deb8 commit 6c2d70b

File tree

3 files changed

+137
-1
lines changed

3 files changed

+137
-1
lines changed

changelog.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
77

88
## [Unreleased]
99

10+
### Added
11+
12+
- Eflyt: Added functions for sending letters.
13+
1014
## [2.13.0] - 2025-08-13
1115

1216
### Added
Lines changed: 132 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,132 @@
1+
"""This module contains functions for sending letters from a case in eFlyt."""
2+
3+
from selenium import webdriver
4+
from selenium.webdriver.common.by import By
5+
from selenium.webdriver.support.select import Select
6+
from selenium.webdriver.support.ui import WebDriverWait
7+
from selenium.webdriver.support import expected_conditions as EC
8+
from selenium.common.exceptions import TimeoutException
9+
10+
from itk_dev_shared_components.eflyt import eflyt_case
11+
12+
13+
def send_letter_to_anmelder(browser: webdriver.Chrome, letter_text: str) -> bool:
14+
"""Open the 'Breve' tab and send a letter to the anmelder using the 'Individuelt brev'-template.
15+
16+
Args:
17+
browser: The webdriver browser object.
18+
original_letter: The title of the original logiværtserklæring.
19+
20+
Returns:
21+
bool: True if the letter was sent.
22+
"""
23+
eflyt_case.change_tab(browser, tab_index=3)
24+
25+
click_letter_template(browser, "- Individuelt brev")
26+
27+
# Select the anmelder as the receiver
28+
select_letter_receiver(browser, "anmelder")
29+
30+
# Click 'Send brev'
31+
browser.find_element(By.ID, "ctl00_ContentPlaceHolder2_ptFanePerson_bcPersonTab_btnSendBrev").click()
32+
33+
# Insert the correct letter text
34+
text_area = browser.find_element(By.ID, "ctl00_ContentPlaceHolder2_ptFanePerson_bcPersonTab_txtStandardText")
35+
text_area.clear()
36+
text_area.send_keys(letter_text)
37+
# Click 'Ok'
38+
browser.find_element(By.ID, "ctl00_ContentPlaceHolder2_ptFanePerson_bcPersonTab_btnOK").click()
39+
40+
# Check if a warning appears
41+
if check_digital_post_warning(browser):
42+
# Click 'Nej'
43+
browser.find_element(By.ID, "ctl00_ContentPlaceHolder2_ptFanePerson_bcPersonTab_btnDeleteLetter").click()
44+
return False
45+
46+
# Click 'Ja'
47+
browser.find_element(By.ID, "ctl00_ContentPlaceHolder2_ptFanePerson_bcPersonTab_btnSaveLetter").click()
48+
return True
49+
50+
51+
def click_letter_template(browser: webdriver.Chrome, letter_name: str):
52+
"""Click the letter template with the given name under the "Breve" tab.
53+
54+
Args:
55+
browser: The webdriver browser object.
56+
letter_name: The literal name of the letter template to click.
57+
58+
Raises:
59+
ValueError: If the letter wasn't found in the list.
60+
"""
61+
letter_table = browser.find_element(By.ID, "ctl00_ContentPlaceHolder2_ptFanePerson_bcPersonTab_GridViewBreveNew")
62+
rows = letter_table.find_elements(By.TAG_NAME, "tr")
63+
64+
for row in rows:
65+
text = row.find_element(By.XPATH, "td[2]").text
66+
if text == letter_name:
67+
row.find_element(By.XPATH, "td[1]/input").click()
68+
return
69+
70+
raise ValueError(f"Template with the name '{letter_name}' was not found.")
71+
72+
73+
def select_letter_receiver(browser: webdriver.Chrome, receiver_name: str) -> None:
74+
"""Select the receiver for the letter. The search is fuzzy so it's only checked
75+
if the options contains the receiver name.
76+
77+
I some cases there's only one option for the receiver in which
78+
case there's a text label instead of a select element. In this
79+
case the predefined name is still checked against the desired receiver.
80+
81+
Args:
82+
browser: The webdriver browser object.
83+
receiver_name: The name of the receiver to select.
84+
85+
Raises:
86+
ValueError: If the given name isn't found in the select options.
87+
ValueError: If the given name doesn't match the static label.
88+
"""
89+
# Check if there is a select for the receiver name
90+
try:
91+
# Wait for the dropdown to be present
92+
name_select_element = WebDriverWait(browser, 2).until(
93+
EC.presence_of_element_located((By.ID, "ctl00_ContentPlaceHolder2_ptFanePerson_bcPersonTab_ddlModtager"))
94+
)
95+
name_select = Select(name_select_element)
96+
97+
# Wait until the dropdown has more than one option
98+
WebDriverWait(browser, 2).until(lambda browser: len(name_select.options) > 1)
99+
100+
for i, option in enumerate(name_select.options):
101+
if receiver_name in option.text:
102+
name_select.select_by_index(i)
103+
return
104+
105+
raise ValueError(f"'{receiver_name}' wasn't found on the list of possible receivers.")
106+
107+
except TimeoutException:
108+
pass # Continue to the next check if the dropdown is not found
109+
110+
# If there's simply a label for the receiver, check if the name matches
111+
try:
112+
name_label = WebDriverWait(browser, 2).until(
113+
EC.presence_of_element_located((By.ID, "ctl00_ContentPlaceHolder2_ptFanePerson_bcPersonTab_lblModtagerName"))
114+
)
115+
if receiver_name not in name_label.text:
116+
raise ValueError(f"'{receiver_name}' didn't match the predefined receiver.")
117+
except TimeoutException as exc:
118+
raise ValueError("Receiver name label did not load in time.") from exc
119+
120+
121+
def check_digital_post_warning(browser: webdriver.Chrome) -> bool:
122+
"""Check if a red warning text has appeared warning that
123+
a letter must be sent manually.
124+
125+
Args:
126+
browser: The webdriver browser object.
127+
128+
Returns:
129+
bool: True if the warning has appeared.
130+
"""
131+
warning_text = browser.find_elements(By.XPATH, "//font[@color='red']")
132+
return len(warning_text) != 0 and "Dokumentet skal sendes manuelt" in warning_text[0].text

itk_dev_shared_components/eflyt/eflyt_login.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
"""Module for logging into Eflyt/Daedalus/Whatchamacallit using Selenium"""
1+
"""Module for logging into Eflyt using Selenium"""
22
import time
33

44
from selenium import webdriver

0 commit comments

Comments
 (0)