|
| 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 |
0 commit comments