Created
March 8, 2023 08:10
-
-
Save solareon/a5247e107601fd58f049d32759dcad45 to your computer and use it in GitHub Desktop.
Unanet automatic timecard entry and creation
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| from datetime import datetime | |
| from playwright.sync_api import Playwright, sync_playwright | |
| def run(playwright: Playwright) -> None: | |
| # Define the URL of the login page and the target URL | |
| login_url = "https://<yourcompany>.unanet.biz/<yourcompany>/action/login/validate" | |
| target_url = "https://<yourcompany>.unanet.biz/<yourcompany>/action/home" | |
| logout_url = "https://<yourcompany>.unanet.biz/<yourcompany>/action/logout" | |
| # Set the login credentials | |
| username = 'username' | |
| password = 'password' | |
| daily_hours = 8 | |
| # Launch the browser and open a new context | |
| browser = playwright.chromium.launch(headless=True) | |
| context = browser.new_context() | |
| # Navigate to the login page and fill in the login form | |
| page = context.new_page() | |
| page.goto(login_url) | |
| page.fill('input[name="username"]', username) | |
| page.fill('input[name="password"]', password) | |
| # Click the login button and wait for the target page to load | |
| page.click('button[type="submit"]') | |
| page.wait_for_url(target_url) | |
| # Find the edit link based on the current date and navigate to the edit page | |
| today = datetime.today() | |
| edit_url = None | |
| links = page.query_selector_all('a[title^="Edit timesheet"]') | |
| for link in links: | |
| title = link.get_attribute('title') | |
| if title: | |
| title_parts = title.split(' ') | |
| start_date = datetime.strptime(title_parts[3], '%m/%d/%Y').date() | |
| end_date = datetime.strptime(title_parts[5], '%m/%d/%Y').date() | |
| if start_date <= today.date() <= end_date: | |
| href = link.get_attribute('href') | |
| edit_url = f"https://<yourcompany>.unanet.biz{href}" | |
| print(f"Edit URL: {edit_url}") | |
| if edit_url: | |
| page.goto(edit_url) | |
| # Wait for the timesheet to load | |
| page.wait_for_selector('tr[id^="r"]') | |
| # Find the first project row and update its name | |
| project_row = page.query_selector('tr[id^="r"]') | |
| # Find the cell for the current day and check if it's empty | |
| day_of_month = today.day | |
| cell_id = f'd_2_{day_of_month}' | |
| day_cell = project_row.query_selector(f'td[id="{cell_id}"]') | |
| day_hours_input = day_cell.query_selector('input[class*=hours]') | |
| day_hours = day_hours_input.get_attribute('value') | |
| if not day_hours: | |
| day_hours_input.fill(daily_hours) | |
| # Save the timesheet | |
| print("Hours for today: " + day_hours_input.get_attribute('value')) | |
| save_button = page.query_selector('button[id="button_save"]') | |
| save_button.click() | |
| print("Timesheet saved successfully") | |
| if day_hours: | |
| print("Hours for today: " + day_hours) | |
| # Wait for the timesheet to save and log out | |
| # page.wait_for_selector('button[name="button_logout"]') | |
| page.goto(logout_url) | |
| browser.close() | |
| print("Logged out successfully") | |
| else: | |
| print("Edit link not found for today's date. Creating a new timesheet...") | |
| # Create a new timesheet | |
| add_timesheet_link = page.query_selector('a[title="Create Timesheet"]') | |
| add_timesheet_link.click() | |
| # Wait for the new timesheet to load | |
| page.wait_for_selector('input[name="date"]') | |
| # Check if the date on the new timesheet matches today's date | |
| date_input = page.query_selector('input[name="date"]') | |
| date_value = date_input.get_attribute('value') | |
| date_value_parts = date_value.split('/') | |
| date_month = int(date_value_parts[0]) | |
| date_day = int(date_value_parts[1]) | |
| date_year = int(date_value_parts[2]) | |
| if date_month != today.month or date_day != today.day or date_year != today.year: | |
| new_date_value = today.strftime('%m/%d/%Y') | |
| date_input.fill(new_date_value) | |
| # Save the new timesheet | |
| save_button = page.query_selector('button[id="button_save"]') | |
| save_button.click() | |
| # Wait for the new timesheet to save | |
| page.wait_for_selector('tr[id^="r"]') | |
| # Find the project row and update its name | |
| project_row = page.query_selector('tr[id^="r"]') | |
| # Find the cell for the current day and fill in the hours | |
| day_of_month = today.day | |
| cell_id = f'd_2_{day_of_month}' | |
| day_cell = project_row.query_selector(f'td[id="{cell_id}"]') | |
| day_hours_input = day_cell.query_selector('input[class*=hours]') | |
| day_hours = day_hours_input.get_attribute('value') | |
| if not day_hours: | |
| day_hours_input.fill(daily_hours) | |
| # Save the timesheet | |
| save_button = page.query_selector('button[id="button_save"]') | |
| save_button.click() | |
| # Wait for the timesheet to save and log out | |
| page.wait_for_selector('button[name="button_logout"]') | |
| page.goto(logout_url) | |
| browser.close() | |
| print("New timesheet created and logged out successfully") | |
| with sync_playwright() as playwright: | |
| run(playwright) |
Author
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Automatically create and fill in a timecard for companies that use Unanet timekeeping. Leverages playwright due to javascript loading inline elements of the page. Targets the first timecard row and fills in the target hours. Unanet doesn't really see to care if we logout but we do anyway.
Will 100% break if you get a forced password change or change the charge code.