Exemplo n.º 1
0
def ecase_login():
    """
        Establishes an instance of chrome in selenium.
        Navigates to eCase and logs in with credentials provided in constants.py
    """
    prefs = {'download.default_directory': rf'{constants.DOWNLOADS_DIR}'}
    try:
        options = webdriver.ChromeOptions()
        options.add_experimental_option('prefs', prefs)
        driver = webdriver.Chrome(options=options)
    except SessionNotCreatedException:
        return button_functions.popup_error(
            "Please contact the Datatec to update "
            "local ChromeDriver to the latest version")
    except WebDriverException:
        return button_functions.popup_error(
            "Please contact the Datatec to install "
            "Chromedriver.exe locally. PATH not set")

    driver.get(f'{constants.ECASE_URL}')
    user_name = driver.find_element_by_id('mod_login_username')
    user_password = driver.find_element_by_id('mod_login_password')
    user_name.clear()
    user_name.send_keys(f'{constants.ECASE_USERNAME}')
    user_password.clear()
    user_password.send_keys(f'{constants.ECASE_PASSWORD}')
    driver.find_element_by_name('loginButton').click()

    return driver
Exemplo n.º 2
0
def nhi_check(driver, nhi):
    """
    This inputs and searches for a specific NHI string.
    If the user does exist in ecase, it will return their page, and
    on all resident pages, there is a link at xpath
    //*[@id="formTab1"]/div[2]/h1/span/div/a[3]/u. This is the text 'Resident'.
    :param driver: selenium webdriver object
    :param nhi: String like 'AHF3980'. Three letters, followed by 4 numbers.
    :return:
    """
    driver.get(f'{constants.ECASE_URL}?action=search')
    driver.find_element_by_id('activeAndInactive').click()
    nhi = nhi.upper()
    nhi_field = driver.find_element_by_name('txtNHINumber')
    nhi_field.send_keys(nhi)
    driver.find_element_by_id('searchButton').click()

    try:
        driver.find_element(By.XPATH,
                            '//*[@id="formTab1"]/div[2]/h1/span/div/a[3]/u')

    except NoSuchElementException:
        driver.quit()
        files_remover('fs_')
        return button_functions.popup_error(
            "9001: NHI is incorrect, please check "
            "you've entered it correctly "
            "and the resident is set up correctly")
Exemplo n.º 3
0
def main_bowel_report(driver, wing: str, age: int):
    """
    Downloads file of bowel reports of specified wing,
    for the previous *age* month in the past i.e, 1 = previous month,
    2 = 2 months ago etc
    :param driver: selenium driver object
    :param wing: area
    :param age: number of months in the past
    :return:
    """
    search_reports(driver, 'bowel_report')

    month = (datetime.datetime.now() - datetime.timedelta(days=30 * age)).month
    year = (datetime.datetime.now() - datetime.timedelta(days=30 * age)).year
    month_spec = downloader_support_functions.date_selector(month, year)
    count = age

    wait = WebDriverWait(driver, 10)
    driver.implicitly_wait(10)
    try:
        driver.find_elements_by_id('generate').click()
    except NoSuchElementException:
        driver.quit()
        return button_functions.popup_error(
            "bowel report not available in the ecase report generator")

    fields = driver.find_elements_by_id('clause-field-0')
    date_from_fields = driver.find_elements_by_xpath(
        '//*[@id="clause-field-0-date"]')
    date_to_fields = driver.find_elements_by_xpath(
        '//*[@id="clause-field-1-date "]')
    fields[0].send_keys(wing)
    date_from_fields[1].click()

    downloader_support_functions.click_previous_month_button(driver, count)
    # finding the first available selectable date, and hovering to it
    first_available_date = wait.until(
        ec.element_to_be_clickable(
            (By.CSS_SELECTOR, f"body > div.Zebra_DatePicker.dp_visible > "
             f"table.dp_daypicker > tbody > tr:nth-child(2)"
             f" > td:nth-child({month_spec[1]})")))

    ActionChains(driver).move_to_element(first_available_date).perform()
    driver.find_element_by_css_selector(
        f"body > div.Zebra_DatePicker.dp_visible >"
        f" table.dp_daypicker > tbody > "
        f"tr:nth-child(2) > td:nth-child({month_spec[1]}) ").click()
    date_to_fields[1].click()

    downloader_support_functions.click_previous_month_button(driver, count)

    driver.find_element_by_css_selector(
        "body > div.Zebra_DatePicker.dp_visible > table.dp_daypicker > "
        f"tbody > tr:nth-child({month_spec[0]}) > td:nth-child({month_spec[2]}) "
    ).click()
    driver.implicitly_wait(10)
    driver.find_element(By.XPATH, '//*[@id="btn-generate"]').click()
Exemplo n.º 4
0
def ecase_birthdays(driver):
    """
        Downloads the report with ‘birthdayList’ in the name.
        Report has the list of resident birth dates
    """
    search_reports(driver, 'birthdayList_MCF')
    try:
        driver.find_element_by_id('generate').click()
    except NoSuchElementException:
        return button_functions.popup_error(
            "The Birthday list report is "
            "not available in the ecase report generator")
Exemplo n.º 5
0
def doctor_numbers_download(driver):
    """
        Downloads the report with ‘doctor’ in the name.
        Report has a list of residents and who their doctor is.
    """
    search_reports(driver, 'doctor_Numbers')
    try:
        driver.find_elements_by_id('generate')[0].click(
        )  #bug fixed on 22/07/2020, return list of button, added indexing [0]
    except NoSuchElementException:
        return button_functions.popup_error(
            "The Doctor numbers report is not "
            "available in the ecase report generator")
Exemplo n.º 6
0
def ecase_pi_risk(driver):
    """
    Downloads the pir_code from ecase reports that contains the customer codes for each resident
    """
    # Download the csv with all customer codes
    search_reports(driver, 'pir_code')
    while not os.path.isfile(rf'{constants.DOWNLOADS_DIR}\pir_code.csv'):
        try:
            driver.find_element_by_id('generate').click()
        except NoSuchElementException:
            driver.quit()
            return button_functions.popup_error(
                "pir_code report not available in the ecase report generator")
        except ElementClickInterceptedException:
            continue
Exemplo n.º 7
0
def ecase_data(driver):
    """
        Navigates to the report screen,
        and downloads all reports with the keyword ‘data’
    """
    search_reports(driver, 'data_')
    try:
        buttons = driver.find_elements_by_id('generate')
        for button in buttons:
            button.click()
            time.sleep(2)
            driver.implicitly_wait(10)

    except NoSuchElementException:
        driver.quit()
        files_remover('data_')
        return button_functions.popup_error(
            "Some or all data reports are not available in the ecase report generator"
        )
Exemplo n.º 8
0
def care_level_csv(driver):
    """
        Downloads reports with ‘pod_’ in the name. 
        Downloads the report ‘pod_MCF’, and ‘pod_Residents’,
        both with the level of care for each resident
    """
    search_reports(driver, 'pod_')
    try:
        buttons = driver.find_elements_by_id('generate')
        time.sleep(5)
        for button in buttons:
            button.click()
            time.sleep(2)
    except NoSuchElementException:
        driver.quit()
        files_remover('pod_')
        return button_functions.popup_error(
            "Some or all podiatry reports are "
            "not available in the ecase report generator")
Exemplo n.º 9
0
def ecase_movements(driver):
    """
        Downloads CSV of ‘temp_movements’.
        Handles the selecting of dates within eCase date selector,
        selects from 1 July 2018, till the end of the current month.
    """
    search_reports(driver, 'temp_movements')

    month_spec = downloader_support_functions.date_selector(
        datetime.datetime.now().month,
        datetime.datetime.now().year)

    driver.implicitly_wait(15)
    try:
        buttons = driver.find_elements_by_id('generate')  #.click()
        time.sleep(5)
        for button in buttons:
            button.click()
            time.sleep(2)
    except NoSuchElementException:
        driver.quit()
        return button_functions.popup_error(
            "The Temp movements report is not "
            "available in the ecase report generator")

    date_to_fields = driver.find_elements_by_xpath(
        '//*[@id="clause-field-1-date "]')

    date_to_fields[0].click()

    # clicking the date that we hovered over
    driver.find_element_by_css_selector(
        f"body > div.Zebra_DatePicker.dp_visible >"
        f" table.dp_daypicker > tbody > "
        f"tr:nth-child({month_spec[0]}) > "
        f"td:nth-child({month_spec[2]})").click()

    driver.implicitly_wait(15)
    driver.find_element(By.XPATH, '//*[@id="btn-generate"]').click()
Exemplo n.º 10
0
def resident_contacts(driver, nhi: str):
    """
        Downloads all reports starting with the name ‘fs’.
        Will be Resident info, and Resident Contact’s info
    """
    search_reports(driver, 'fs_')
    while not os.path.isfile(rf'{constants.DOWNLOADS_DIR}\fs_Res.csv'):
        try:
            buttons = driver.find_elements_by_id('generate')
            for button in buttons:
                button.click()
                driver.find_element_by_id('clause-field-0').send_keys(nhi)
                driver.find_element_by_id('btn-generate').click()
                time.sleep(2)
        except NoSuchElementException:
            driver.quit()
            files_remover('fs_')
            return button_functions.popup_error(
                "Some or all front sheet reports "
                "are not available in the ecase "
                "report generator")
        except ElementClickInterceptedException:
            continue
Exemplo n.º 11
0
def care_plan_audits_download(driver, wing: str):
    """
        Clicks the ‘Generate’ button,
        and enters the wing into the filter box,
        and downloads the subsequent report.
        Should be used in a loop of wings,
        in conjunction with eCase_Care_Plans_Audit.
        This is used in a loop within ButtonFunctions.py, to
        pass in each wing and download the wing's file. This file
        is then used to create a file with a sheet for each area
        and their care plan status.
    """
    search_reports(driver, 'cp_')
    driver.find_element_by_id('generate').click()
    driver.find_element_by_id('clause-field-0').send_keys(wing)
    try:
        driver.find_element_by_id('btn-generate').click()

    except NoSuchElementException:
        driver.quit()
        return button_functions.popup_error(
            "care plans report not available in"
            " the ecase report generator")
    time.sleep(2)
Exemplo n.º 12
0
def create_label_list():
    """
        Takes the fs_Res and fs_Con reports from eCase,
        and produces a formatted excel document for printing
        on a sheet of sticky labels. This won’t automatically
        print out the list, but it will open the formatted
        document to be printed from the bypass tray with the sticky labels.
        For Admissions officer and receptionist. 
    """
    try:
        sheet_book = Workbook()
        label_sheet = sheet_book.active

        doctors = ['Mascher', 'Jun', 'Mulgan', 'Hulley']

        styles.print_settings(label_sheet,
                              widths=[
                                  14.714, 8.88571, 8.88571, 13.286, 11, 14.714,
                                  8.88571, 8.88571, 13.286
                              ],
                              landscape=False)

        respite = False

        if os.path.isfile(rf'{constants.DOWNLOADS_DIR}\p_name.txt'):
            p_file = open(rf'{constants.DOWNLOADS_DIR}\p_name.txt')
            p_name = p_file.read()
            p_file.close()
        else:
            p_name = ''

        with open(rf'{constants.DOWNLOADS_DIR}\fs_Res.csv',
                  newline='') as basic_info:
            basic_info_data = csv.reader(basic_info,
                                         delimiter=',',
                                         quotechar='"')
            basic_data = list(basic_info_data)

            if not any(substring in basic_data[1][9] for substring in doctors):
                respite = True

        last_name = basic_data[1][2]

        if p_name == '':
            fore_names = basic_data[1][1] + ' ' + basic_data[1][3]
        else:
            fore_names = basic_data[1][1] + ' ' + basic_data[1][
                3] + f' ({p_name})'

        month = [
            '0', 'Jan', 'Feb', 'Mar', 'Apri', 'May', 'Jun', 'Jul', 'Aug',
            'Sep', 'Oct', 'Nov', 'Dec'
        ]
        date_of_birth = (
            f'{basic_data[1][4][8:10]}/'
            f'{month[int(basic_data[1][4][5:7])]}/'  #used to be basic_data[1][4][5:7], change to index and tranfer to month by the list month
            f'{basic_data[1][4][0:4]}')
        nhi = basic_data[1][10]
        gp = 'GP: ' + basic_data[1][9]
        sav = 'St Andrew\'s Village'
        room = basic_data[1][0]

        if respite:
            # #    Doctors numbers.  Drs dont want them on the labels anymore.
            # #         Except for respite.
            with open(rf'{constants.DOWNLOADS_DIR}\fs_Con.csv',
                      newline='') as contact_info:
                contact_info_data = csv.reader(contact_info,
                                               delimiter=',',
                                               quotechar='"')
                contact_data = list(contact_info_data)
                for row in contact_data[1:len(contact_data)]:
                    if row[9] == 'Medical Practitioner':
                        gp = 'GP: ' + row[0]
                        if row[7] != '':
                            gp = gp + ' ' + row[7]

                        elif row[6] != '':
                            gp = gp + ' ' + row[6]

                        elif row[5] != '':
                            gp = gp + ' ' + row[5]

                        else:
                            gp = gp + ' ' + 'No Number Present'

        surname_font = Font(name='Arial', size=11, bold=True)
        forename_font = Font(name='Arial', size=11)
        med_norm_font = Font(name='Arial', size=10)
        small_bold_font = Font(name='Arial', size=10, bold=True)
        room_font = Font(name='Arial', size=7)

        left_list = ['', last_name, date_of_birth, gp, sav]
        right_list = ['', fore_names, nhi, '', room]

        for i in range(40):
            label_sheet.row_dimensions[i].height = float(21.25)

        for label in range(8):
            for label_row in range(1, 5):
                coeff = (label * 5) + label_row
                label_sheet[f'A{coeff}'] = left_list[label_row]
                label_sheet[f'F{coeff}'] = left_list[label_row]
                label_sheet[f'D{coeff}'] = right_list[label_row]
                label_sheet[f'I{coeff}'] = right_list[label_row]

                if label_row == 1:
                    label_sheet[f'A{coeff}'].font = surname_font
                    label_sheet[f'F{coeff}'].font = surname_font
                    label_sheet[f'D{coeff}'].font = forename_font
                    label_sheet[f'I{coeff}'].font = forename_font
                    label_sheet[f'D{coeff}'].alignment = Alignment(
                        horizontal='right')
                    label_sheet[f'I{coeff}'].alignment = Alignment(
                        horizontal='right')

                if label_row == 2:
                    label_sheet[f'A{coeff}'].font = med_norm_font
                    label_sheet[f'F{coeff}'].font = med_norm_font
                    label_sheet[f'D{coeff}'].font = small_bold_font
                    label_sheet[f'I{coeff}'].font = small_bold_font
                    label_sheet[f'D{coeff}'].alignment = Alignment(
                        horizontal='right')
                    label_sheet[f'I{coeff}'].alignment = Alignment(
                        horizontal='right')

                if label_row == 3:
                    label_sheet[f'A{coeff}'].font = med_norm_font
                    label_sheet[f'F{coeff}'].font = med_norm_font

                if label_row == 4:
                    label_sheet[f'A{coeff}'].font = small_bold_font
                    label_sheet[f'F{coeff}'].font = small_bold_font
                    label_sheet[f'D{coeff}'].font = room_font
                    label_sheet[f'I{coeff}'].font = room_font
                    label_sheet[f'D{coeff}'].alignment = Alignment(
                        horizontal='right')
                    label_sheet[f'I{coeff}'].alignment = Alignment(
                        horizontal='right')

        label_sheet.print_area = 'A1:I39'
        label_sheet.page_margins.top = .6
        label_sheet.page_margins.right = 0.27
        label_sheet.page_margins.bottom = .52
        label_sheet.page_margins.left = .48

        sheet_book.save(rf'{constants.OUTPUTS_DIR}\label_sheet.xlsx')
        sheet_book.close()

        os.startfile(rf'{constants.OUTPUTS_DIR}\label_sheet.xlsx')

        info_files_remover()

    except PermissionError:
        info_files_remover()
        return button_functions.popup_error(
            "Could not print Label sheet, as"
            " the file has been opened by someone else")
Exemplo n.º 13
0
def create_door_label(no_print=False):
    """
        Takes the fs_Res and fs_Con reports from eCase,
        and prints a formatted Door Label to place on the front
        of the resident’s room
    """

    try:
        sheet_book = Workbook()
        door_sheet = sheet_book.active

        if os.path.isfile(rf'{constants.DOWNLOADS_DIR}\p_name.txt'):
            p_file = open(rf'{constants.DOWNLOADS_DIR}\p_name.txt')
            p_name = p_file.read()
            p_file.close()
        else:
            p_name = ''

        with open(rf'{constants.DOWNLOADS_DIR}\fs_Res.csv',
                  newline='') as basic_info:
            basic_info_data = csv.reader(basic_info,
                                         delimiter=',',
                                         quotechar='"')
            basic_data = list(basic_info_data)

        namecard_font = Font(size=36, bold=True, name='Arial')

        nhi_font = Font(size=28, bold=True, name='Copperplate Gothic Light')

        door_sheet['B6'] = basic_data[1][1] + ' ' + basic_data[1][
            3] + ' (' + p_name + ') ' + basic_data[1][2]
        door_sheet['B6'].font = namecard_font
        door_sheet['B6'].alignment = Alignment(horizontal='center',
                                               vertical='center',
                                               wrap_text=True)
        door_sheet.merge_cells(start_row=6,
                               start_column=2,
                               end_row=18,
                               end_column=10)
        door_sheet['C24'] = basic_data[1][2]
        door_sheet['C24'].font = nhi_font
        door_sheet['C27'] = basic_data[1][1]
        door_sheet['C27'].font = nhi_font
        door_sheet['C29'] = basic_data[1][3]
        door_sheet['C29'].font = nhi_font
        door_sheet['C35'] = 'NHI No:'
        door_sheet['C35'].font = nhi_font
        door_sheet['F35'] = basic_data[1][10]
        door_sheet['F35'].font = nhi_font

        # # # Inserting Resident Photo
        for file in os.listdir(rf'{constants.DOWNLOADS_DIR}'):
            if re.match(r"^[A-Z]{3}[0-9]{4} Photo\.", file):
                photoname = file
                profile = Image(rf'{constants.DOWNLOADS_DIR}\{photoname}')
                profile.anchor = 'H21'
                profile.height = 212
                profile.width = 192
                door_sheet.add_image(profile)
                sheet_book.save(rf'{constants.OUTPUTS_DIR}\door_label.xlsx')

        styles.full_border(door_sheet, 'B6:J18', border=['double'])
        styles.full_border(door_sheet, 'B21:J38', border=['double'])

        door_sheet.print_area = 'A5:K39'
        styles.print_settings(door_sheet, landscape=False)
        sheet_book.save(rf'{constants.OUTPUTS_DIR}\door_label.xlsx')
        sheet_book.close()

        if not no_print:
            os.startfile(rf'{constants.OUTPUTS_DIR}\door_label.xlsx', 'print')

        info_files_remover()
    except PermissionError:
        info_files_remover()
        return button_functions.popup_error(
            "Could not print Door Label, as"
            " the file has been opened by someone")
Exemplo n.º 14
0
def create_front_sheet(village=False, no_print=False, nurses=False):
    """
        Takes the fs_Res and fs_Con reports from eCase,
        and produces a formatted front sheet for use in admission files.
        Prints out 2 copies with banking account information,
        and 1 without for the admission filing.
        This is for the Admission officer and accountants
    """
    sheet_book = Workbook()
    front_sheet = sheet_book.active

    basic_info_index = [
        'D6', 'D8', 'D9', 'D10', 'D12', 'D13', 'D14', 'D15', 'D16', 'I10',
        'I13', 'I14', 'I15', 'I16'
    ]

    epoa_info_index = [
        'D21', 'D23', 'D24', 'D25', 'D26', 'I21', 'I23', 'I24', 'I25', 'I26'
    ]

    contact_info_index = [
        'D31', 'D33', 'D35', 'D36', 'D37', 'D40', 'D41', 'D42', 'D43', 'I31',
        'I33', 'I35', 'I36', 'I37', 'I40', 'I41', 'I42', 'I43'
    ]

    funeral_info_index = [
        'D47', 'D48', 'I47', 'D51', 'D53', 'D54', 'D55', 'D57', 'D58', 'D59',
        'D60', 'I51', 'I53', 'I54', 'I55', 'I57', 'I58', 'I59', 'I60'
    ]
    # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #

    #  headings
    main_heading_font = Font(size=14, bold=True, italic=True, color='000080')
    headings_font = Font(size=10, bold=True, italic=True, color='008000')
    sheet_titles_font = Font(size=10, bold=True, underline='single')

    sheet_headings = {
        'RESIDENTS INFORMATION FRONT SHEET': 'B4',
        'ENDURING POWER OF ATTORNEY DETAILS': 'B19',
        'CONTACTS FOR HEALTH AND WELFARE DECISIONS': 'B29',
        'FUNERAL DIRECTOR': 'B46'
    }

    sheet_titles = {
        'Health and Welfare': 'B20',
        'Property': 'G20',
        'First Contact': 'B30',
        'Second Contact': 'G30',
        'Send Monthly SAV Account to': 'B50',
        'Send Monthly Trust Account to': 'G50'
    }

    basic_info_fields = {
        'Location at SAV': 'B6',
        'Title': 'B8',
        'Surname': 'B9',
        'Forenames': 'B10',
        'Preferred Name': 'B11',
        'Date of Birth': 'B12',
        'Place of Birth': 'B13',
        'Religion': 'B14',
        'Gender': 'B15',
        'Marital Status': 'B16',
        'Doctor at SAV': 'G10',
        'Telephone No.': 'G11',
        'NHI No': 'G13',
        'Date Admitted': 'G14',
        'Care Level': 'G15',
        'Ethnic Group': 'G16'
    }

    #  This is for two contacts
    epoa_info_fields = {
        'B21': 'Name',
        'B23': 'Home Phone',
        'B24': 'Work Phone',
        'B25': 'Mobile Phone',
        'B26': 'E-mail',
        'G21': 'Name',
        'G23': 'Home Phone',
        'G24': 'Work Phone',
        'G25': 'Mobile Phone',
        'G26': 'E-mail'
    }

    #  This is for the Primary and secondary contacts
    contact_info_fields = {
        'B31': 'Name',
        'B33': 'Relationship',
        'B35': 'Address',
        'B40': 'Home Phone',
        'B41': 'Work Phone',
        'B42': 'Mobile Phone',
        'B43': 'E-mail',
        'G31': 'Name',
        'G33': 'Relationship',
        'G35': 'Address',
        'G40': 'Home Phone',
        'G41': 'Work Phone',
        'G42': 'Mobile Phone',
        'G43': 'E-mail'
    }

    #  Funeral Director. Additional Monthly SAV and Trust account contact
    funeral_info_fields = {
        'B47': 'Company Name',
        'B48': 'Phone Number',
        'G47': 'Type of Service',
        'B51': 'Name',
        'B53': 'Address',
        'B57': 'Home Phone',
        'B58': 'Work Phone',
        'B59': 'Mobile Phone',
        'B60': 'E-mail',
        'G51': 'Name',
        'G53': 'Address',
        'G57': 'Home Phone',
        'G58': 'Work Phone',
        'G59': 'Mobile Phone',
        'G60': 'E-mail'
    }

    front_sheet['B1'].font = main_heading_font

    #  sheet headings writing to sheet & setting text styles
    for heading in sheet_headings:
        front_sheet[sheet_headings[heading]] = heading
        front_sheet[sheet_headings[heading]].font = headings_font

    #  sheet titles writing to sheet & setting text style
    for title in sheet_titles:
        front_sheet[sheet_titles[title]] = title
        front_sheet[sheet_titles[title]].font = sheet_titles_font

    # Writing the basic info headers into the file
    for info in basic_info_fields:
        front_sheet[basic_info_fields[info]] = info

    #  EPOA Details writing to sheet
    for epoa in epoa_info_fields:
        front_sheet[epoa] = epoa_info_fields[epoa]

    #  Contact info writing to sheet# # #
    for contact in contact_info_fields:
        front_sheet[contact] = contact_info_fields[contact]

    #  Funeral director info writing to sheet
    for funeral_info in funeral_info_fields:
        front_sheet[funeral_info] = funeral_info_fields[funeral_info]

    #  sheet image writing to sheet & positioning
    logo = Image(
        r'J:\Quality Data\Data Technician\eCase Migration\ecase_automated\images/SAVLandscape.png'
    )
    logo.anchor = 'A1'
    logo.width = 250
    logo.height = 40
    front_sheet.add_image(logo)
    sheet_book.save(rf'{constants.OUTPUTS_DIR}\front_sheet.xlsx')

    #  Setting text borders for whole sheet
    styles.full_border(front_sheet, 'D6')

    styles.full_border(front_sheet, 'D8:D11')
    styles.full_border(front_sheet, 'D12:D17')
    styles.full_border(front_sheet, 'I10:I11')
    styles.full_border(front_sheet, 'I13:I17')

    styles.full_border(front_sheet, 'D21')
    styles.full_border(front_sheet, 'D23:D26')
    styles.full_border(front_sheet, 'I21')
    styles.full_border(front_sheet, 'I23:I26')

    styles.full_border(front_sheet, 'D31')
    styles.full_border(front_sheet, 'D33')
    styles.full_border(front_sheet, 'D35:D38')
    styles.full_border(front_sheet, 'D40:D43')
    styles.full_border(front_sheet, 'I31')
    styles.full_border(front_sheet, 'I33')
    styles.full_border(front_sheet, 'I35:I38')
    styles.full_border(front_sheet, 'I40:I43')

    styles.full_border(front_sheet, 'D47:D48')
    styles.full_border(front_sheet, 'I47')

    styles.full_border(front_sheet, 'D51')
    styles.full_border(front_sheet, 'I51')
    styles.full_border(front_sheet, 'D53:D55')
    styles.full_border(front_sheet, 'I53:I55')
    styles.full_border(front_sheet, 'D57:D60')
    styles.full_border(front_sheet, 'I57:I60')

    #  Column widths
    styles.print_settings(
        front_sheet,
        widths=[0.15, 17.0, .15, 23.0, 4.15, 4.15, 16.0, .15, 28.0],
        landscape=False)

    respite = False

    #  Basic Resident info Writing to sheet# # #
    doctors = ['Mascher', 'Jun', 'Mulgan', 'Hulley']

    if os.path.isfile(rf'{constants.DOWNLOADS_DIR}\p_name.txt'):
        p_file = open(rf'{constants.DOWNLOADS_DIR}\p_name.txt')
        p_name = p_file.read()
        p_file.close()
    else:
        p_name = ''

    front_sheet['D11'] = p_name

    with open(rf'{constants.DOWNLOADS_DIR}\fs_Res.csv',
              newline='') as basic_info:
        basic_info_data = csv.reader(basic_info, delimiter=',', quotechar='"')
        basic_data = list(basic_info_data)
        try:
            if 'Andrew' in basic_data[1][0]:
                basic_data[1][0] = basic_data[1][0][20:len(basic_data[1][0])]

            if not any(substring in basic_data[1][9] for substring in doctors):
                respite = True
            month = [
                '0', 'Jan', 'Feb', 'Mar', 'Apri', 'May', 'Jun', 'Jul', 'Aug',
                'Sep', 'Oct', 'Nov', 'Dec'
            ]
            for cell in basic_info_index:
                front_sheet[cell] = basic_data[1][basic_info_index.index(cell)]
                if cell == 'D12':
                    front_sheet[cell] = (
                        f'{basic_data[1][4][8:10]}/'
                        f'{month[int(basic_data[1][4][5:7])]}/'
                        f'{basic_data[1][4][0:4]}')

                if cell == 'I14':
                    front_sheet[cell] = (
                        f'{basic_data[1][11][8:10]}/'
                        f'{month[int(basic_data[1][11][5:7])]}/'
                        f'{basic_data[1][11][0:4]}')

        except IndexError:
            info_files_remover()
            return button_functions.popup_error(
                "9002: NHI is incorrect, please check you've entered it correctly "
                "and the resident is set up correctly with that NHI")

        except ValueError:  #if date is empty
            front_sheet[cell] = "Not Available"
            pass

    for file in os.listdir(rf'{constants.DOWNLOADS_DIR}'):
        if re.match(r"^[A-Z]{3}[0-9]{4} Photo\.", file):
            photoname = file
            profile = Image(rf'{constants.DOWNLOADS_DIR}\{photoname}')
            profile.anchor = 'I2'
            profile.height = 140
            profile.width = 100
            front_sheet.add_image(profile)
            sheet_book.save(rf'{constants.OUTPUTS_DIR}\front_sheet.xlsx')

    with open(rf'{constants.DOWNLOADS_DIR}\fs_Con.csv',
              newline='') as contact_info:
        contact_info_data = csv.reader(contact_info,
                                       delimiter=',',
                                       quotechar='"')
        contact_data = list(contact_info_data)
        for row in contact_data[1:len(contact_data)]:
            if row[9] == 'First Contact':
                for cell in contact_info_index[0:9]:
                    front_sheet[cell] = row[contact_info_index.index(cell)]

            elif row[9] == 'Second Contact':
                for cell in contact_info_index[9:18]:
                    front_sheet[cell] = row[contact_info_index.index(cell) - 9]

            elif row[9] == 'EPA Welfare':
                front_sheet[epoa_info_index[0]] = row[0]
                front_sheet[epoa_info_index[1]] = row[5]
                front_sheet[epoa_info_index[2]] = row[6]
                front_sheet[epoa_info_index[3]] = row[7]
                front_sheet[epoa_info_index[4]] = row[8]

            elif row[9] == 'EPA Property':
                front_sheet[epoa_info_index[5]] = row[0]
                front_sheet[epoa_info_index[6]] = row[5]
                front_sheet[epoa_info_index[7]] = row[6]
                front_sheet[epoa_info_index[8]] = row[7]
                front_sheet[epoa_info_index[9]] = row[8]

            elif row[9] == 'Funeral Director':
                front_sheet[funeral_info_index[0]] = row[0]
                front_sheet[funeral_info_index[1]] = row[6]

            elif row[9] == 'Send Fees Account' or row[9] == 'Billing':
                front_sheet[funeral_info_index[3]] = row[0]
                front_sheet[funeral_info_index[4]] = row[2]
                front_sheet[funeral_info_index[5]] = row[3]
                front_sheet[funeral_info_index[6]] = row[4]
                front_sheet[funeral_info_index[7]] = row[5]
                front_sheet[funeral_info_index[8]] = row[6]
                front_sheet[funeral_info_index[9]] = row[7]
                front_sheet[funeral_info_index[10]] = row[8]

            elif row[9] == 'Send Trust Account' or row[9] == 'Guaranator':
                front_sheet[funeral_info_index[11]] = row[0]
                front_sheet[funeral_info_index[12]] = row[2]
                front_sheet[funeral_info_index[13]] = row[3]
                front_sheet[funeral_info_index[14]] = row[4]
                front_sheet[funeral_info_index[15]] = row[5]
                front_sheet[funeral_info_index[16]] = row[6]
                front_sheet[funeral_info_index[17]] = row[7]
                front_sheet[funeral_info_index[18]] = row[8]

            elif row[9] == 'Resident':
                front_sheet['B17'] = 'Email'
                front_sheet['D17'] = row[8]
                front_sheet['G17'] = 'Contact Number'
                front_sheet['I17'] = row[5]

            # Doctors numbers.  SAV Drs dont want them on the front sheet anymore
            if respite:
                if row[9] == 'Medical Practitioner':
                    if row[7] != '':
                        front_sheet['I11'] = row[7]

                    elif row[6] != '':
                        front_sheet['I11'] = row[6]

                    elif row[5] != '':
                        front_sheet['I11'] = row[5]

                    else:
                        front_sheet['I11'] = 'No Number Present'
    try:
        #  Printing out Frontsheet without monthly accounts fields
        # For Everyone
        front_sheet.print_area = 'B1:I48'
        sheet_book.save(rf'{constants.OUTPUTS_DIR}\front_sheet.xlsx')
        if not no_print:
            os.startfile(rf'{constants.OUTPUTS_DIR}\front_sheet.xlsx', 'print')
            # Second info copy just for village nurses
            if nurses:
                os.startfile(rf'{constants.OUTPUTS_DIR}\front_sheet.xlsx',
                             'print')

        #  Printing out Frontsheet with monthly accounts fields
        # For Admissions and Village manager
        front_sheet.print_area = 'B1:I60'
        sheet_book.save(rf'{constants.OUTPUTS_DIR}\front_sheet.xlsx')
        if not no_print:
            if not nurses:
                os.startfile(rf'{constants.OUTPUTS_DIR}\front_sheet.xlsx',
                             'print')

        # Just for admissions
        if not no_print:
            if not village and not nurses:
                # print an extra accounts page if in the MCF
                os.startfile(rf'{constants.OUTPUTS_DIR}\front_sheet.xlsx',
                             'print')

        sheet_book.save(rf'{constants.OUTPUTS_DIR}\front_sheet.xlsx')
        sheet_book.close()

        info_files_remover()

    except PermissionError:
        info_files_remover()
        return button_functions.popup_error(
            "Could not print front sheets, as"
            " the file has been opened by someone")