diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json index 5d4179b..1402349 100644 --- a/.devcontainer/devcontainer.json +++ b/.devcontainer/devcontainer.json @@ -19,10 +19,12 @@ "extensions": [ "eamodio.gitlens", "esbenp.prettier-vscode", + "mechatroner.rainbow-csv", "mhutchie.git-graph", "ms-python.python", "ms-python.black-formatter", "ms-python.flake8", + "ms-toolsai.jupyter", "tamasfe.even-better-toml" ] } diff --git a/.env.sample b/.env.sample new file mode 100644 index 0000000..2b01856 --- /dev/null +++ b/.env.sample @@ -0,0 +1,5 @@ +HARVEST_CLIENT_NAME=Client1 +HARVEST_DATA=data/harvest-sample.csv +TOGGL_DATA=data/toggl-sample.csv +TOGGL_PROJECT_INFO=data/toggl-project-info-sample.json +TOGGL_USER_INFO=data/toggl-user-info-sample.json diff --git a/.gitignore b/.gitignore index 30e1f60..7408caa 100644 --- a/.gitignore +++ b/.gitignore @@ -4,6 +4,12 @@ __pycache__ !.config/README.md .coverage .downloads +.env .pytest_cache *.csv *.egg-info +notebooks/data/* +!notebooks/data/harvest-sample.csv +!notebooks/data/toggl-project-info-sample.json +!notebooks/data/toggl-sample.csv +!notebooks/data/toggl-user-info-sample.json diff --git a/compiler_admin/__init__.py b/compiler_admin/__init__.py index 1a914db..8ff2840 100644 --- a/compiler_admin/__init__.py +++ b/compiler_admin/__init__.py @@ -1,5 +1,8 @@ from importlib.metadata import version, PackageNotFoundError +RESULT_SUCCESS = 0 +RESULT_FAILURE = 1 + try: __version__ = version("compiler_admin") except PackageNotFoundError: diff --git a/compiler_admin/commands/__init__.py b/compiler_admin/commands/__init__.py index 2cfbde3..e69de29 100644 --- a/compiler_admin/commands/__init__.py +++ b/compiler_admin/commands/__init__.py @@ -1,2 +0,0 @@ -RESULT_SUCCESS = 0 -RESULT_FAILURE = 1 diff --git a/compiler_admin/commands/convert.py b/compiler_admin/commands/convert.py index 049620f..6e877c1 100644 --- a/compiler_admin/commands/convert.py +++ b/compiler_admin/commands/convert.py @@ -1,6 +1,6 @@ from argparse import Namespace -from compiler_admin.commands import RESULT_SUCCESS, RESULT_FAILURE +from compiler_admin import RESULT_SUCCESS, RESULT_FAILURE from compiler_admin.services.google import ( GROUP_PARTNERS, GROUP_STAFF, diff --git a/compiler_admin/commands/create.py b/compiler_admin/commands/create.py index d1ac860..6576e26 100644 --- a/compiler_admin/commands/create.py +++ b/compiler_admin/commands/create.py @@ -1,7 +1,7 @@ from argparse import Namespace from typing import Sequence -from compiler_admin.commands import RESULT_SUCCESS, RESULT_FAILURE +from compiler_admin import RESULT_SUCCESS, RESULT_FAILURE from compiler_admin.services.google import GROUP_TEAM, add_user_to_group, CallGAMCommand, user_account_name, user_exists diff --git a/compiler_admin/commands/delete.py b/compiler_admin/commands/delete.py index 6a32565..ac5efc1 100644 --- a/compiler_admin/commands/delete.py +++ b/compiler_admin/commands/delete.py @@ -1,6 +1,6 @@ from argparse import Namespace -from compiler_admin.commands import RESULT_SUCCESS, RESULT_FAILURE +from compiler_admin import RESULT_SUCCESS, RESULT_FAILURE from compiler_admin.services.google import CallGAMCommand, user_account_name, user_exists diff --git a/compiler_admin/commands/info.py b/compiler_admin/commands/info.py index 419bede..7548952 100644 --- a/compiler_admin/commands/info.py +++ b/compiler_admin/commands/info.py @@ -1,5 +1,4 @@ -from compiler_admin import __version__ as version -from compiler_admin.commands import RESULT_SUCCESS, RESULT_FAILURE +from compiler_admin import __version__ as version, RESULT_SUCCESS, RESULT_FAILURE from compiler_admin.services.google import CallGAMCommand, CallGYBCommand diff --git a/compiler_admin/commands/init.py b/compiler_admin/commands/init.py index c431684..fde1f80 100644 --- a/compiler_admin/commands/init.py +++ b/compiler_admin/commands/init.py @@ -4,7 +4,7 @@ from shutil import rmtree import subprocess -from compiler_admin.commands import RESULT_FAILURE, RESULT_SUCCESS +from compiler_admin import RESULT_FAILURE, RESULT_SUCCESS from compiler_admin.services.google import USER_ARCHIVE, CallGAMCommand diff --git a/compiler_admin/commands/offboard.py b/compiler_admin/commands/offboard.py index 6f52abd..7c473cd 100644 --- a/compiler_admin/commands/offboard.py +++ b/compiler_admin/commands/offboard.py @@ -1,7 +1,7 @@ from argparse import Namespace from tempfile import NamedTemporaryFile -from compiler_admin.commands import RESULT_SUCCESS, RESULT_FAILURE +from compiler_admin import RESULT_SUCCESS, RESULT_FAILURE from compiler_admin.commands.delete import delete from compiler_admin.commands.signout import signout from compiler_admin.services.google import ( diff --git a/compiler_admin/commands/reset_password.py b/compiler_admin/commands/reset_password.py index 610d38f..023df31 100644 --- a/compiler_admin/commands/reset_password.py +++ b/compiler_admin/commands/reset_password.py @@ -1,6 +1,6 @@ from argparse import Namespace -from compiler_admin.commands import RESULT_SUCCESS, RESULT_FAILURE +from compiler_admin import RESULT_SUCCESS, RESULT_FAILURE from compiler_admin.commands.signout import signout from compiler_admin.services.google import USER_HELLO, CallGAMCommand, user_account_name, user_exists diff --git a/compiler_admin/commands/restore.py b/compiler_admin/commands/restore.py index 4ee3527..1c56e95 100644 --- a/compiler_admin/commands/restore.py +++ b/compiler_admin/commands/restore.py @@ -1,7 +1,7 @@ from argparse import Namespace import pathlib -from compiler_admin.commands import RESULT_SUCCESS, RESULT_FAILURE +from compiler_admin import RESULT_SUCCESS, RESULT_FAILURE from compiler_admin.services.google import USER_ARCHIVE, CallGYBCommand, user_account_name diff --git a/compiler_admin/commands/signout.py b/compiler_admin/commands/signout.py index 657be90..e204578 100644 --- a/compiler_admin/commands/signout.py +++ b/compiler_admin/commands/signout.py @@ -1,6 +1,6 @@ from argparse import Namespace -from compiler_admin.commands import RESULT_SUCCESS, RESULT_FAILURE +from compiler_admin import RESULT_SUCCESS, RESULT_FAILURE from compiler_admin.services.google import CallGAMCommand, user_account_name, user_exists diff --git a/compiler_admin/services/google.py b/compiler_admin/services/google.py index d93f713..50ae080 100644 --- a/compiler_admin/services/google.py +++ b/compiler_admin/services/google.py @@ -3,6 +3,8 @@ from tempfile import NamedTemporaryFile from typing import Any, Sequence, IO +from compiler_admin import RESULT_SUCCESS + # import and alias CallGAMCommand so we can simplify usage in this app from gam import CallGAMCommand as __CallGAMCommand, initializeLogging @@ -96,9 +98,38 @@ def user_exists(username: str) -> bool: print(f"User not in domain: {username}") return False - res = CallGAMCommand(("info", "user", username, "quick")) + info = user_info(username) + + return info != {} + - return res == 0 +def user_info(username: str) -> dict: + """Get a dict of basic user information. + + Args: + username (str): The user@compiler.la to get. + Returns: + A dict of user information + """ + if not str(username).endswith(DOMAIN): + print(f"User not in domain: {username}") + return {} + + with NamedTemporaryFile("w+") as stdout: + res = CallGAMCommand(("info", "user", username, "quick"), stdout=stdout.name) + if res != RESULT_SUCCESS: + # user doesn't exist + return {} + # user exists, read data + lines = stdout.readlines() + # split on newline and filter out lines that aren't line "Key:Value" and empty value lines like "Key:" + lines = [L.strip() for L in lines if len(L.split(":")) == 2 and L.split(":")[1].strip()] + # make a map by splitting the lines, trimming key and value + info = {} + for line in lines: + k, v = line.split(":") + info[k.strip()] = v.strip() + return info def user_in_group(username: str, group: str) -> bool: diff --git a/notebooks/data/harvest-sample.csv b/notebooks/data/harvest-sample.csv new file mode 100644 index 0000000..771b61b --- /dev/null +++ b/notebooks/data/harvest-sample.csv @@ -0,0 +1,251 @@ +Date,Client,Project,Project Code,Task,Notes,Hours,Billable?,Invoiced?,Approved?,First Name,Last Name,Roles,Employee?,External Reference URL +2023-01-21,Client1,Project5,PROJECT,Project Consulting,nascetur ridiculus mus etiam vel augue vestibulum rutrum rutrum neque aenean auctor gravida sem praesent id massa id nisl venenatis lacinia aenean sit,2.51,true,false,false,Hetti,Becken,Team Member,true, +2023-01-07,Client1,Project4,PROJECT,Project Consulting,quam a odio in hac habitasse platea dictumst maecenas ut massa quis augue luctus tincidunt nulla mollis molestie lorem quisque ut erat curabitur,1.84,false,true,false,Sawyer,Berrey,Team Member,false, +2023-01-25,Client1,Project5,PROJECT,Project Consulting,odio odio elementum eu interdum eu tincidunt in leo maecenas pulvinar lobortis est,2.11,true,false,true,Silas,Idenden,Team Member,true, +2023-01-08,Client1,Project3,PROJECT,Project Consulting,in purus eu magna vulputate luctus,1.61,false,true,true,Silas,Idenden,Team Member,true, +2023-01-18,Client1,Project1,PROJECT,Project Consulting,nec sem duis aliquam convallis nunc proin at turpis a pede posuere nonummy integer non velit donec diam neque,1.72,true,false,true,Hetti,Becken,Team Member,false, +2023-01-11,Client1,Project3,PROJECT,Project Consulting,varius nulla facilisi cras non velit nec nisi vulputate nonummy maecenas tincidunt lacus at velit,3.16,true,true,false,Aymer,Hauck,Team Member,false, +2023-01-29,Client1,Project5,PROJECT,Project Consulting,aliquam convallis nunc proin at turpis a pede posuere nonummy,0.33,false,true,false,Hetti,Becken,Team Member,false, +2023-01-26,Client1,Project2,PROJECT,Project Consulting,volutpat erat quisque erat eros viverra eget congue eget semper rutrum nulla nunc purus phasellus in felis donec semper sapien,3.58,true,false,false,Aymer,Hauck,Team Member,true, +2023-01-14,Client1,Project7,PROJECT,Project Consulting,morbi vestibulum velit id pretium iaculis diam,3.0,false,true,false,Silas,Idenden,Team Member,true, +2023-01-13,Client1,Project6,PROJECT,Project Consulting,blandit ultrices enim lorem ipsum dolor sit amet consectetuer adipiscing elit,0.68,false,true,false,Silas,Idenden,Team Member,false, +2023-01-20,Client1,Project1,PROJECT,Project Consulting,tincidunt eu felis fusce posuere felis sed lacus morbi sem mauris laoreet ut rhoncus aliquet pulvinar sed nisl nunc rhoncus dui,2.72,false,false,false,Aymer,Hauck,Team Member,false, +2023-01-24,Client1,Project6,PROJECT,Project Consulting,duis aliquam convallis nunc proin at turpis,2.76,true,false,true,Silas,Idenden,Team Member,false, +2023-01-26,Client1,Project4,PROJECT,Project Consulting,nam congue risus semper porta volutpat quam pede lobortis ligula sit,2.48,true,false,false,Gusella,Swaile,Team Member,true, +2023-01-24,Client1,Project7,PROJECT,Project Consulting,aliquet massa id lobortis convallis tortor risus dapibus augue vel accumsan tellus nisi eu orci mauris lacinia sapien quis libero nullam sit amet turpis elementum,2.23,true,true,false,Aymer,Hauck,Team Member,false, +2023-01-24,Client1,Project3,PROJECT,Project Consulting,odio consequat varius integer ac leo pellentesque ultrices mattis odio,0.92,true,true,true,Hetti,Becken,Team Member,false, +2023-01-15,Client1,Project6,PROJECT,Project Consulting,dis parturient montes nascetur ridiculus mus etiam vel augue vestibulum rutrum,3.14,false,true,false,Silas,Idenden,Team Member,true, +2023-01-22,Client1,Project4,PROJECT,Project Consulting,quis odio consequat varius integer ac leo pellentesque ultrices,3.43,false,false,false,Hetti,Becken,Team Member,false, +2023-01-08,Client1,Project4,PROJECT,Project Consulting,sed magna at nunc commodo placerat praesent blandit nam nulla integer pede justo lacinia eget tincidunt,2.01,true,false,true,Aymer,Hauck,Team Member,true, +2023-01-04,Client1,Project1,PROJECT,Project Consulting,eget elit sodales scelerisque mauris sit amet eros suspendisse accumsan tortor quis turpis,2.84,true,false,false,Hetti,Becken,Team Member,false, +2023-01-27,Client1,Project6,PROJECT,Project Consulting,blandit non interdum in ante vestibulum ante,1.83,true,false,false,Silas,Idenden,Team Member,false, +2023-01-30,Client1,Project4,PROJECT,Project Consulting,eget eros elementum pellentesque quisque porta volutpat erat quisque erat eros viverra eget congue eget semper rutrum nulla nunc purus,1.8,false,false,false,Aymer,Hauck,Team Member,true, +2023-01-11,Client1,Project1,PROJECT,Project Consulting,maecenas ut massa quis augue luctus tincidunt nulla mollis molestie lorem quisque ut erat curabitur gravida nisi at nibh,0.83,true,true,false,Aymer,Hauck,Team Member,false, +2023-01-09,Client1,Project1,PROJECT,Project Consulting,quis lectus suspendisse potenti in eleifend quam a odio in hac habitasse,3.83,true,true,false,Hetti,Becken,Team Member,true, +2023-01-30,Client1,Project3,PROJECT,Project Consulting,vestibulum sit amet cursus id turpis integer aliquet massa id lobortis convallis tortor risus dapibus augue vel accumsan tellus nisi eu orci,1.07,false,false,false,Hetti,Becken,Team Member,true, +2023-01-19,Client1,Project1,PROJECT,Project Consulting,faucibus orci luctus et ultrices posuere cubilia curae donec pharetra,3.9,false,false,true,Aymer,Hauck,Team Member,true, +2023-01-02,Client1,Project7,PROJECT,Project Consulting,in faucibus orci luctus et ultrices posuere cubilia curae nulla dapibus dolor vel est donec odio justo sollicitudin ut suscipit a feugiat et eros vestibulum,0.57,true,true,false,Hetti,Becken,Team Member,true, +2023-01-06,Client1,Project7,PROJECT,Project Consulting,nec nisi vulputate nonummy maecenas tincidunt lacus at velit vivamus vel nulla eget eros elementum pellentesque quisque porta volutpat,2.2,true,false,false,Hetti,Becken,Team Member,true, +2023-01-07,Client1,Project5,PROJECT,Project Consulting,nulla suspendisse potenti cras in purus eu,1.24,true,false,true,Aymer,Hauck,Team Member,true, +2023-01-23,Client1,Project5,PROJECT,Project Consulting,nec nisi vulputate nonummy maecenas tincidunt lacus at velit vivamus vel nulla eget eros elementum pellentesque quisque porta volutpat erat quisque erat eros,0.34,true,true,false,Silas,Idenden,Team Member,false, +2023-01-17,Client1,Project4,PROJECT,Project Consulting,luctus rutrum nulla tellus in sagittis dui vel nisl duis,1.59,true,false,false,Gusella,Swaile,Team Member,false, +2023-01-10,Client1,Project2,PROJECT,Project Consulting,blandit nam nulla integer pede justo,0.5,true,true,false,Hetti,Becken,Team Member,false, +2023-01-21,Client1,Project6,PROJECT,Project Consulting,convallis nulla neque libero convallis eget eleifend luctus ultricies eu nibh quisque id justo sit amet sapien,2.22,false,false,true,Gusella,Swaile,Team Member,true, +2023-01-23,Client1,Project7,PROJECT,Project Consulting,tortor sollicitudin mi sit amet lobortis sapien sapien non,3.29,false,true,false,Gusella,Swaile,Team Member,true, +2023-01-11,Client1,Project6,PROJECT,Project Consulting,gravida sem praesent id massa id nisl venenatis lacinia aenean sit amet justo morbi ut odio cras mi pede malesuada in imperdiet et commodo vulputate,2.21,false,false,true,Gusella,Swaile,Team Member,false, +2023-01-24,Client1,Project5,PROJECT,Project Consulting,vulputate elementum nullam varius nulla facilisi cras non velit nec nisi vulputate nonummy,2.28,false,true,false,Sawyer,Berrey,Team Member,false, +2023-01-18,Client1,Project4,PROJECT,Project Consulting,imperdiet nullam orci pede venenatis non sodales sed tincidunt eu felis fusce,1.67,false,false,false,Sawyer,Berrey,Team Member,false, +2023-01-12,Client1,Project5,PROJECT,Project Consulting,massa quis augue luctus tincidunt nulla mollis molestie lorem,1.55,true,false,false,Hetti,Becken,Team Member,false, +2023-01-02,Client1,Project3,PROJECT,Project Consulting,nulla justo aliquam quis turpis eget elit sodales scelerisque mauris sit amet eros suspendisse accumsan tortor quis turpis sed ante vivamus tortor duis mattis,2.98,false,false,true,Aymer,Hauck,Team Member,true, +2023-01-14,Client1,Project5,PROJECT,Project Consulting,pede justo lacinia eget tincidunt eget tempus vel pede morbi porttitor lorem id ligula,2.33,false,true,true,Silas,Idenden,Team Member,false, +2023-01-09,Client1,Project1,PROJECT,Project Consulting,donec pharetra magna vestibulum aliquet ultrices erat tortor sollicitudin mi sit amet lobortis sapien sapien,1.03,false,true,true,Sawyer,Berrey,Team Member,true, +2023-01-21,Client1,Project4,PROJECT,Project Consulting,ac lobortis vel dapibus at diam nam tristique tortor eu pede,0.21,true,true,false,Gusella,Swaile,Team Member,true, +2023-01-05,Client1,Project1,PROJECT,Project Consulting,cursus vestibulum proin eu mi nulla ac enim in tempor,3.79,false,true,false,Gusella,Swaile,Team Member,true, +2023-01-25,Client1,Project6,PROJECT,Project Consulting,neque aenean auctor gravida sem praesent id massa id nisl venenatis lacinia aenean sit amet justo morbi ut,3.86,true,false,true,Gusella,Swaile,Team Member,true, +2023-01-13,Client1,Project4,PROJECT,Project Consulting,et commodo vulputate justo in blandit ultrices enim lorem ipsum dolor sit amet consectetuer adipiscing elit proin interdum mauris non,3.82,false,false,false,Aymer,Hauck,Team Member,true, +2023-01-10,Client1,Project1,PROJECT,Project Consulting,nulla quisque arcu libero rutrum ac lobortis vel dapibus at diam nam tristique,0.98,true,false,true,Gusella,Swaile,Team Member,true, +2023-01-27,Client1,Project5,PROJECT,Project Consulting,egestas metus aenean fermentum donec ut mauris eget massa tempor,2.54,false,true,true,Gusella,Swaile,Team Member,true, +2023-01-14,Client1,Project4,PROJECT,Project Consulting,feugiat et eros vestibulum ac est lacinia nisi venenatis tristique fusce congue diam id ornare imperdiet sapien urna pretium nisl ut volutpat sapien arcu,2.11,false,true,false,Sawyer,Berrey,Team Member,false, +2023-01-18,Client1,Project4,PROJECT,Project Consulting,tortor duis mattis egestas metus aenean fermentum donec ut mauris eget,2.74,false,false,true,Silas,Idenden,Team Member,false, +2023-01-12,Client1,Project7,PROJECT,Project Consulting,eget eros elementum pellentesque quisque porta volutpat erat quisque erat eros,2.19,false,true,false,Hetti,Becken,Team Member,false, +2023-01-30,Client1,Project4,PROJECT,Project Consulting,volutpat erat quisque erat eros viverra eget congue eget semper rutrum nulla,2.73,true,true,true,Gusella,Swaile,Team Member,false, +2023-01-05,Client1,Project7,PROJECT,Project Consulting,malesuada in imperdiet et commodo vulputate justo in blandit,0.84,true,true,false,Gusella,Swaile,Team Member,false, +2023-01-16,Client1,Project2,PROJECT,Project Consulting,erat id mauris vulputate elementum nullam varius nulla facilisi,3.18,true,true,true,Sawyer,Berrey,Team Member,false, +2023-01-12,Client1,Project3,PROJECT,Project Consulting,vel augue vestibulum rutrum rutrum neque aenean auctor gravida,2.42,false,true,false,Hetti,Becken,Team Member,true, +2023-01-21,Client1,Project5,PROJECT,Project Consulting,in tempor turpis nec euismod scelerisque quam turpis adipiscing lorem vitae mattis nibh ligula nec sem,0.56,false,true,true,Gusella,Swaile,Team Member,false, +2023-01-23,Client1,Project6,PROJECT,Project Consulting,elementum in hac habitasse platea dictumst morbi vestibulum velit id pretium iaculis diam erat fermentum justo nec condimentum neque,1.07,true,true,true,Sawyer,Berrey,Team Member,false, +2023-01-25,Client1,Project4,PROJECT,Project Consulting,elementum pellentesque quisque porta volutpat erat quisque erat eros viverra eget congue eget semper rutrum nulla nunc purus phasellus in felis,2.48,false,true,false,Silas,Idenden,Team Member,false, +2023-01-12,Client1,Project4,PROJECT,Project Consulting,morbi a ipsum integer a nibh,1.4,false,false,true,Aymer,Hauck,Team Member,true, +2023-01-04,Client1,Project3,PROJECT,Project Consulting,aliquet at feugiat non pretium quis,2.36,false,true,false,Sawyer,Berrey,Team Member,false, +2023-01-26,Client1,Project4,PROJECT,Project Consulting,id ornare imperdiet sapien urna pretium nisl ut volutpat sapien arcu sed augue aliquam erat volutpat in congue etiam justo etiam pretium iaculis justo in,1.26,false,true,true,Sawyer,Berrey,Team Member,false, +2023-01-09,Client1,Project5,PROJECT,Project Consulting,at turpis donec posuere metus vitae ipsum aliquam non mauris morbi non lectus aliquam sit amet diam in magna bibendum imperdiet nullam orci pede venenatis,0.47,true,true,true,Gusella,Swaile,Team Member,false, +2023-01-06,Client1,Project1,PROJECT,Project Consulting,vehicula consequat morbi a ipsum integer a nibh in quis justo maecenas rhoncus aliquam lacus morbi quis,2.25,true,false,true,Aymer,Hauck,Team Member,true, +2023-01-12,Client1,Project3,PROJECT,Project Consulting,pede malesuada in imperdiet et commodo vulputate justo in blandit ultrices enim lorem ipsum dolor sit amet consectetuer adipiscing elit proin interdum mauris non ligula,3.84,false,false,true,Aymer,Hauck,Team Member,true, +2023-01-12,Client1,Project3,PROJECT,Project Consulting,curae duis faucibus accumsan odio curabitur convallis duis consequat dui nec,2.06,true,false,true,Sawyer,Berrey,Team Member,true, +2023-01-27,Client1,Project7,PROJECT,Project Consulting,hac habitasse platea dictumst aliquam augue quam,2.93,true,true,false,Silas,Idenden,Team Member,false, +2023-01-07,Client1,Project5,PROJECT,Project Consulting,praesent blandit nam nulla integer pede justo lacinia eget tincidunt eget tempus vel pede morbi porttitor lorem id ligula suspendisse ornare consequat lectus in,2.42,false,false,false,Silas,Idenden,Team Member,false, +2023-01-26,Client1,Project5,PROJECT,Project Consulting,sit amet eleifend pede libero quis orci nullam molestie nibh in lectus pellentesque at nulla suspendisse,2.65,true,false,true,Aymer,Hauck,Team Member,true, +2023-01-08,Client1,Project5,PROJECT,Project Consulting,porttitor lacus at turpis donec posuere metus vitae ipsum aliquam non mauris morbi non lectus aliquam,1.55,true,true,true,Sawyer,Berrey,Team Member,false, +2023-01-06,Client1,Project4,PROJECT,Project Consulting,leo maecenas pulvinar lobortis est phasellus sit amet erat nulla tempus vivamus in felis eu sapien cursus vestibulum proin eu,3.49,false,false,false,Aymer,Hauck,Team Member,true, +2023-01-27,Client1,Project4,PROJECT,Project Consulting,nullam orci pede venenatis non sodales sed tincidunt eu,3.67,true,true,true,Silas,Idenden,Team Member,true, +2023-01-23,Client1,Project7,PROJECT,Project Consulting,congue vivamus metus arcu adipiscing molestie hendrerit at vulputate vitae nisl aenean lectus pellentesque eget nunc donec quis orci eget orci,0.23,false,true,false,Sawyer,Berrey,Team Member,false, +2023-01-30,Client1,Project1,PROJECT,Project Consulting,nibh quisque id justo sit amet sapien dignissim vestibulum vestibulum ante ipsum primis in faucibus orci luctus et,3.53,true,true,false,Silas,Idenden,Team Member,false, +2023-01-28,Client1,Project6,PROJECT,Project Consulting,nec euismod scelerisque quam turpis adipiscing lorem vitae mattis nibh ligula nec,2.13,true,true,true,Aymer,Hauck,Team Member,true, +2023-01-11,Client1,Project3,PROJECT,Project Consulting,maecenas tristique est et tempus semper est,1.62,false,true,true,Sawyer,Berrey,Team Member,true, +2023-01-04,Client1,Project7,PROJECT,Project Consulting,vehicula condimentum curabitur in libero ut massa volutpat convallis morbi odio odio elementum eu interdum eu tincidunt in leo maecenas,0.8,false,false,false,Sawyer,Berrey,Team Member,true, +2023-01-22,Client1,Project5,PROJECT,Project Consulting,nonummy integer non velit donec diam neque vestibulum eget vulputate ut ultrices vel augue vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere,3.41,false,true,false,Hetti,Becken,Team Member,true, +2023-01-16,Client1,Project3,PROJECT,Project Consulting,nonummy integer non velit donec diam neque vestibulum eget vulputate ut ultrices vel augue vestibulum ante,0.74,false,false,true,Sawyer,Berrey,Team Member,true, +2023-01-22,Client1,Project7,PROJECT,Project Consulting,interdum mauris non ligula pellentesque ultrices phasellus id sapien in sapien iaculis,1.47,true,true,true,Sawyer,Berrey,Team Member,false, +2023-01-30,Client1,Project2,PROJECT,Project Consulting,dui vel sem sed sagittis nam congue risus semper porta volutpat quam pede lobortis ligula sit amet eleifend,3.01,false,true,false,Gusella,Swaile,Team Member,false, +2023-01-26,Client1,Project3,PROJECT,Project Consulting,ligula vehicula consequat morbi a ipsum,3.81,true,false,false,Hetti,Becken,Team Member,true, +2023-01-05,Client1,Project6,PROJECT,Project Consulting,aenean auctor gravida sem praesent id massa id nisl venenatis lacinia aenean sit amet justo morbi ut odio cras mi pede malesuada in imperdiet,2.68,false,true,true,Silas,Idenden,Team Member,true, +2023-01-09,Client1,Project1,PROJECT,Project Consulting,et ultrices posuere cubilia curae nulla dapibus dolor vel est donec odio justo sollicitudin ut suscipit a,2.63,true,false,true,Gusella,Swaile,Team Member,true, +2023-01-28,Client1,Project4,PROJECT,Project Consulting,amet lobortis sapien sapien non mi,3.72,true,true,true,Gusella,Swaile,Team Member,true, +2023-01-07,Client1,Project5,PROJECT,Project Consulting,vehicula condimentum curabitur in libero ut massa volutpat convallis morbi odio odio elementum eu interdum eu tincidunt in leo maecenas,1.24,false,false,true,Hetti,Becken,Team Member,true, +2023-01-03,Client1,Project1,PROJECT,Project Consulting,praesent blandit lacinia erat vestibulum,1.51,true,false,true,Hetti,Becken,Team Member,true, +2023-01-03,Client1,Project3,PROJECT,Project Consulting,elementum ligula vehicula consequat morbi a ipsum integer a nibh in quis justo,3.14,false,false,false,Aymer,Hauck,Team Member,false, +2023-01-24,Client1,Project6,PROJECT,Project Consulting,porttitor lorem id ligula suspendisse ornare consequat lectus,3.34,false,false,true,Silas,Idenden,Team Member,true, +2023-01-17,Client1,Project3,PROJECT,Project Consulting,ante nulla justo aliquam quis turpis eget elit sodales scelerisque mauris sit amet eros suspendisse accumsan tortor quis,2.19,true,false,false,Gusella,Swaile,Team Member,true, +2023-01-07,Client1,Project6,PROJECT,Project Consulting,nunc viverra dapibus nulla suscipit ligula in lacus curabitur at ipsum ac tellus semper interdum mauris ullamcorper purus sit amet nulla,2.76,false,false,false,Hetti,Becken,Team Member,true, +2023-01-14,Client1,Project3,PROJECT,Project Consulting,in faucibus orci luctus et ultrices posuere cubilia curae donec pharetra magna vestibulum aliquet ultrices erat tortor sollicitudin mi sit amet lobortis,0.91,false,false,false,Aymer,Hauck,Team Member,true, +2023-01-17,Client1,Project2,PROJECT,Project Consulting,cras pellentesque volutpat dui maecenas tristique est et tempus semper est quam pharetra magna ac consequat metus sapien,2.42,true,true,true,Silas,Idenden,Team Member,true, +2023-01-14,Client1,Project6,PROJECT,Project Consulting,bibendum felis sed interdum venenatis turpis enim blandit mi,1.27,true,false,true,Sawyer,Berrey,Team Member,false, +2023-01-06,Client1,Project5,PROJECT,Project Consulting,nibh ligula nec sem duis aliquam convallis,0.91,false,true,true,Silas,Idenden,Team Member,true, +2023-01-17,Client1,Project5,PROJECT,Project Consulting,vestibulum sagittis sapien cum sociis natoque,3.86,true,true,false,Silas,Idenden,Team Member,true, +2023-01-20,Client1,Project2,PROJECT,Project Consulting,diam neque vestibulum eget vulputate ut ultrices vel augue vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia curae donec pharetra,2.43,false,true,true,Hetti,Becken,Team Member,false, +2023-01-23,Client1,Project7,PROJECT,Project Consulting,id luctus nec molestie sed justo pellentesque viverra pede ac diam cras pellentesque volutpat dui maecenas tristique est et tempus semper est quam,1.57,false,true,true,Sawyer,Berrey,Team Member,true, +2023-01-03,Client1,Project4,PROJECT,Project Consulting,aliquet maecenas leo odio condimentum id luctus nec molestie sed justo pellentesque viverra pede ac diam cras pellentesque volutpat dui maecenas tristique est,2.06,false,false,true,Sawyer,Berrey,Team Member,true, +2023-01-16,Client1,Project4,PROJECT,Project Consulting,eu massa donec dapibus duis at velit eu,1.25,true,true,false,Sawyer,Berrey,Team Member,false, +2023-01-18,Client1,Project3,PROJECT,Project Consulting,aliquam sit amet diam in magna bibendum imperdiet nullam orci pede venenatis non sodales sed tincidunt eu,1.63,true,true,true,Sawyer,Berrey,Team Member,false, +2023-01-29,Client1,Project3,PROJECT,Project Consulting,vestibulum sagittis sapien cum sociis natoque penatibus et magnis dis parturient montes nascetur ridiculus mus etiam vel augue vestibulum,3.51,false,true,true,Gusella,Swaile,Team Member,true, +2023-01-25,Client1,Project6,PROJECT,Project Consulting,id nulla ultrices aliquet maecenas leo odio condimentum id luctus nec molestie sed justo pellentesque,3.64,true,false,false,Hetti,Becken,Team Member,false, +2023-01-06,Client1,Project2,PROJECT,Project Consulting,at nunc commodo placerat praesent blandit,3.42,false,false,false,Silas,Idenden,Team Member,false, +2023-01-13,Client1,Project7,PROJECT,Project Consulting,varius ut blandit non interdum in ante vestibulum ante ipsum,1.1,true,true,false,Hetti,Becken,Team Member,true, +2023-01-02,Client1,Project3,PROJECT,Project Consulting,elit proin interdum mauris non ligula pellentesque ultrices phasellus id sapien in sapien iaculis congue vivamus metus arcu adipiscing molestie hendrerit at,0.71,false,false,false,Hetti,Becken,Team Member,true, +2023-01-05,Client1,Project3,PROJECT,Project Consulting,dolor vel est donec odio justo sollicitudin ut suscipit a feugiat et eros vestibulum ac est lacinia,3.48,true,false,false,Gusella,Swaile,Team Member,false, +2023-01-18,Client1,Project3,PROJECT,Project Consulting,auctor sed tristique in tempus sit,1.9,false,false,false,Hetti,Becken,Team Member,false, +2023-01-05,Client1,Project7,PROJECT,Project Consulting,ornare imperdiet sapien urna pretium nisl ut volutpat sapien arcu sed augue aliquam erat volutpat in congue etiam justo etiam pretium iaculis justo,2.43,true,true,false,Gusella,Swaile,Team Member,false, +2023-01-26,Client1,Project2,PROJECT,Project Consulting,et ultrices posuere cubilia curae donec pharetra magna vestibulum aliquet ultrices erat tortor sollicitudin mi sit amet lobortis sapien sapien,3.04,true,true,true,Gusella,Swaile,Team Member,true, +2023-01-27,Client1,Project1,PROJECT,Project Consulting,consequat nulla nisl nunc nisl duis bibendum felis sed interdum venenatis turpis enim blandit mi in porttitor pede,3.21,false,false,false,Gusella,Swaile,Team Member,true, +2023-01-06,Client1,Project7,PROJECT,Project Consulting,feugiat et eros vestibulum ac est lacinia nisi venenatis tristique fusce congue diam id ornare imperdiet sapien urna pretium nisl ut volutpat sapien,0.59,false,false,true,Sawyer,Berrey,Team Member,false, +2023-01-13,Client1,Project6,PROJECT,Project Consulting,aliquam augue quam sollicitudin vitae consectetuer eget rutrum at lorem integer tincidunt ante vel ipsum praesent blandit lacinia erat vestibulum sed magna at,2.04,false,false,false,Hetti,Becken,Team Member,false, +2023-01-25,Client1,Project6,PROJECT,Project Consulting,vestibulum eget vulputate ut ultrices vel augue vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia curae donec pharetra,2.03,true,false,true,Hetti,Becken,Team Member,false, +2023-01-22,Client1,Project1,PROJECT,Project Consulting,sollicitudin mi sit amet lobortis sapien sapien non mi integer,0.08,true,true,true,Hetti,Becken,Team Member,true, +2023-01-13,Client1,Project6,PROJECT,Project Consulting,platea dictumst morbi vestibulum velit id pretium iaculis diam erat fermentum justo nec condimentum neque sapien placerat ante nulla justo aliquam quis turpis eget,1.12,true,true,false,Sawyer,Berrey,Team Member,false, +2023-01-20,Client1,Project7,PROJECT,Project Consulting,quis turpis eget elit sodales scelerisque mauris sit amet eros suspendisse accumsan tortor quis turpis sed ante vivamus,3.76,false,true,false,Aymer,Hauck,Team Member,true, +2023-01-26,Client1,Project3,PROJECT,Project Consulting,eget eros elementum pellentesque quisque porta volutpat erat quisque erat eros viverra eget congue eget semper rutrum nulla nunc purus phasellus in felis donec,0.88,true,false,true,Gusella,Swaile,Team Member,true, +2023-01-05,Client1,Project2,PROJECT,Project Consulting,sapien placerat ante nulla justo aliquam quis turpis eget elit sodales scelerisque,1.26,true,true,true,Silas,Idenden,Team Member,true, +2023-01-30,Client1,Project6,PROJECT,Project Consulting,ante vivamus tortor duis mattis egestas metus aenean fermentum donec ut mauris eget massa tempor convallis,1.94,true,false,false,Silas,Idenden,Team Member,false, +2023-01-15,Client1,Project7,PROJECT,Project Consulting,vulputate justo in blandit ultrices,3.61,true,false,false,Gusella,Swaile,Team Member,false, +2023-01-15,Client1,Project4,PROJECT,Project Consulting,viverra pede ac diam cras pellentesque volutpat dui maecenas tristique est et,0.05,true,true,false,Silas,Idenden,Team Member,false, +2023-01-07,Client1,Project1,PROJECT,Project Consulting,in purus eu magna vulputate luctus cum sociis natoque penatibus et magnis dis parturient montes nascetur ridiculus mus vivamus vestibulum sagittis sapien cum sociis natoque,3.16,true,true,false,Hetti,Becken,Team Member,true, +2023-01-25,Client1,Project2,PROJECT,Project Consulting,nibh in lectus pellentesque at,2.14,true,true,true,Sawyer,Berrey,Team Member,true, +2023-01-16,Client1,Project4,PROJECT,Project Consulting,vestibulum proin eu mi nulla ac enim in tempor,2.99,true,false,true,Silas,Idenden,Team Member,true, +2023-01-20,Client1,Project6,PROJECT,Project Consulting,metus sapien ut nunc vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia curae mauris viverra diam vitae quam suspendisse potenti nullam,1.31,true,true,true,Silas,Idenden,Team Member,true, +2023-01-08,Client1,Project3,PROJECT,Project Consulting,curae mauris viverra diam vitae quam suspendisse potenti nullam porttitor lacus at turpis donec posuere metus vitae ipsum aliquam non mauris morbi non,2.59,false,true,false,Sawyer,Berrey,Team Member,false, +2023-01-26,Client1,Project5,PROJECT,Project Consulting,in felis eu sapien cursus vestibulum proin eu mi nulla ac enim,2.42,false,true,true,Gusella,Swaile,Team Member,false, +2023-01-15,Client1,Project3,PROJECT,Project Consulting,luctus cum sociis natoque penatibus et magnis dis parturient montes nascetur ridiculus mus vivamus,1.66,true,false,true,Sawyer,Berrey,Team Member,true, +2023-01-26,Client1,Project2,PROJECT,Project Consulting,convallis nulla neque libero convallis eget eleifend luctus ultricies eu nibh,1.3,false,false,true,Gusella,Swaile,Team Member,false, +2023-01-06,Client1,Project2,PROJECT,Project Consulting,sit amet eleifend pede libero quis orci nullam molestie nibh in lectus pellentesque at nulla suspendisse potenti cras in purus eu magna,3.69,false,true,false,Hetti,Becken,Team Member,false, +2023-01-10,Client1,Project6,PROJECT,Project Consulting,curae donec pharetra magna vestibulum aliquet ultrices erat tortor sollicitudin mi sit amet lobortis sapien sapien non mi integer ac neque duis bibendum morbi non,2.67,true,true,false,Aymer,Hauck,Team Member,true, +2023-01-18,Client1,Project1,PROJECT,Project Consulting,ullamcorper augue a suscipit nulla elit ac nulla sed,0.53,false,true,false,Gusella,Swaile,Team Member,true, +2023-01-11,Client1,Project7,PROJECT,Project Consulting,elementum pellentesque quisque porta volutpat erat quisque erat eros viverra eget congue eget semper rutrum nulla nunc purus phasellus in,1.92,true,true,false,Sawyer,Berrey,Team Member,true, +2023-01-14,Client1,Project6,PROJECT,Project Consulting,interdum mauris non ligula pellentesque ultrices phasellus id sapien in sapien iaculis congue vivamus metus arcu adipiscing molestie hendrerit at,4.0,true,false,false,Hetti,Becken,Team Member,false, +2023-01-03,Client1,Project2,PROJECT,Project Consulting,praesent blandit nam nulla integer pede,0.7,false,false,true,Silas,Idenden,Team Member,true, +2023-01-21,Client1,Project5,PROJECT,Project Consulting,vivamus in felis eu sapien cursus vestibulum,2.42,true,false,false,Sawyer,Berrey,Team Member,true, +2023-01-11,Client1,Project7,PROJECT,Project Consulting,blandit ultrices enim lorem ipsum dolor sit amet consectetuer adipiscing elit proin interdum mauris non ligula pellentesque ultrices phasellus id sapien in,2.54,false,false,false,Aymer,Hauck,Team Member,true, +2023-01-13,Client1,Project3,PROJECT,Project Consulting,sapien varius ut blandit non interdum in ante vestibulum ante ipsum primis in faucibus,0.22,false,false,true,Hetti,Becken,Team Member,true, +2023-01-25,Client1,Project6,PROJECT,Project Consulting,consequat lectus in est risus auctor sed tristique in tempus sit amet,2.83,true,true,false,Aymer,Hauck,Team Member,false, +2023-01-26,Client1,Project5,PROJECT,Project Consulting,ultrices posuere cubilia curae mauris viverra diam,1.51,false,true,true,Silas,Idenden,Team Member,true, +2023-01-14,Client1,Project6,PROJECT,Project Consulting,viverra diam vitae quam suspendisse potenti nullam porttitor lacus at,3.07,true,true,true,Gusella,Swaile,Team Member,false, +2023-01-29,Client1,Project7,PROJECT,Project Consulting,ut at dolor quis odio consequat varius integer,3.39,false,true,false,Sawyer,Berrey,Team Member,false, +2023-01-24,Client1,Project5,PROJECT,Project Consulting,ut blandit non interdum in,0.44,false,false,true,Silas,Idenden,Team Member,true, +2023-01-18,Client1,Project4,PROJECT,Project Consulting,faucibus orci luctus et ultrices posuere,1.14,true,false,true,Silas,Idenden,Team Member,false, +2023-01-06,Client1,Project3,PROJECT,Project Consulting,vitae nisi nam ultrices libero non mattis pulvinar nulla pede ullamcorper augue a suscipit,0.44,false,false,true,Sawyer,Berrey,Team Member,false, +2023-01-11,Client1,Project7,PROJECT,Project Consulting,ac consequat metus sapien ut nunc vestibulum ante ipsum primis in faucibus,0.69,false,false,false,Silas,Idenden,Team Member,false, +2023-01-09,Client1,Project5,PROJECT,Project Consulting,nulla integer pede justo lacinia eget tincidunt eget,1.98,false,true,true,Sawyer,Berrey,Team Member,true, +2023-01-07,Client1,Project4,PROJECT,Project Consulting,quam a odio in hac habitasse platea dictumst maecenas ut massa quis augue luctus tincidunt nulla mollis molestie lorem quisque,0.69,false,false,false,Gusella,Swaile,Team Member,true, +2023-01-13,Client1,Project6,PROJECT,Project Consulting,id ornare imperdiet sapien urna pretium nisl ut volutpat sapien arcu sed augue aliquam erat volutpat,1.87,true,false,false,Gusella,Swaile,Team Member,true, +2023-01-29,Client1,Project1,PROJECT,Project Consulting,quis turpis sed ante vivamus tortor duis mattis egestas metus aenean fermentum donec,0.21,false,false,true,Hetti,Becken,Team Member,false, +2023-01-30,Client1,Project1,PROJECT,Project Consulting,pellentesque ultrices phasellus id sapien in sapien iaculis congue vivamus metus arcu adipiscing molestie hendrerit at vulputate vitae nisl aenean lectus pellentesque eget nunc,0.33,true,false,false,Sawyer,Berrey,Team Member,false, +2023-01-21,Client1,Project3,PROJECT,Project Consulting,nec sem duis aliquam convallis nunc proin at turpis a pede posuere nonummy integer non velit donec diam,3.75,false,true,true,Aymer,Hauck,Team Member,true, +2023-01-12,Client1,Project1,PROJECT,Project Consulting,eu interdum eu tincidunt in leo maecenas pulvinar lobortis est phasellus sit amet erat nulla tempus,1.01,true,false,true,Sawyer,Berrey,Team Member,false, +2023-01-21,Client1,Project1,PROJECT,Project Consulting,placerat ante nulla justo aliquam quis turpis eget elit sodales scelerisque mauris sit amet eros suspendisse accumsan,1.33,false,true,false,Hetti,Becken,Team Member,true, +2023-01-18,Client1,Project7,PROJECT,Project Consulting,ac diam cras pellentesque volutpat dui maecenas tristique est et tempus semper est quam pharetra magna ac consequat metus sapien ut nunc,3.8,false,true,false,Aymer,Hauck,Team Member,true, +2023-01-25,Client1,Project5,PROJECT,Project Consulting,sed nisl nunc rhoncus dui vel sem sed sagittis nam congue risus semper porta volutpat quam pede lobortis ligula sit amet eleifend pede,2.58,false,false,true,Aymer,Hauck,Team Member,true, +2023-01-08,Client1,Project2,PROJECT,Project Consulting,lobortis convallis tortor risus dapibus augue vel accumsan tellus nisi eu orci mauris lacinia sapien quis libero nullam sit amet,1.33,true,true,false,Silas,Idenden,Team Member,true, +2023-01-28,Client1,Project3,PROJECT,Project Consulting,felis sed lacus morbi sem mauris laoreet ut rhoncus aliquet pulvinar sed,3.92,true,false,true,Hetti,Becken,Team Member,true, +2023-01-09,Client1,Project1,PROJECT,Project Consulting,enim leo rhoncus sed vestibulum sit amet cursus id turpis integer,1.53,true,true,true,Hetti,Becken,Team Member,true, +2023-01-15,Client1,Project7,PROJECT,Project Consulting,eros vestibulum ac est lacinia,2.14,true,false,true,Gusella,Swaile,Team Member,true, +2023-01-05,Client1,Project1,PROJECT,Project Consulting,justo sollicitudin ut suscipit a feugiat et eros,2.68,false,false,true,Aymer,Hauck,Team Member,false, +2023-01-21,Client1,Project1,PROJECT,Project Consulting,cursus id turpis integer aliquet massa id lobortis convallis tortor risus dapibus augue,0.26,true,false,false,Aymer,Hauck,Team Member,false, +2023-01-21,Client1,Project6,PROJECT,Project Consulting,mattis odio donec vitae nisi nam ultrices libero non mattis pulvinar nulla pede ullamcorper augue a suscipit nulla elit ac nulla,1.64,true,false,true,Hetti,Becken,Team Member,true, +2023-01-22,Client1,Project1,PROJECT,Project Consulting,pulvinar lobortis est phasellus sit amet erat nulla tempus vivamus in felis eu sapien cursus vestibulum proin eu mi nulla,3.17,true,true,true,Silas,Idenden,Team Member,false, +2023-01-11,Client1,Project1,PROJECT,Project Consulting,nulla elit ac nulla sed vel enim sit amet nunc viverra,3.53,false,false,true,Gusella,Swaile,Team Member,true, +2023-01-19,Client1,Project6,PROJECT,Project Consulting,at turpis donec posuere metus vitae ipsum aliquam non mauris morbi non lectus aliquam sit amet diam in magna bibendum imperdiet nullam,2.45,true,false,true,Hetti,Becken,Team Member,true, +2023-01-16,Client1,Project7,PROJECT,Project Consulting,elit ac nulla sed vel enim sit amet,0.73,false,true,false,Gusella,Swaile,Team Member,true, +2023-01-15,Client1,Project7,PROJECT,Project Consulting,vel est donec odio justo sollicitudin ut suscipit a feugiat et eros vestibulum ac est lacinia nisi venenatis,2.6,true,false,false,Hetti,Becken,Team Member,false, +2023-01-23,Client1,Project7,PROJECT,Project Consulting,posuere metus vitae ipsum aliquam non mauris morbi non lectus aliquam sit amet diam in magna bibendum imperdiet nullam orci pede venenatis,3.57,false,false,false,Hetti,Becken,Team Member,true, +2023-01-30,Client1,Project3,PROJECT,Project Consulting,sagittis nam congue risus semper porta volutpat quam pede lobortis ligula sit amet eleifend pede libero quis orci nullam,1.11,true,true,true,Gusella,Swaile,Team Member,false, +2023-01-23,Client1,Project7,PROJECT,Project Consulting,ultrices phasellus id sapien in sapien iaculis congue vivamus metus arcu adipiscing molestie hendrerit at vulputate vitae nisl aenean lectus pellentesque eget,1.53,true,false,true,Aymer,Hauck,Team Member,false, +2023-01-30,Client1,Project2,PROJECT,Project Consulting,magna vulputate luctus cum sociis natoque penatibus et magnis dis parturient montes nascetur ridiculus mus vivamus vestibulum sagittis sapien cum sociis natoque penatibus et magnis,1.61,false,false,false,Hetti,Becken,Team Member,true, +2023-01-03,Client1,Project1,PROJECT,Project Consulting,eget rutrum at lorem integer tincidunt ante vel ipsum praesent blandit lacinia erat vestibulum,0.41,true,false,false,Sawyer,Berrey,Team Member,true, +2023-01-17,Client1,Project1,PROJECT,Project Consulting,vulputate justo in blandit ultrices enim lorem ipsum dolor sit amet consectetuer adipiscing elit proin,3.88,true,false,false,Hetti,Becken,Team Member,true, +2023-01-30,Client1,Project4,PROJECT,Project Consulting,phasellus in felis donec semper sapien a libero nam dui proin leo odio porttitor id consequat in consequat ut nulla sed accumsan,1.72,false,false,false,Hetti,Becken,Team Member,true, +2023-01-10,Client1,Project6,PROJECT,Project Consulting,eleifend pede libero quis orci nullam molestie nibh in lectus pellentesque,0.78,false,true,false,Hetti,Becken,Team Member,false, +2023-01-20,Client1,Project2,PROJECT,Project Consulting,iaculis justo in hac habitasse platea dictumst etiam faucibus cursus urna ut tellus nulla ut erat id mauris vulputate elementum nullam,3.25,false,false,false,Silas,Idenden,Team Member,false, +2023-01-09,Client1,Project7,PROJECT,Project Consulting,nulla sed vel enim sit amet nunc viverra dapibus nulla suscipit ligula in lacus curabitur at ipsum ac tellus semper interdum,1.97,true,false,false,Aymer,Hauck,Team Member,false, +2023-01-11,Client1,Project1,PROJECT,Project Consulting,eu interdum eu tincidunt in leo maecenas pulvinar lobortis est phasellus sit amet erat nulla,2.95,true,true,false,Sawyer,Berrey,Team Member,true, +2023-01-25,Client1,Project7,PROJECT,Project Consulting,leo pellentesque ultrices mattis odio donec vitae,1.17,false,false,false,Silas,Idenden,Team Member,false, +2023-01-03,Client1,Project2,PROJECT,Project Consulting,ipsum ac tellus semper interdum mauris ullamcorper purus sit amet nulla quisque arcu libero rutrum ac lobortis vel dapibus at diam nam,1.61,false,false,false,Gusella,Swaile,Team Member,true, +2023-01-22,Client1,Project1,PROJECT,Project Consulting,mollis molestie lorem quisque ut erat curabitur gravida nisi at nibh in hac habitasse platea dictumst aliquam augue quam sollicitudin vitae consectetuer eget,1.41,false,false,false,Silas,Idenden,Team Member,false, +2023-01-25,Client1,Project7,PROJECT,Project Consulting,adipiscing lorem vitae mattis nibh ligula nec sem duis aliquam convallis nunc proin at turpis a pede posuere nonummy integer non velit,3.77,false,true,false,Hetti,Becken,Team Member,true, +2023-01-22,Client1,Project6,PROJECT,Project Consulting,arcu libero rutrum ac lobortis vel dapibus at diam nam tristique,2.38,true,false,false,Silas,Idenden,Team Member,false, +2023-01-30,Client1,Project3,PROJECT,Project Consulting,nulla mollis molestie lorem quisque ut erat curabitur gravida nisi at,1.81,false,false,false,Aymer,Hauck,Team Member,false, +2023-01-04,Client1,Project3,PROJECT,Project Consulting,mauris vulputate elementum nullam varius nulla facilisi cras,2.58,false,false,false,Gusella,Swaile,Team Member,false, +2023-01-30,Client1,Project4,PROJECT,Project Consulting,augue vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia curae,2.34,true,false,true,Gusella,Swaile,Team Member,false, +2023-01-17,Client1,Project2,PROJECT,Project Consulting,sit amet justo morbi ut odio,2.19,true,false,false,Hetti,Becken,Team Member,false, +2023-01-25,Client1,Project1,PROJECT,Project Consulting,odio curabitur convallis duis consequat dui nec nisi volutpat eleifend donec ut dolor morbi vel,2.9,false,true,false,Gusella,Swaile,Team Member,true, +2023-01-06,Client1,Project1,PROJECT,Project Consulting,primis in faucibus orci luctus et ultrices posuere cubilia curae donec pharetra magna,2.46,false,true,true,Silas,Idenden,Team Member,true, +2023-01-30,Client1,Project5,PROJECT,Project Consulting,a feugiat et eros vestibulum ac est lacinia nisi venenatis tristique fusce congue diam id ornare imperdiet sapien,0.48,false,true,false,Aymer,Hauck,Team Member,true, +2023-01-03,Client1,Project6,PROJECT,Project Consulting,vel lectus in quam fringilla rhoncus mauris enim leo rhoncus sed vestibulum sit amet cursus id turpis integer aliquet massa id lobortis convallis,1.51,true,false,false,Hetti,Becken,Team Member,true, +2023-01-18,Client1,Project7,PROJECT,Project Consulting,ligula sit amet eleifend pede libero quis orci nullam molestie,2.88,true,true,true,Sawyer,Berrey,Team Member,true, +2023-01-03,Client1,Project4,PROJECT,Project Consulting,ut erat curabitur gravida nisi at nibh in hac habitasse platea dictumst aliquam,0.82,true,true,true,Aymer,Hauck,Team Member,false, +2023-01-10,Client1,Project1,PROJECT,Project Consulting,duis aliquam convallis nunc proin at turpis a pede posuere nonummy integer non velit donec diam neque vestibulum eget vulputate ut ultrices vel augue,3.25,true,true,true,Gusella,Swaile,Team Member,false, +2023-01-22,Client1,Project7,PROJECT,Project Consulting,orci eget orci vehicula condimentum curabitur in libero ut massa,0.77,false,true,true,Gusella,Swaile,Team Member,true, +2023-01-11,Client1,Project2,PROJECT,Project Consulting,curabitur convallis duis consequat dui nec,2.63,false,true,false,Aymer,Hauck,Team Member,true, +2023-01-30,Client1,Project3,PROJECT,Project Consulting,platea dictumst maecenas ut massa quis augue luctus tincidunt nulla,0.27,false,true,false,Gusella,Swaile,Team Member,true, +2023-01-06,Client1,Project6,PROJECT,Project Consulting,accumsan odio curabitur convallis duis consequat dui nec nisi volutpat eleifend donec ut dolor morbi vel lectus in quam fringilla rhoncus,2.11,false,true,true,Sawyer,Berrey,Team Member,true, +2023-01-25,Client1,Project2,PROJECT,Project Consulting,mattis egestas metus aenean fermentum donec ut mauris eget massa tempor convallis nulla neque libero convallis eget eleifend luctus,2.21,true,true,false,Aymer,Hauck,Team Member,true, +2023-01-30,Client1,Project1,PROJECT,Project Consulting,metus arcu adipiscing molestie hendrerit at vulputate vitae nisl aenean lectus pellentesque eget,3.41,true,false,false,Sawyer,Berrey,Team Member,true, +2023-01-16,Client1,Project6,PROJECT,Project Consulting,amet turpis elementum ligula vehicula consequat morbi a,0.11,false,false,true,Aymer,Hauck,Team Member,true, +2023-01-14,Client1,Project2,PROJECT,Project Consulting,elementum ligula vehicula consequat morbi a,0.7,true,true,true,Hetti,Becken,Team Member,false, +2023-01-15,Client1,Project1,PROJECT,Project Consulting,eu massa donec dapibus duis at velit eu est congue elementum in hac habitasse platea dictumst morbi vestibulum,3.03,false,true,false,Silas,Idenden,Team Member,false, +2023-01-18,Client1,Project2,PROJECT,Project Consulting,volutpat sapien arcu sed augue aliquam erat volutpat in congue etiam,0.73,false,true,true,Hetti,Becken,Team Member,true, +2023-01-28,Client1,Project5,PROJECT,Project Consulting,bibendum morbi non quam nec dui luctus rutrum nulla tellus in sagittis dui vel nisl,3.71,false,false,false,Hetti,Becken,Team Member,false, +2023-01-05,Client1,Project4,PROJECT,Project Consulting,primis in faucibus orci luctus et ultrices posuere cubilia curae duis faucibus accumsan odio curabitur convallis duis consequat,1.35,false,true,true,Silas,Idenden,Team Member,true, +2023-01-27,Client1,Project7,PROJECT,Project Consulting,risus semper porta volutpat quam pede lobortis ligula,3.21,true,false,true,Hetti,Becken,Team Member,true, +2023-01-15,Client1,Project2,PROJECT,Project Consulting,quam a odio in hac habitasse platea dictumst maecenas ut massa quis augue luctus tincidunt nulla mollis molestie lorem quisque ut erat curabitur gravida nisi,1.58,true,true,true,Gusella,Swaile,Team Member,true, +2023-01-04,Client1,Project3,PROJECT,Project Consulting,viverra eget congue eget semper rutrum nulla nunc purus phasellus in,2.95,false,true,true,Aymer,Hauck,Team Member,false, +2023-01-26,Client1,Project4,PROJECT,Project Consulting,condimentum id luctus nec molestie sed justo pellentesque viverra pede ac diam cras pellentesque volutpat dui maecenas tristique est et tempus semper est quam pharetra,1.63,true,false,false,Gusella,Swaile,Team Member,true, +2023-01-15,Client1,Project1,PROJECT,Project Consulting,iaculis justo in hac habitasse platea dictumst etiam faucibus cursus urna,2.32,false,true,false,Hetti,Becken,Team Member,true, +2023-01-20,Client1,Project6,PROJECT,Project Consulting,elit proin risus praesent lectus vestibulum quam sapien varius ut blandit non interdum in ante vestibulum ante ipsum,3.96,false,true,false,Silas,Idenden,Team Member,true, +2023-01-12,Client1,Project7,PROJECT,Project Consulting,luctus et ultrices posuere cubilia curae nulla dapibus,1.25,false,true,true,Aymer,Hauck,Team Member,false, +2023-01-27,Client1,Project1,PROJECT,Project Consulting,quis justo maecenas rhoncus aliquam lacus morbi quis tortor id nulla ultrices aliquet maecenas leo odio,4.0,false,false,true,Sawyer,Berrey,Team Member,false, +2023-01-29,Client1,Project3,PROJECT,Project Consulting,mi pede malesuada in imperdiet et commodo vulputate justo in blandit ultrices enim,1.63,false,true,true,Gusella,Swaile,Team Member,true, +2023-01-07,Client1,Project1,PROJECT,Project Consulting,proin leo odio porttitor id consequat in consequat,1.03,true,false,true,Sawyer,Berrey,Team Member,true, +2023-01-17,Client1,Project5,PROJECT,Project Consulting,porttitor id consequat in consequat ut nulla sed accumsan felis ut at dolor quis odio consequat varius integer ac leo pellentesque ultrices mattis,3.62,false,false,false,Hetti,Becken,Team Member,true, +2023-01-21,Client1,Project4,PROJECT,Project Consulting,justo morbi ut odio cras mi pede malesuada in,1.07,false,true,true,Hetti,Becken,Team Member,true, +2023-01-06,Client1,Project7,PROJECT,Project Consulting,leo odio porttitor id consequat in consequat ut nulla sed accumsan felis ut at dolor,3.62,true,true,false,Silas,Idenden,Team Member,false, +2023-01-26,Client1,Project1,PROJECT,Project Consulting,est quam pharetra magna ac consequat metus sapien ut,2.19,false,false,true,Hetti,Becken,Team Member,true, +2023-01-14,Client1,Project7,PROJECT,Project Consulting,non interdum in ante vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia curae duis faucibus accumsan odio curabitur,0.83,true,false,false,Gusella,Swaile,Team Member,false, +2023-01-19,Client1,Project2,PROJECT,Project Consulting,neque aenean auctor gravida sem praesent id massa id,2.15,true,false,false,Aymer,Hauck,Team Member,true, +2023-01-04,Client1,Project7,PROJECT,Project Consulting,convallis eget eleifend luctus ultricies eu nibh quisque id justo sit amet sapien dignissim vestibulum vestibulum,3.92,true,true,true,Sawyer,Berrey,Team Member,true, +2023-01-11,Client1,Project2,PROJECT,Project Consulting,suspendisse ornare consequat lectus in est risus auctor sed tristique in tempus sit amet sem fusce,1.13,true,false,true,Silas,Idenden,Team Member,false, +2023-01-28,Client1,Project4,PROJECT,Project Consulting,volutpat in congue etiam justo etiam pretium iaculis justo in hac habitasse platea dictumst etiam faucibus cursus urna,2.62,false,false,true,Silas,Idenden,Team Member,false, +2023-01-14,Client1,Project5,PROJECT,Project Consulting,pretium nisl ut volutpat sapien arcu sed augue aliquam erat volutpat in congue etiam justo etiam pretium,1.74,false,true,true,Sawyer,Berrey,Team Member,true, +2023-01-13,Client1,Project3,PROJECT,Project Consulting,rutrum nulla tellus in sagittis dui vel nisl duis ac nibh fusce lacus purus aliquet at feugiat non,0.49,true,true,false,Hetti,Becken,Team Member,true, +2023-01-12,Client1,Project7,PROJECT,Project Consulting,nibh ligula nec sem duis aliquam convallis nunc proin at turpis a pede posuere nonummy integer non velit donec diam,2.64,true,true,true,Silas,Idenden,Team Member,false, +2023-01-08,Client1,Project5,PROJECT,Project Consulting,id nisl venenatis lacinia aenean sit amet justo morbi ut odio cras mi pede malesuada in imperdiet et commodo vulputate justo in blandit ultrices,4.0,true,true,false,Gusella,Swaile,Team Member,true, +2023-01-13,Client1,Project7,PROJECT,Project Consulting,eget orci vehicula condimentum curabitur in,0.47,false,false,false,Gusella,Swaile,Team Member,true, +2023-01-04,Client1,Project2,PROJECT,Project Consulting,elit sodales scelerisque mauris sit amet eros suspendisse,2.86,true,false,false,Silas,Idenden,Team Member,false, +2023-01-21,Client1,Project3,PROJECT,Project Consulting,quam sapien varius ut blandit non interdum in ante,0.73,false,false,true,Hetti,Becken,Team Member,true, +2023-01-30,Client1,Project7,PROJECT,Project Consulting,ligula suspendisse ornare consequat lectus in est risus,0.76,false,true,true,Gusella,Swaile,Team Member,true, +2023-01-11,Client1,Project7,PROJECT,Project Consulting,in blandit ultrices enim lorem ipsum dolor sit amet consectetuer adipiscing,3.15,true,false,true,Silas,Idenden,Team Member,true, +2023-01-26,Client1,Project1,PROJECT,Project Consulting,magna vestibulum aliquet ultrices erat tortor sollicitudin mi sit amet lobortis sapien sapien non mi integer ac neque duis bibendum morbi non quam nec dui,2.79,false,true,true,Hetti,Becken,Team Member,true, +2023-01-15,Client1,Project7,PROJECT,Project Consulting,iaculis justo in hac habitasse platea dictumst etiam faucibus cursus urna ut tellus nulla ut erat id mauris vulputate elementum nullam varius nulla,0.99,true,false,false,Sawyer,Berrey,Team Member,true, +2023-01-02,Client1,Project1,PROJECT,Project Consulting,odio elementum eu interdum eu tincidunt in leo maecenas pulvinar lobortis est phasellus sit amet erat nulla,0.73,true,false,true,Gusella,Swaile,Team Member,false, +2023-01-06,Client1,Project4,PROJECT,Project Consulting,pharetra magna ac consequat metus sapien ut nunc vestibulum ante ipsum,1.86,true,false,true,Silas,Idenden,Team Member,true, +2023-01-06,Client1,Project4,PROJECT,Project Consulting,consequat dui nec nisi volutpat eleifend donec ut dolor morbi vel,2.55,false,false,false,Hetti,Becken,Team Member,true, +2023-01-07,Client1,Project4,PROJECT,Project Consulting,mattis nibh ligula nec sem duis aliquam convallis nunc proin at turpis a pede posuere nonummy integer,3.8,false,false,true,Gusella,Swaile,Team Member,false, +2023-01-20,Client1,Project2,PROJECT,Project Consulting,tincidunt in leo maecenas pulvinar lobortis est phasellus sit amet erat,2.11,true,true,true,Silas,Idenden,Team Member,true, +2023-01-16,Client1,Project1,PROJECT,Project Consulting,at feugiat non pretium quis lectus suspendisse potenti in eleifend quam a odio in hac habitasse platea dictumst maecenas ut massa quis augue luctus,1.2,true,true,false,Hetti,Becken,Team Member,true, +2023-01-13,Client1,Project4,PROJECT,Project Consulting,lectus aliquam sit amet diam in,3.32,true,false,false,Aymer,Hauck,Team Member,false, +2023-01-20,Client1,Project6,PROJECT,Project Consulting,nulla integer pede justo lacinia eget tincidunt eget tempus vel pede morbi porttitor lorem,2.53,false,true,false,Sawyer,Berrey,Team Member,true, +2023-01-05,Client1,Project3,PROJECT,Project Consulting,condimentum neque sapien placerat ante nulla justo aliquam quis,1.44,true,true,false,Hetti,Becken,Team Member,true, +2023-01-12,Client1,Project6,PROJECT,Project Consulting,etiam faucibus cursus urna ut,1.37,false,false,true,Sawyer,Berrey,Team Member,false, +2023-01-20,Client1,Project4,PROJECT,Project Consulting,varius ut blandit non interdum in ante vestibulum ante ipsum primis in faucibus orci,2.95,true,false,true,Gusella,Swaile,Team Member,true, +2023-01-05,Client1,Project5,PROJECT,Project Consulting,vestibulum ante ipsum primis in faucibus,1.65,true,true,false,Aymer,Hauck,Team Member,true, +2023-01-22,Client1,Project3,PROJECT,Project Consulting,habitasse platea dictumst aliquam augue quam sollicitudin vitae consectetuer eget rutrum at lorem integer tincidunt ante vel,0.09,false,false,false,Aymer,Hauck,Team Member,false, +2023-01-12,Client1,Project2,PROJECT,Project Consulting,magna bibendum imperdiet nullam orci,3.33,true,false,false,Gusella,Swaile,Team Member,false, +2023-01-07,Client1,Project3,PROJECT,Project Consulting,sapien in sapien iaculis congue vivamus metus arcu adipiscing molestie hendrerit at vulputate vitae nisl aenean lectus pellentesque eget nunc,0.75,false,true,true,Aymer,Hauck,Team Member,true, diff --git a/notebooks/data/toggl-project-info-sample.json b/notebooks/data/toggl-project-info-sample.json new file mode 100644 index 0000000..8505813 --- /dev/null +++ b/notebooks/data/toggl-project-info-sample.json @@ -0,0 +1,4 @@ +{ + "Project1": "WT1-01 - Project1", + "Project3": "WT3-01 - Project3" +} diff --git a/notebooks/data/toggl-sample.csv b/notebooks/data/toggl-sample.csv new file mode 100644 index 0000000..95e014c --- /dev/null +++ b/notebooks/data/toggl-sample.csv @@ -0,0 +1,251 @@ +Email,Start date,Start time,Duration,Project,Task,Client,Billable,Description +aymer@compiler.la,2023-01-02,09:00:00,02:58:00,Prime1,Project3,Client1,Yes,nulla justo aliquam quis turpis eget elit sodales scelerisque mauris sit amet eros suspendisse accumsan tortor quis turpis sed ante vivamus tortor duis mattis +aymer@compiler.la,2023-01-03,09:00:00,03:08:00,Prime1,Project3,Client1,Yes,elementum ligula vehicula consequat morbi a ipsum integer a nibh in quis justo +aymer@compiler.la,2023-01-03,12:08:00,00:49:00,Prime1,Project4,Client1,Yes,ut erat curabitur gravida nisi at nibh in hac habitasse platea dictumst aliquam +aymer@compiler.la,2023-01-04,09:00:00,02:57:00,Prime1,Project3,Client1,Yes,viverra eget congue eget semper rutrum nulla nunc purus phasellus in +aymer@compiler.la,2023-01-05,09:00:00,02:40:00,Prime1,Project1,Client1,Yes,justo sollicitudin ut suscipit a feugiat et eros +aymer@compiler.la,2023-01-05,11:40:00,01:39:00,Prime1,Project5,Client1,Yes,vestibulum ante ipsum primis in faucibus +aymer@compiler.la,2023-01-06,09:00:00,02:15:00,Prime1,Project1,Client1,Yes,vehicula consequat morbi a ipsum integer a nibh in quis justo maecenas rhoncus aliquam lacus morbi quis +aymer@compiler.la,2023-01-06,11:15:00,03:29:00,Prime1,Project4,Client1,Yes,leo maecenas pulvinar lobortis est phasellus sit amet erat nulla tempus vivamus in felis eu sapien cursus vestibulum proin eu +aymer@compiler.la,2023-01-07,09:00:00,01:14:00,Prime1,Project5,Client1,Yes,nulla suspendisse potenti cras in purus eu +aymer@compiler.la,2023-01-07,10:14:00,00:45:00,Prime1,Project3,Client1,Yes,sapien in sapien iaculis congue vivamus metus arcu adipiscing molestie hendrerit at vulputate vitae nisl aenean lectus pellentesque eget nunc +aymer@compiler.la,2023-01-08,09:00:00,02:00:00,Prime1,Project4,Client1,Yes,sed magna at nunc commodo placerat praesent blandit nam nulla integer pede justo lacinia eget tincidunt +aymer@compiler.la,2023-01-09,09:00:00,01:58:00,Prime1,Project7,Client1,Yes,nulla sed vel enim sit amet nunc viverra dapibus nulla suscipit ligula in lacus curabitur at ipsum ac tellus semper interdum +aymer@compiler.la,2023-01-10,09:00:00,02:40:00,Prime1,Project6,Client1,Yes,curae donec pharetra magna vestibulum aliquet ultrices erat tortor sollicitudin mi sit amet lobortis sapien sapien non mi integer ac neque duis bibendum morbi non +aymer@compiler.la,2023-01-11,09:00:00,03:09:00,Prime1,Project3,Client1,Yes,varius nulla facilisi cras non velit nec nisi vulputate nonummy maecenas tincidunt lacus at velit +aymer@compiler.la,2023-01-11,12:09:00,00:49:00,Prime1,Project1,Client1,Yes,maecenas ut massa quis augue luctus tincidunt nulla mollis molestie lorem quisque ut erat curabitur gravida nisi at nibh +aymer@compiler.la,2023-01-11,12:59:00,02:32:00,Prime1,Project7,Client1,Yes,blandit ultrices enim lorem ipsum dolor sit amet consectetuer adipiscing elit proin interdum mauris non ligula pellentesque ultrices phasellus id sapien in +aymer@compiler.la,2023-01-11,15:31:00,02:37:00,Prime1,Project2,Client1,Yes,curabitur convallis duis consequat dui nec +aymer@compiler.la,2023-01-12,09:00:00,01:24:00,Prime1,Project4,Client1,Yes,morbi a ipsum integer a nibh +aymer@compiler.la,2023-01-12,10:24:00,03:50:00,Prime1,Project3,Client1,Yes,pede malesuada in imperdiet et commodo vulputate justo in blandit ultrices enim lorem ipsum dolor sit amet consectetuer adipiscing elit proin interdum mauris non ligula +aymer@compiler.la,2023-01-12,14:14:00,01:15:00,Prime1,Project7,Client1,Yes,luctus et ultrices posuere cubilia curae nulla dapibus +aymer@compiler.la,2023-01-13,09:00:00,03:49:00,Prime1,Project4,Client1,Yes,et commodo vulputate justo in blandit ultrices enim lorem ipsum dolor sit amet consectetuer adipiscing elit proin interdum mauris non +aymer@compiler.la,2023-01-13,12:49:00,03:19:00,Prime1,Project4,Client1,Yes,lectus aliquam sit amet diam in +aymer@compiler.la,2023-01-14,09:00:00,00:54:00,Prime1,Project3,Client1,Yes,in faucibus orci luctus et ultrices posuere cubilia curae donec pharetra magna vestibulum aliquet ultrices erat tortor sollicitudin mi sit amet lobortis +aymer@compiler.la,2023-01-16,09:00:00,00:06:00,Prime1,Project6,Client1,Yes,amet turpis elementum ligula vehicula consequat morbi a +aymer@compiler.la,2023-01-18,09:00:00,03:48:00,Prime1,Project7,Client1,Yes,ac diam cras pellentesque volutpat dui maecenas tristique est et tempus semper est quam pharetra magna ac consequat metus sapien ut nunc +aymer@compiler.la,2023-01-19,09:00:00,03:54:00,Prime1,Project1,Client1,Yes,faucibus orci luctus et ultrices posuere cubilia curae donec pharetra +aymer@compiler.la,2023-01-19,12:54:00,02:09:00,Prime1,Project2,Client1,Yes,neque aenean auctor gravida sem praesent id massa id +aymer@compiler.la,2023-01-20,09:00:00,02:43:00,Prime1,Project1,Client1,Yes,tincidunt eu felis fusce posuere felis sed lacus morbi sem mauris laoreet ut rhoncus aliquet pulvinar sed nisl nunc rhoncus dui +aymer@compiler.la,2023-01-20,11:43:00,03:45:00,Prime1,Project7,Client1,Yes,quis turpis eget elit sodales scelerisque mauris sit amet eros suspendisse accumsan tortor quis turpis sed ante vivamus +aymer@compiler.la,2023-01-21,09:00:00,03:45:00,Prime1,Project3,Client1,Yes,nec sem duis aliquam convallis nunc proin at turpis a pede posuere nonummy integer non velit donec diam +aymer@compiler.la,2023-01-21,12:45:00,00:15:00,Prime1,Project1,Client1,Yes,cursus id turpis integer aliquet massa id lobortis convallis tortor risus dapibus augue +aymer@compiler.la,2023-01-22,09:00:00,00:05:00,Prime1,Project3,Client1,Yes,habitasse platea dictumst aliquam augue quam sollicitudin vitae consectetuer eget rutrum at lorem integer tincidunt ante vel +aymer@compiler.la,2023-01-23,09:00:00,01:31:00,Prime1,Project7,Client1,Yes,ultrices phasellus id sapien in sapien iaculis congue vivamus metus arcu adipiscing molestie hendrerit at vulputate vitae nisl aenean lectus pellentesque eget +aymer@compiler.la,2023-01-24,09:00:00,02:13:00,Prime1,Project7,Client1,Yes,aliquet massa id lobortis convallis tortor risus dapibus augue vel accumsan tellus nisi eu orci mauris lacinia sapien quis libero nullam sit amet turpis elementum +aymer@compiler.la,2023-01-25,09:00:00,02:49:00,Prime1,Project6,Client1,Yes,consequat lectus in est risus auctor sed tristique in tempus sit amet +aymer@compiler.la,2023-01-25,11:49:00,02:34:00,Prime1,Project5,Client1,Yes,sed nisl nunc rhoncus dui vel sem sed sagittis nam congue risus semper porta volutpat quam pede lobortis ligula sit amet eleifend pede +aymer@compiler.la,2023-01-25,14:24:00,02:12:00,Prime1,Project2,Client1,Yes,mattis egestas metus aenean fermentum donec ut mauris eget massa tempor convallis nulla neque libero convallis eget eleifend luctus +aymer@compiler.la,2023-01-26,09:00:00,03:34:00,Prime1,Project2,Client1,Yes,volutpat erat quisque erat eros viverra eget congue eget semper rutrum nulla nunc purus phasellus in felis donec semper sapien +aymer@compiler.la,2023-01-26,12:34:00,02:39:00,Prime1,Project5,Client1,Yes,sit amet eleifend pede libero quis orci nullam molestie nibh in lectus pellentesque at nulla suspendisse +aymer@compiler.la,2023-01-28,09:00:00,02:07:00,Prime1,Project6,Client1,Yes,nec euismod scelerisque quam turpis adipiscing lorem vitae mattis nibh ligula nec +aymer@compiler.la,2023-01-30,09:00:00,01:48:00,Prime1,Project4,Client1,Yes,eget eros elementum pellentesque quisque porta volutpat erat quisque erat eros viverra eget congue eget semper rutrum nulla nunc purus +aymer@compiler.la,2023-01-30,10:48:00,01:48:00,Prime1,Project3,Client1,Yes,nulla mollis molestie lorem quisque ut erat curabitur gravida nisi at +aymer@compiler.la,2023-01-30,12:36:00,00:28:00,Prime1,Project5,Client1,Yes,a feugiat et eros vestibulum ac est lacinia nisi venenatis tristique fusce congue diam id ornare imperdiet sapien +gusella@compiler.la,2023-01-02,09:00:00,00:43:00,Prime1,Project1,Client1,Yes,odio elementum eu interdum eu tincidunt in leo maecenas pulvinar lobortis est phasellus sit amet erat nulla +gusella@compiler.la,2023-01-03,09:00:00,01:36:00,Prime1,Project2,Client1,Yes,ipsum ac tellus semper interdum mauris ullamcorper purus sit amet nulla quisque arcu libero rutrum ac lobortis vel dapibus at diam nam +gusella@compiler.la,2023-01-04,09:00:00,02:34:00,Prime1,Project3,Client1,Yes,mauris vulputate elementum nullam varius nulla facilisi cras +gusella@compiler.la,2023-01-05,09:00:00,03:47:00,Prime1,Project1,Client1,Yes,cursus vestibulum proin eu mi nulla ac enim in tempor +gusella@compiler.la,2023-01-05,12:47:00,00:50:00,Prime1,Project7,Client1,Yes,malesuada in imperdiet et commodo vulputate justo in blandit +gusella@compiler.la,2023-01-05,13:37:00,03:28:00,Prime1,Project3,Client1,Yes,dolor vel est donec odio justo sollicitudin ut suscipit a feugiat et eros vestibulum ac est lacinia +gusella@compiler.la,2023-01-05,17:06:00,02:25:00,Prime1,Project7,Client1,Yes,ornare imperdiet sapien urna pretium nisl ut volutpat sapien arcu sed augue aliquam erat volutpat in congue etiam justo etiam pretium iaculis justo +gusella@compiler.la,2023-01-07,09:00:00,00:41:00,Prime1,Project4,Client1,Yes,quam a odio in hac habitasse platea dictumst maecenas ut massa quis augue luctus tincidunt nulla mollis molestie lorem quisque +gusella@compiler.la,2023-01-07,09:41:00,03:48:00,Prime1,Project4,Client1,Yes,mattis nibh ligula nec sem duis aliquam convallis nunc proin at turpis a pede posuere nonummy integer +gusella@compiler.la,2023-01-08,09:00:00,04:00:00,Prime1,Project5,Client1,Yes,id nisl venenatis lacinia aenean sit amet justo morbi ut odio cras mi pede malesuada in imperdiet et commodo vulputate justo in blandit ultrices +gusella@compiler.la,2023-01-09,09:00:00,00:28:00,Prime1,Project5,Client1,Yes,at turpis donec posuere metus vitae ipsum aliquam non mauris morbi non lectus aliquam sit amet diam in magna bibendum imperdiet nullam orci pede venenatis +gusella@compiler.la,2023-01-09,09:28:00,02:37:00,Prime1,Project1,Client1,Yes,et ultrices posuere cubilia curae nulla dapibus dolor vel est donec odio justo sollicitudin ut suscipit a +gusella@compiler.la,2023-01-10,09:00:00,00:58:00,Prime1,Project1,Client1,Yes,nulla quisque arcu libero rutrum ac lobortis vel dapibus at diam nam tristique +gusella@compiler.la,2023-01-10,09:58:00,03:15:00,Prime1,Project1,Client1,Yes,duis aliquam convallis nunc proin at turpis a pede posuere nonummy integer non velit donec diam neque vestibulum eget vulputate ut ultrices vel augue +gusella@compiler.la,2023-01-11,09:00:00,02:12:00,Prime1,Project6,Client1,Yes,gravida sem praesent id massa id nisl venenatis lacinia aenean sit amet justo morbi ut odio cras mi pede malesuada in imperdiet et commodo vulputate +gusella@compiler.la,2023-01-11,11:12:00,03:31:00,Prime1,Project1,Client1,Yes,nulla elit ac nulla sed vel enim sit amet nunc viverra +gusella@compiler.la,2023-01-12,09:00:00,03:19:00,Prime1,Project2,Client1,Yes,magna bibendum imperdiet nullam orci +gusella@compiler.la,2023-01-13,09:00:00,01:52:00,Prime1,Project6,Client1,Yes,id ornare imperdiet sapien urna pretium nisl ut volutpat sapien arcu sed augue aliquam erat volutpat +gusella@compiler.la,2023-01-13,10:52:00,00:28:00,Prime1,Project7,Client1,Yes,eget orci vehicula condimentum curabitur in +gusella@compiler.la,2023-01-14,09:00:00,03:04:00,Prime1,Project6,Client1,Yes,viverra diam vitae quam suspendisse potenti nullam porttitor lacus at +gusella@compiler.la,2023-01-14,12:04:00,00:49:00,Prime1,Project7,Client1,Yes,non interdum in ante vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia curae duis faucibus accumsan odio curabitur +gusella@compiler.la,2023-01-15,09:00:00,03:36:00,Prime1,Project7,Client1,Yes,vulputate justo in blandit ultrices +gusella@compiler.la,2023-01-15,12:36:00,02:08:00,Prime1,Project7,Client1,Yes,eros vestibulum ac est lacinia +gusella@compiler.la,2023-01-15,14:45:00,01:34:00,Prime1,Project2,Client1,Yes,quam a odio in hac habitasse platea dictumst maecenas ut massa quis augue luctus tincidunt nulla mollis molestie lorem quisque ut erat curabitur gravida nisi +gusella@compiler.la,2023-01-16,09:00:00,00:43:00,Prime1,Project7,Client1,Yes,elit ac nulla sed vel enim sit amet +gusella@compiler.la,2023-01-17,09:00:00,01:35:00,Prime1,Project4,Client1,Yes,luctus rutrum nulla tellus in sagittis dui vel nisl duis +gusella@compiler.la,2023-01-17,10:35:00,02:11:00,Prime1,Project3,Client1,Yes,ante nulla justo aliquam quis turpis eget elit sodales scelerisque mauris sit amet eros suspendisse accumsan tortor quis +gusella@compiler.la,2023-01-18,09:00:00,00:31:00,Prime1,Project1,Client1,Yes,ullamcorper augue a suscipit nulla elit ac nulla sed +gusella@compiler.la,2023-01-20,09:00:00,02:57:00,Prime1,Project4,Client1,Yes,varius ut blandit non interdum in ante vestibulum ante ipsum primis in faucibus orci +gusella@compiler.la,2023-01-21,09:00:00,02:13:00,Prime1,Project6,Client1,Yes,convallis nulla neque libero convallis eget eleifend luctus ultricies eu nibh quisque id justo sit amet sapien +gusella@compiler.la,2023-01-21,11:13:00,00:12:00,Prime1,Project4,Client1,Yes,ac lobortis vel dapibus at diam nam tristique tortor eu pede +gusella@compiler.la,2023-01-21,11:25:00,00:33:00,Prime1,Project5,Client1,Yes,in tempor turpis nec euismod scelerisque quam turpis adipiscing lorem vitae mattis nibh ligula nec sem +gusella@compiler.la,2023-01-22,09:00:00,00:46:00,Prime1,Project7,Client1,Yes,orci eget orci vehicula condimentum curabitur in libero ut massa +gusella@compiler.la,2023-01-23,09:00:00,03:17:00,Prime1,Project7,Client1,Yes,tortor sollicitudin mi sit amet lobortis sapien sapien non +gusella@compiler.la,2023-01-25,09:00:00,03:51:00,Prime1,Project6,Client1,Yes,neque aenean auctor gravida sem praesent id massa id nisl venenatis lacinia aenean sit amet justo morbi ut +gusella@compiler.la,2023-01-25,12:51:00,02:54:00,Prime1,Project1,Client1,Yes,odio curabitur convallis duis consequat dui nec nisi volutpat eleifend donec ut dolor morbi vel +gusella@compiler.la,2023-01-26,09:00:00,02:28:00,Prime1,Project4,Client1,Yes,nam congue risus semper porta volutpat quam pede lobortis ligula sit +gusella@compiler.la,2023-01-26,11:28:00,03:02:00,Prime1,Project2,Client1,Yes,et ultrices posuere cubilia curae donec pharetra magna vestibulum aliquet ultrices erat tortor sollicitudin mi sit amet lobortis sapien sapien +gusella@compiler.la,2023-01-26,14:31:00,00:52:00,Prime1,Project3,Client1,Yes,eget eros elementum pellentesque quisque porta volutpat erat quisque erat eros viverra eget congue eget semper rutrum nulla nunc purus phasellus in felis donec +gusella@compiler.la,2023-01-26,15:24:00,02:25:00,Prime1,Project5,Client1,Yes,in felis eu sapien cursus vestibulum proin eu mi nulla ac enim +gusella@compiler.la,2023-01-26,17:49:00,01:18:00,Prime1,Project2,Client1,Yes,convallis nulla neque libero convallis eget eleifend luctus ultricies eu nibh +gusella@compiler.la,2023-01-26,19:07:00,01:37:00,Prime1,Project4,Client1,Yes,condimentum id luctus nec molestie sed justo pellentesque viverra pede ac diam cras pellentesque volutpat dui maecenas tristique est et tempus semper est quam pharetra +gusella@compiler.la,2023-01-27,09:00:00,02:32:00,Prime1,Project5,Client1,Yes,egestas metus aenean fermentum donec ut mauris eget massa tempor +gusella@compiler.la,2023-01-27,11:32:00,03:12:00,Prime1,Project1,Client1,Yes,consequat nulla nisl nunc nisl duis bibendum felis sed interdum venenatis turpis enim blandit mi in porttitor pede +gusella@compiler.la,2023-01-28,09:00:00,03:43:00,Prime1,Project4,Client1,Yes,amet lobortis sapien sapien non mi +gusella@compiler.la,2023-01-29,09:00:00,03:30:00,Prime1,Project3,Client1,Yes,vestibulum sagittis sapien cum sociis natoque penatibus et magnis dis parturient montes nascetur ridiculus mus etiam vel augue vestibulum +gusella@compiler.la,2023-01-29,12:30:00,01:37:00,Prime1,Project3,Client1,Yes,mi pede malesuada in imperdiet et commodo vulputate justo in blandit ultrices enim +gusella@compiler.la,2023-01-30,09:00:00,02:43:00,Prime1,Project4,Client1,Yes,volutpat erat quisque erat eros viverra eget congue eget semper rutrum nulla +gusella@compiler.la,2023-01-30,11:43:00,03:00:00,Prime1,Project2,Client1,Yes,dui vel sem sed sagittis nam congue risus semper porta volutpat quam pede lobortis ligula sit amet eleifend +gusella@compiler.la,2023-01-30,14:44:00,01:06:00,Prime1,Project3,Client1,Yes,sagittis nam congue risus semper porta volutpat quam pede lobortis ligula sit amet eleifend pede libero quis orci nullam +gusella@compiler.la,2023-01-30,15:51:00,02:20:00,Prime1,Project4,Client1,Yes,augue vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia curae +gusella@compiler.la,2023-01-30,18:11:00,00:16:00,Prime1,Project3,Client1,Yes,platea dictumst maecenas ut massa quis augue luctus tincidunt nulla +gusella@compiler.la,2023-01-30,18:27:00,00:45:00,Prime1,Project7,Client1,Yes,ligula suspendisse ornare consequat lectus in est risus +hetti@compiler.la,2023-01-02,09:00:00,00:34:00,Prime1,Project7,Client1,Yes,in faucibus orci luctus et ultrices posuere cubilia curae nulla dapibus dolor vel est donec odio justo sollicitudin ut suscipit a feugiat et eros vestibulum +hetti@compiler.la,2023-01-02,09:34:00,00:42:00,Prime1,Project3,Client1,Yes,elit proin interdum mauris non ligula pellentesque ultrices phasellus id sapien in sapien iaculis congue vivamus metus arcu adipiscing molestie hendrerit at +hetti@compiler.la,2023-01-03,09:00:00,01:30:00,Prime1,Project1,Client1,Yes,praesent blandit lacinia erat vestibulum +hetti@compiler.la,2023-01-03,10:30:00,01:30:00,Prime1,Project6,Client1,Yes,vel lectus in quam fringilla rhoncus mauris enim leo rhoncus sed vestibulum sit amet cursus id turpis integer aliquet massa id lobortis convallis +hetti@compiler.la,2023-01-04,09:00:00,02:50:00,Prime1,Project1,Client1,Yes,eget elit sodales scelerisque mauris sit amet eros suspendisse accumsan tortor quis turpis +hetti@compiler.la,2023-01-05,09:00:00,01:26:00,Prime1,Project3,Client1,Yes,condimentum neque sapien placerat ante nulla justo aliquam quis +hetti@compiler.la,2023-01-06,09:00:00,02:12:00,Prime1,Project7,Client1,Yes,nec nisi vulputate nonummy maecenas tincidunt lacus at velit vivamus vel nulla eget eros elementum pellentesque quisque porta volutpat +hetti@compiler.la,2023-01-06,11:12:00,03:41:00,Prime1,Project2,Client1,Yes,sit amet eleifend pede libero quis orci nullam molestie nibh in lectus pellentesque at nulla suspendisse potenti cras in purus eu magna +hetti@compiler.la,2023-01-06,14:53:00,02:33:00,Prime1,Project4,Client1,Yes,consequat dui nec nisi volutpat eleifend donec ut dolor morbi vel +hetti@compiler.la,2023-01-07,09:00:00,01:14:00,Prime1,Project5,Client1,Yes,vehicula condimentum curabitur in libero ut massa volutpat convallis morbi odio odio elementum eu interdum eu tincidunt in leo maecenas +hetti@compiler.la,2023-01-07,10:14:00,02:45:00,Prime1,Project6,Client1,Yes,nunc viverra dapibus nulla suscipit ligula in lacus curabitur at ipsum ac tellus semper interdum mauris ullamcorper purus sit amet nulla +hetti@compiler.la,2023-01-07,13:00:00,03:09:00,Prime1,Project1,Client1,Yes,in purus eu magna vulputate luctus cum sociis natoque penatibus et magnis dis parturient montes nascetur ridiculus mus vivamus vestibulum sagittis sapien cum sociis natoque +hetti@compiler.la,2023-01-09,09:00:00,03:49:00,Prime1,Project1,Client1,Yes,quis lectus suspendisse potenti in eleifend quam a odio in hac habitasse +hetti@compiler.la,2023-01-09,12:49:00,01:31:00,Prime1,Project1,Client1,Yes,enim leo rhoncus sed vestibulum sit amet cursus id turpis integer +hetti@compiler.la,2023-01-10,09:00:00,00:30:00,Prime1,Project2,Client1,Yes,blandit nam nulla integer pede justo +hetti@compiler.la,2023-01-10,09:30:00,00:46:00,Prime1,Project6,Client1,Yes,eleifend pede libero quis orci nullam molestie nibh in lectus pellentesque +hetti@compiler.la,2023-01-12,09:00:00,01:33:00,Prime1,Project5,Client1,Yes,massa quis augue luctus tincidunt nulla mollis molestie lorem +hetti@compiler.la,2023-01-12,10:33:00,02:11:00,Prime1,Project7,Client1,Yes,eget eros elementum pellentesque quisque porta volutpat erat quisque erat eros +hetti@compiler.la,2023-01-12,12:44:00,02:25:00,Prime1,Project3,Client1,Yes,vel augue vestibulum rutrum rutrum neque aenean auctor gravida +hetti@compiler.la,2023-01-13,09:00:00,01:06:00,Prime1,Project7,Client1,Yes,varius ut blandit non interdum in ante vestibulum ante ipsum +hetti@compiler.la,2023-01-13,10:06:00,02:02:00,Prime1,Project6,Client1,Yes,aliquam augue quam sollicitudin vitae consectetuer eget rutrum at lorem integer tincidunt ante vel ipsum praesent blandit lacinia erat vestibulum sed magna at +hetti@compiler.la,2023-01-13,12:08:00,00:13:00,Prime1,Project3,Client1,Yes,sapien varius ut blandit non interdum in ante vestibulum ante ipsum primis in faucibus +hetti@compiler.la,2023-01-13,12:21:00,00:29:00,Prime1,Project3,Client1,Yes,rutrum nulla tellus in sagittis dui vel nisl duis ac nibh fusce lacus purus aliquet at feugiat non +hetti@compiler.la,2023-01-14,09:00:00,04:00:00,Prime1,Project6,Client1,Yes,interdum mauris non ligula pellentesque ultrices phasellus id sapien in sapien iaculis congue vivamus metus arcu adipiscing molestie hendrerit at +hetti@compiler.la,2023-01-14,13:00:00,00:42:00,Prime1,Project2,Client1,Yes,elementum ligula vehicula consequat morbi a +hetti@compiler.la,2023-01-15,09:00:00,02:36:00,Prime1,Project7,Client1,Yes,vel est donec odio justo sollicitudin ut suscipit a feugiat et eros vestibulum ac est lacinia nisi venenatis +hetti@compiler.la,2023-01-15,11:36:00,02:19:00,Prime1,Project1,Client1,Yes,iaculis justo in hac habitasse platea dictumst etiam faucibus cursus urna +hetti@compiler.la,2023-01-16,09:00:00,01:12:00,Prime1,Project1,Client1,Yes,at feugiat non pretium quis lectus suspendisse potenti in eleifend quam a odio in hac habitasse platea dictumst maecenas ut massa quis augue luctus +hetti@compiler.la,2023-01-17,09:00:00,03:52:00,Prime1,Project1,Client1,Yes,vulputate justo in blandit ultrices enim lorem ipsum dolor sit amet consectetuer adipiscing elit proin +hetti@compiler.la,2023-01-17,12:52:00,02:11:00,Prime1,Project2,Client1,Yes,sit amet justo morbi ut odio +hetti@compiler.la,2023-01-17,15:04:00,03:37:00,Prime1,Project5,Client1,Yes,porttitor id consequat in consequat ut nulla sed accumsan felis ut at dolor quis odio consequat varius integer ac leo pellentesque ultrices mattis +hetti@compiler.la,2023-01-18,09:00:00,01:43:00,Prime1,Project1,Client1,Yes,nec sem duis aliquam convallis nunc proin at turpis a pede posuere nonummy integer non velit donec diam neque +hetti@compiler.la,2023-01-18,10:43:00,01:54:00,Prime1,Project3,Client1,Yes,auctor sed tristique in tempus sit +hetti@compiler.la,2023-01-18,12:37:00,00:43:00,Prime1,Project2,Client1,Yes,volutpat sapien arcu sed augue aliquam erat volutpat in congue etiam +hetti@compiler.la,2023-01-19,09:00:00,02:27:00,Prime1,Project6,Client1,Yes,at turpis donec posuere metus vitae ipsum aliquam non mauris morbi non lectus aliquam sit amet diam in magna bibendum imperdiet nullam +hetti@compiler.la,2023-01-20,09:00:00,02:25:00,Prime1,Project2,Client1,Yes,diam neque vestibulum eget vulputate ut ultrices vel augue vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia curae donec pharetra +hetti@compiler.la,2023-01-21,09:00:00,02:30:00,Prime1,Project5,Client1,Yes,nascetur ridiculus mus etiam vel augue vestibulum rutrum rutrum neque aenean auctor gravida sem praesent id massa id nisl venenatis lacinia aenean sit +hetti@compiler.la,2023-01-21,11:30:00,01:19:00,Prime1,Project1,Client1,Yes,placerat ante nulla justo aliquam quis turpis eget elit sodales scelerisque mauris sit amet eros suspendisse accumsan +hetti@compiler.la,2023-01-21,12:50:00,01:38:00,Prime1,Project6,Client1,Yes,mattis odio donec vitae nisi nam ultrices libero non mattis pulvinar nulla pede ullamcorper augue a suscipit nulla elit ac nulla +hetti@compiler.la,2023-01-21,14:28:00,01:04:00,Prime1,Project4,Client1,Yes,justo morbi ut odio cras mi pede malesuada in +hetti@compiler.la,2023-01-21,15:33:00,00:43:00,Prime1,Project3,Client1,Yes,quam sapien varius ut blandit non interdum in ante +hetti@compiler.la,2023-01-22,09:00:00,03:25:00,Prime1,Project4,Client1,Yes,quis odio consequat varius integer ac leo pellentesque ultrices +hetti@compiler.la,2023-01-22,12:25:00,03:24:00,Prime1,Project5,Client1,Yes,nonummy integer non velit donec diam neque vestibulum eget vulputate ut ultrices vel augue vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere +hetti@compiler.la,2023-01-22,15:50:00,00:04:00,Prime1,Project1,Client1,Yes,sollicitudin mi sit amet lobortis sapien sapien non mi integer +hetti@compiler.la,2023-01-23,09:00:00,03:34:00,Prime1,Project7,Client1,Yes,posuere metus vitae ipsum aliquam non mauris morbi non lectus aliquam sit amet diam in magna bibendum imperdiet nullam orci pede venenatis +hetti@compiler.la,2023-01-24,09:00:00,00:55:00,Prime1,Project3,Client1,Yes,odio consequat varius integer ac leo pellentesque ultrices mattis odio +hetti@compiler.la,2023-01-25,09:00:00,03:38:00,Prime1,Project6,Client1,Yes,id nulla ultrices aliquet maecenas leo odio condimentum id luctus nec molestie sed justo pellentesque +hetti@compiler.la,2023-01-25,12:38:00,02:01:00,Prime1,Project6,Client1,Yes,vestibulum eget vulputate ut ultrices vel augue vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia curae donec pharetra +hetti@compiler.la,2023-01-25,14:40:00,03:46:00,Prime1,Project7,Client1,Yes,adipiscing lorem vitae mattis nibh ligula nec sem duis aliquam convallis nunc proin at turpis a pede posuere nonummy integer non velit +hetti@compiler.la,2023-01-26,09:00:00,03:48:00,Prime1,Project3,Client1,Yes,ligula vehicula consequat morbi a ipsum +hetti@compiler.la,2023-01-26,12:48:00,02:11:00,Prime1,Project1,Client1,Yes,est quam pharetra magna ac consequat metus sapien ut +hetti@compiler.la,2023-01-26,15:00:00,02:47:00,Prime1,Project1,Client1,Yes,magna vestibulum aliquet ultrices erat tortor sollicitudin mi sit amet lobortis sapien sapien non mi integer ac neque duis bibendum morbi non quam nec dui +hetti@compiler.la,2023-01-27,09:00:00,03:12:00,Prime1,Project7,Client1,Yes,risus semper porta volutpat quam pede lobortis ligula +hetti@compiler.la,2023-01-28,09:00:00,03:55:00,Prime1,Project3,Client1,Yes,felis sed lacus morbi sem mauris laoreet ut rhoncus aliquet pulvinar sed +hetti@compiler.la,2023-01-28,12:55:00,03:42:00,Prime1,Project5,Client1,Yes,bibendum morbi non quam nec dui luctus rutrum nulla tellus in sagittis dui vel nisl +hetti@compiler.la,2023-01-29,09:00:00,00:19:00,Prime1,Project5,Client1,Yes,aliquam convallis nunc proin at turpis a pede posuere nonummy +hetti@compiler.la,2023-01-29,09:19:00,00:12:00,Prime1,Project1,Client1,Yes,quis turpis sed ante vivamus tortor duis mattis egestas metus aenean fermentum donec +hetti@compiler.la,2023-01-30,09:00:00,01:04:00,Prime1,Project3,Client1,Yes,vestibulum sit amet cursus id turpis integer aliquet massa id lobortis convallis tortor risus dapibus augue vel accumsan tellus nisi eu orci +hetti@compiler.la,2023-01-30,10:04:00,01:36:00,Prime1,Project2,Client1,Yes,magna vulputate luctus cum sociis natoque penatibus et magnis dis parturient montes nascetur ridiculus mus vivamus vestibulum sagittis sapien cum sociis natoque penatibus et magnis +hetti@compiler.la,2023-01-30,11:40:00,01:43:00,Prime1,Project4,Client1,Yes,phasellus in felis donec semper sapien a libero nam dui proin leo odio porttitor id consequat in consequat ut nulla sed accumsan +sawyer@compiler.la,2023-01-03,09:00:00,02:03:00,Prime1,Project4,Client1,Yes,aliquet maecenas leo odio condimentum id luctus nec molestie sed justo pellentesque viverra pede ac diam cras pellentesque volutpat dui maecenas tristique est +sawyer@compiler.la,2023-01-03,11:03:00,00:24:00,Prime1,Project1,Client1,Yes,eget rutrum at lorem integer tincidunt ante vel ipsum praesent blandit lacinia erat vestibulum +sawyer@compiler.la,2023-01-04,09:00:00,02:21:00,Prime1,Project3,Client1,Yes,aliquet at feugiat non pretium quis +sawyer@compiler.la,2023-01-04,11:21:00,00:48:00,Prime1,Project7,Client1,Yes,vehicula condimentum curabitur in libero ut massa volutpat convallis morbi odio odio elementum eu interdum eu tincidunt in leo maecenas +sawyer@compiler.la,2023-01-04,12:09:00,03:55:00,Prime1,Project7,Client1,Yes,convallis eget eleifend luctus ultricies eu nibh quisque id justo sit amet sapien dignissim vestibulum vestibulum +sawyer@compiler.la,2023-01-06,09:00:00,00:35:00,Prime1,Project7,Client1,Yes,feugiat et eros vestibulum ac est lacinia nisi venenatis tristique fusce congue diam id ornare imperdiet sapien urna pretium nisl ut volutpat sapien +sawyer@compiler.la,2023-01-06,09:35:00,00:26:00,Prime1,Project3,Client1,Yes,vitae nisi nam ultrices libero non mattis pulvinar nulla pede ullamcorper augue a suscipit +sawyer@compiler.la,2023-01-06,10:01:00,02:06:00,Prime1,Project6,Client1,Yes,accumsan odio curabitur convallis duis consequat dui nec nisi volutpat eleifend donec ut dolor morbi vel lectus in quam fringilla rhoncus +sawyer@compiler.la,2023-01-07,09:00:00,01:50:00,Prime1,Project4,Client1,Yes,quam a odio in hac habitasse platea dictumst maecenas ut massa quis augue luctus tincidunt nulla mollis molestie lorem quisque ut erat curabitur +sawyer@compiler.la,2023-01-07,10:50:00,01:01:00,Prime1,Project1,Client1,Yes,proin leo odio porttitor id consequat in consequat +sawyer@compiler.la,2023-01-08,09:00:00,01:33:00,Prime1,Project5,Client1,Yes,porttitor lacus at turpis donec posuere metus vitae ipsum aliquam non mauris morbi non lectus aliquam +sawyer@compiler.la,2023-01-08,10:33:00,02:35:00,Prime1,Project3,Client1,Yes,curae mauris viverra diam vitae quam suspendisse potenti nullam porttitor lacus at turpis donec posuere metus vitae ipsum aliquam non mauris morbi non +sawyer@compiler.la,2023-01-09,09:00:00,01:01:00,Prime1,Project1,Client1,Yes,donec pharetra magna vestibulum aliquet ultrices erat tortor sollicitudin mi sit amet lobortis sapien sapien +sawyer@compiler.la,2023-01-09,10:01:00,01:58:00,Prime1,Project5,Client1,Yes,nulla integer pede justo lacinia eget tincidunt eget +sawyer@compiler.la,2023-01-11,09:00:00,01:37:00,Prime1,Project3,Client1,Yes,maecenas tristique est et tempus semper est +sawyer@compiler.la,2023-01-11,10:37:00,01:55:00,Prime1,Project7,Client1,Yes,elementum pellentesque quisque porta volutpat erat quisque erat eros viverra eget congue eget semper rutrum nulla nunc purus phasellus in +sawyer@compiler.la,2023-01-11,12:32:00,02:57:00,Prime1,Project1,Client1,Yes,eu interdum eu tincidunt in leo maecenas pulvinar lobortis est phasellus sit amet erat nulla +sawyer@compiler.la,2023-01-12,09:00:00,02:03:00,Prime1,Project3,Client1,Yes,curae duis faucibus accumsan odio curabitur convallis duis consequat dui nec +sawyer@compiler.la,2023-01-12,11:03:00,01:00:00,Prime1,Project1,Client1,Yes,eu interdum eu tincidunt in leo maecenas pulvinar lobortis est phasellus sit amet erat nulla tempus +sawyer@compiler.la,2023-01-12,12:04:00,01:22:00,Prime1,Project6,Client1,Yes,etiam faucibus cursus urna ut +sawyer@compiler.la,2023-01-13,09:00:00,01:07:00,Prime1,Project6,Client1,Yes,platea dictumst morbi vestibulum velit id pretium iaculis diam erat fermentum justo nec condimentum neque sapien placerat ante nulla justo aliquam quis turpis eget +sawyer@compiler.la,2023-01-14,09:00:00,02:06:00,Prime1,Project4,Client1,Yes,feugiat et eros vestibulum ac est lacinia nisi venenatis tristique fusce congue diam id ornare imperdiet sapien urna pretium nisl ut volutpat sapien arcu +sawyer@compiler.la,2023-01-14,11:06:00,01:16:00,Prime1,Project6,Client1,Yes,bibendum felis sed interdum venenatis turpis enim blandit mi +sawyer@compiler.la,2023-01-14,12:22:00,01:44:00,Prime1,Project5,Client1,Yes,pretium nisl ut volutpat sapien arcu sed augue aliquam erat volutpat in congue etiam justo etiam pretium +sawyer@compiler.la,2023-01-15,09:00:00,01:39:00,Prime1,Project3,Client1,Yes,luctus cum sociis natoque penatibus et magnis dis parturient montes nascetur ridiculus mus vivamus +sawyer@compiler.la,2023-01-15,10:39:00,00:59:00,Prime1,Project7,Client1,Yes,iaculis justo in hac habitasse platea dictumst etiam faucibus cursus urna ut tellus nulla ut erat id mauris vulputate elementum nullam varius nulla +sawyer@compiler.la,2023-01-16,09:00:00,03:10:00,Prime1,Project2,Client1,Yes,erat id mauris vulputate elementum nullam varius nulla facilisi +sawyer@compiler.la,2023-01-16,12:10:00,00:44:00,Prime1,Project3,Client1,Yes,nonummy integer non velit donec diam neque vestibulum eget vulputate ut ultrices vel augue vestibulum ante +sawyer@compiler.la,2023-01-16,12:55:00,01:15:00,Prime1,Project4,Client1,Yes,eu massa donec dapibus duis at velit eu +sawyer@compiler.la,2023-01-18,09:00:00,01:40:00,Prime1,Project4,Client1,Yes,imperdiet nullam orci pede venenatis non sodales sed tincidunt eu felis fusce +sawyer@compiler.la,2023-01-18,10:40:00,01:37:00,Prime1,Project3,Client1,Yes,aliquam sit amet diam in magna bibendum imperdiet nullam orci pede venenatis non sodales sed tincidunt eu +sawyer@compiler.la,2023-01-18,12:18:00,02:52:00,Prime1,Project7,Client1,Yes,ligula sit amet eleifend pede libero quis orci nullam molestie +sawyer@compiler.la,2023-01-20,09:00:00,02:31:00,Prime1,Project6,Client1,Yes,nulla integer pede justo lacinia eget tincidunt eget tempus vel pede morbi porttitor lorem +sawyer@compiler.la,2023-01-21,09:00:00,02:25:00,Prime1,Project5,Client1,Yes,vivamus in felis eu sapien cursus vestibulum +sawyer@compiler.la,2023-01-22,09:00:00,01:28:00,Prime1,Project7,Client1,Yes,interdum mauris non ligula pellentesque ultrices phasellus id sapien in sapien iaculis +sawyer@compiler.la,2023-01-23,09:00:00,01:04:00,Prime1,Project6,Client1,Yes,elementum in hac habitasse platea dictumst morbi vestibulum velit id pretium iaculis diam erat fermentum justo nec condimentum neque +sawyer@compiler.la,2023-01-23,10:04:00,00:13:00,Prime1,Project7,Client1,Yes,congue vivamus metus arcu adipiscing molestie hendrerit at vulputate vitae nisl aenean lectus pellentesque eget nunc donec quis orci eget orci +sawyer@compiler.la,2023-01-23,10:18:00,01:34:00,Prime1,Project7,Client1,Yes,id luctus nec molestie sed justo pellentesque viverra pede ac diam cras pellentesque volutpat dui maecenas tristique est et tempus semper est quam +sawyer@compiler.la,2023-01-24,09:00:00,02:16:00,Prime1,Project5,Client1,Yes,vulputate elementum nullam varius nulla facilisi cras non velit nec nisi vulputate nonummy +sawyer@compiler.la,2023-01-25,09:00:00,02:08:00,Prime1,Project2,Client1,Yes,nibh in lectus pellentesque at +sawyer@compiler.la,2023-01-26,09:00:00,01:15:00,Prime1,Project4,Client1,Yes,id ornare imperdiet sapien urna pretium nisl ut volutpat sapien arcu sed augue aliquam erat volutpat in congue etiam justo etiam pretium iaculis justo in +sawyer@compiler.la,2023-01-27,09:00:00,04:00:00,Prime1,Project1,Client1,Yes,quis justo maecenas rhoncus aliquam lacus morbi quis tortor id nulla ultrices aliquet maecenas leo odio +sawyer@compiler.la,2023-01-29,09:00:00,03:23:00,Prime1,Project7,Client1,Yes,ut at dolor quis odio consequat varius integer +sawyer@compiler.la,2023-01-30,09:00:00,00:19:00,Prime1,Project1,Client1,Yes,pellentesque ultrices phasellus id sapien in sapien iaculis congue vivamus metus arcu adipiscing molestie hendrerit at vulputate vitae nisl aenean lectus pellentesque eget nunc +sawyer@compiler.la,2023-01-30,09:19:00,03:24:00,Prime1,Project1,Client1,Yes,metus arcu adipiscing molestie hendrerit at vulputate vitae nisl aenean lectus pellentesque eget +silas@compiler.la,2023-01-03,09:00:00,00:42:00,Prime1,Project2,Client1,Yes,praesent blandit nam nulla integer pede +silas@compiler.la,2023-01-04,09:00:00,02:51:00,Prime1,Project2,Client1,Yes,elit sodales scelerisque mauris sit amet eros suspendisse +silas@compiler.la,2023-01-05,09:00:00,02:40:00,Prime1,Project6,Client1,Yes,aenean auctor gravida sem praesent id massa id nisl venenatis lacinia aenean sit amet justo morbi ut odio cras mi pede malesuada in imperdiet +silas@compiler.la,2023-01-05,11:40:00,01:15:00,Prime1,Project2,Client1,Yes,sapien placerat ante nulla justo aliquam quis turpis eget elit sodales scelerisque +silas@compiler.la,2023-01-05,12:56:00,01:21:00,Prime1,Project4,Client1,Yes,primis in faucibus orci luctus et ultrices posuere cubilia curae duis faucibus accumsan odio curabitur convallis duis consequat +silas@compiler.la,2023-01-06,09:00:00,00:54:00,Prime1,Project5,Client1,Yes,nibh ligula nec sem duis aliquam convallis +silas@compiler.la,2023-01-06,09:54:00,03:25:00,Prime1,Project2,Client1,Yes,at nunc commodo placerat praesent blandit +silas@compiler.la,2023-01-06,13:19:00,02:27:00,Prime1,Project1,Client1,Yes,primis in faucibus orci luctus et ultrices posuere cubilia curae donec pharetra magna +silas@compiler.la,2023-01-06,15:47:00,03:37:00,Prime1,Project7,Client1,Yes,leo odio porttitor id consequat in consequat ut nulla sed accumsan felis ut at dolor +silas@compiler.la,2023-01-06,19:24:00,01:51:00,Prime1,Project4,Client1,Yes,pharetra magna ac consequat metus sapien ut nunc vestibulum ante ipsum +silas@compiler.la,2023-01-07,09:00:00,02:25:00,Prime1,Project5,Client1,Yes,praesent blandit nam nulla integer pede justo lacinia eget tincidunt eget tempus vel pede morbi porttitor lorem id ligula suspendisse ornare consequat lectus in +silas@compiler.la,2023-01-08,09:00:00,01:36:00,Prime1,Project3,Client1,Yes,in purus eu magna vulputate luctus +silas@compiler.la,2023-01-08,10:36:00,01:19:00,Prime1,Project2,Client1,Yes,lobortis convallis tortor risus dapibus augue vel accumsan tellus nisi eu orci mauris lacinia sapien quis libero nullam sit amet +silas@compiler.la,2023-01-11,09:00:00,00:41:00,Prime1,Project7,Client1,Yes,ac consequat metus sapien ut nunc vestibulum ante ipsum primis in faucibus +silas@compiler.la,2023-01-11,09:41:00,01:07:00,Prime1,Project2,Client1,Yes,suspendisse ornare consequat lectus in est risus auctor sed tristique in tempus sit amet sem fusce +silas@compiler.la,2023-01-11,10:49:00,03:09:00,Prime1,Project7,Client1,Yes,in blandit ultrices enim lorem ipsum dolor sit amet consectetuer adipiscing +silas@compiler.la,2023-01-12,09:00:00,02:38:00,Prime1,Project7,Client1,Yes,nibh ligula nec sem duis aliquam convallis nunc proin at turpis a pede posuere nonummy integer non velit donec diam +silas@compiler.la,2023-01-13,09:00:00,00:40:00,Prime1,Project6,Client1,Yes,blandit ultrices enim lorem ipsum dolor sit amet consectetuer adipiscing elit +silas@compiler.la,2023-01-14,09:00:00,03:00:00,Prime1,Project7,Client1,Yes,morbi vestibulum velit id pretium iaculis diam +silas@compiler.la,2023-01-14,12:00:00,02:19:00,Prime1,Project5,Client1,Yes,pede justo lacinia eget tincidunt eget tempus vel pede morbi porttitor lorem id ligula +silas@compiler.la,2023-01-15,09:00:00,03:08:00,Prime1,Project6,Client1,Yes,dis parturient montes nascetur ridiculus mus etiam vel augue vestibulum rutrum +silas@compiler.la,2023-01-15,12:08:00,00:03:00,Prime1,Project4,Client1,Yes,viverra pede ac diam cras pellentesque volutpat dui maecenas tristique est et +silas@compiler.la,2023-01-15,12:11:00,03:01:00,Prime1,Project1,Client1,Yes,eu massa donec dapibus duis at velit eu est congue elementum in hac habitasse platea dictumst morbi vestibulum +silas@compiler.la,2023-01-16,09:00:00,02:59:00,Prime1,Project4,Client1,Yes,vestibulum proin eu mi nulla ac enim in tempor +silas@compiler.la,2023-01-17,09:00:00,02:25:00,Prime1,Project2,Client1,Yes,cras pellentesque volutpat dui maecenas tristique est et tempus semper est quam pharetra magna ac consequat metus sapien +silas@compiler.la,2023-01-17,11:25:00,03:51:00,Prime1,Project5,Client1,Yes,vestibulum sagittis sapien cum sociis natoque +silas@compiler.la,2023-01-18,09:00:00,02:44:00,Prime1,Project4,Client1,Yes,tortor duis mattis egestas metus aenean fermentum donec ut mauris eget +silas@compiler.la,2023-01-18,11:44:00,01:08:00,Prime1,Project4,Client1,Yes,faucibus orci luctus et ultrices posuere +silas@compiler.la,2023-01-20,09:00:00,01:18:00,Prime1,Project6,Client1,Yes,metus sapien ut nunc vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia curae mauris viverra diam vitae quam suspendisse potenti nullam +silas@compiler.la,2023-01-20,10:18:00,03:15:00,Prime1,Project2,Client1,Yes,iaculis justo in hac habitasse platea dictumst etiam faucibus cursus urna ut tellus nulla ut erat id mauris vulputate elementum nullam +silas@compiler.la,2023-01-20,13:33:00,03:57:00,Prime1,Project6,Client1,Yes,elit proin risus praesent lectus vestibulum quam sapien varius ut blandit non interdum in ante vestibulum ante ipsum +silas@compiler.la,2023-01-20,17:31:00,02:06:00,Prime1,Project2,Client1,Yes,tincidunt in leo maecenas pulvinar lobortis est phasellus sit amet erat +silas@compiler.la,2023-01-22,09:00:00,03:10:00,Prime1,Project1,Client1,Yes,pulvinar lobortis est phasellus sit amet erat nulla tempus vivamus in felis eu sapien cursus vestibulum proin eu mi nulla +silas@compiler.la,2023-01-22,12:10:00,01:24:00,Prime1,Project1,Client1,Yes,mollis molestie lorem quisque ut erat curabitur gravida nisi at nibh in hac habitasse platea dictumst aliquam augue quam sollicitudin vitae consectetuer eget +silas@compiler.la,2023-01-22,13:34:00,02:22:00,Prime1,Project6,Client1,Yes,arcu libero rutrum ac lobortis vel dapibus at diam nam tristique +silas@compiler.la,2023-01-23,09:00:00,00:20:00,Prime1,Project5,Client1,Yes,nec nisi vulputate nonummy maecenas tincidunt lacus at velit vivamus vel nulla eget eros elementum pellentesque quisque porta volutpat erat quisque erat eros +silas@compiler.la,2023-01-24,09:00:00,02:45:00,Prime1,Project6,Client1,Yes,duis aliquam convallis nunc proin at turpis +silas@compiler.la,2023-01-24,11:45:00,03:20:00,Prime1,Project6,Client1,Yes,porttitor lorem id ligula suspendisse ornare consequat lectus +silas@compiler.la,2023-01-24,15:06:00,00:26:00,Prime1,Project5,Client1,Yes,ut blandit non interdum in +silas@compiler.la,2023-01-25,09:00:00,02:06:00,Prime1,Project5,Client1,Yes,odio odio elementum eu interdum eu tincidunt in leo maecenas pulvinar lobortis est +silas@compiler.la,2023-01-25,11:06:00,02:28:00,Prime1,Project4,Client1,Yes,elementum pellentesque quisque porta volutpat erat quisque erat eros viverra eget congue eget semper rutrum nulla nunc purus phasellus in felis +silas@compiler.la,2023-01-25,13:35:00,01:10:00,Prime1,Project7,Client1,Yes,leo pellentesque ultrices mattis odio donec vitae +silas@compiler.la,2023-01-26,09:00:00,01:30:00,Prime1,Project5,Client1,Yes,ultrices posuere cubilia curae mauris viverra diam +silas@compiler.la,2023-01-27,09:00:00,01:49:00,Prime1,Project6,Client1,Yes,blandit non interdum in ante vestibulum ante +silas@compiler.la,2023-01-27,10:49:00,02:55:00,Prime1,Project7,Client1,Yes,hac habitasse platea dictumst aliquam augue quam +silas@compiler.la,2023-01-27,13:45:00,03:40:00,Prime1,Project4,Client1,Yes,nullam orci pede venenatis non sodales sed tincidunt eu +silas@compiler.la,2023-01-28,09:00:00,02:37:00,Prime1,Project4,Client1,Yes,volutpat in congue etiam justo etiam pretium iaculis justo in hac habitasse platea dictumst etiam faucibus cursus urna +silas@compiler.la,2023-01-30,09:00:00,03:31:00,Prime1,Project1,Client1,Yes,nibh quisque id justo sit amet sapien dignissim vestibulum vestibulum ante ipsum primis in faucibus orci luctus et +silas@compiler.la,2023-01-30,12:31:00,01:56:00,Prime1,Project6,Client1,Yes,ante vivamus tortor duis mattis egestas metus aenean fermentum donec ut mauris eget massa tempor convallis diff --git a/notebooks/data/toggl-user-info-sample.json b/notebooks/data/toggl-user-info-sample.json new file mode 100644 index 0000000..3034b97 --- /dev/null +++ b/notebooks/data/toggl-user-info-sample.json @@ -0,0 +1,22 @@ +{ + "aymer@compiler.la": { + "Last Name": "Hauck", + "First Name": "Aymer" + }, + "gusella@compiler.la": { + "Last Name": "Swaile", + "First Name": "Gusella" + }, + "hetti@compiler.la": { + "Last Name": "Becken", + "First Name": "Hetti" + }, + "sawyer@compiler.la": { + "Last Name": "Berrey", + "First Name": "Sawyer" + }, + "silas@compiler.la": { + "Last Name": "Idenden", + "First Name": "Silas" + } +} diff --git a/notebooks/harvest-to-toggl.ipynb b/notebooks/harvest-to-toggl.ipynb new file mode 100644 index 0000000..f74ca64 --- /dev/null +++ b/notebooks/harvest-to-toggl.ipynb @@ -0,0 +1,169 @@ +{ + "cells": [ + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "from datetime import datetime, timedelta\n", + "import os\n", + "from pathlib import Path\n", + "import pandas as pd\n", + "\n", + "\n", + "def duration_str(duration: timedelta):\n", + " \"\"\"\n", + " Use total seconds to convert to a datetime and format as a string e.g. 01:30\n", + " \"\"\"\n", + " return datetime.fromtimestamp(duration.total_seconds()).strftime(\"%H:%M\")\n", + "\n", + "\n", + "DATA_DIR = Path(\"./data\")\n", + "DATA_SOURCE = Path(os.environ.get(\"HARVEST_DATA\", \"./data/harvest-sample.csv\"))" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# assign category dtype for efficiency on repeating text columns\n", + "dtypes = {\n", + " \"Client\": \"category\",\n", + " \"Project\": \"category\",\n", + " \"First Name\": \"category\",\n", + " \"Last Name\": \"category\",\n", + "}\n", + "# skip reading the columns we don't care about for Toggl\n", + "cols = list(dtypes) + [\n", + " \"Date\",\n", + " \"Notes\",\n", + " \"Hours\",\n", + "]\n", + "# read CSV file, parsing dates\n", + "source = pd.read_csv(DATA_SOURCE, dtype=dtypes, usecols=cols, parse_dates=[\"Date\"], cache_dates=True)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# rename columns that can be imported as-is\n", + "source.rename(columns={\"Project\": \"Task\", \"Notes\": \"Description\", \"Date\": \"Start Date\"}, inplace=True)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# update static calculated columns\n", + "source[\"Client\"] = \"Xentrans\"\n", + "source[\"Client\"] = source[\"Client\"].astype(\"category\")\n", + "source[\"Project\"] = \"Xentrans\"\n", + "source[\"Project\"] = source[\"Project\"].astype(\"category\")\n", + "source[\"Billable\"] = \"Yes\"\n", + "source[\"Billable\"] = source[\"Billable\"].astype(\"category\")" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# add the Email column\n", + "source[\"Email\"] = source[\"First Name\"].apply(lambda x: f\"{x.lower()}@compiler.la\").astype(\"category\")\n", + "# drop individual name columns\n", + "source.drop(columns=[\"First Name\", \"Last Name\"], inplace=True)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# Convert numeric Hours to timedelta Duration\n", + "source[\"Duration\"] = source[\"Hours\"].apply(pd.to_timedelta, unit=\"hours\")" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# Default start time to 09:00\n", + "source[\"Start Time\"] = pd.to_timedelta(\"09:00:00\")" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "def calc_start_time(group):\n", + " \"\"\"\n", + " Start time is offset by the previous record's duration, with a default of 0 offset for the first record\n", + " \"\"\"\n", + " group[\"Start Time\"] = group[\"Start Time\"] + group[\"Duration\"].shift(fill_value=pd.to_timedelta(\"00:00:00\")).cumsum()\n", + " return group" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# sort and group users into their distinct days\n", + "source.sort_values([\"Email\", \"Start Date\"], inplace=True)\n", + "user_days = source.groupby([\"Email\", \"Start Date\"])\n", + "user_days = user_days.apply(calc_start_time)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# convert timedeltas to duration strings\n", + "user_days[\"Duration\"] = user_days[\"Duration\"].apply(duration_str)\n", + "user_days[\"Start Time\"] = user_days[\"Start Time\"].apply(duration_str)\n", + "\n", + "# export to CSV, reordering columns\n", + "columns=[\"Email\", \"Start Date\", \"Start Time\", \"Duration\", \"Project\", \"Task\", \"Client\", \"Billable\", \"Description\"]\n", + "user_days.to_csv(DATA_DIR / \"toggl.csv\", index=False, columns=columns)" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.11.6" + } + }, + "nbformat": 4, + "nbformat_minor": 2 +} diff --git a/notebooks/toggl-to-harvest.ipynb b/notebooks/toggl-to-harvest.ipynb new file mode 100644 index 0000000..a48709f --- /dev/null +++ b/notebooks/toggl-to-harvest.ipynb @@ -0,0 +1,232 @@ +{ + "cells": [ + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "from compiler_admin.services.google import user_info as google_user_info\n", + "import json\n", + "import os\n", + "from pathlib import Path\n", + "import pandas as pd\n", + "import re\n", + "\n", + "\n", + "DATA_DIR = Path(\"./data\")\n", + "DATA_SOURCE = Path(os.environ.get(\"TOGGL_DATA\", \"./data/toggl-sample.csv\"))\n", + "\n", + "PROJECT_INFO_FILE = os.environ.get(\"TOGGL_PROJECT_INFO\")\n", + "USER_INFO_FILE = os.environ.get(\"TOGGL_USER_INFO\")\n", + "\n", + "CLIENT_NAME = os.environ.get(\"HARVEST_CLIENT_NAME\")\n", + "\n", + "\n", + "def str_timedelta(td):\n", + " \"\"\"\n", + " Convert a string formatted duration (e.g. 01:30) to a timedelta.\n", + " \"\"\"\n", + " return pd.to_timedelta(pd.to_datetime(td, format=\"%H:%M:%S\").strftime(\"%H:%M:%S\"))\n", + "\n", + "\n", + "def read_info_file(file):\n", + " with open(file, \"r\") as ui:\n", + " return json.load(ui)\n", + "\n", + "\n", + "def write_info_file(file, info):\n", + " with open(file, \"w\") as ui:\n", + " json.dump(info, ui, indent=2)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# assign category dtype for efficiency on repeating text columns\n", + "dtypes = {\n", + " \"Email\": \"category\",\n", + " \"Task\": \"category\",\n", + " \"Client\": \"category\"\n", + "}\n", + "# skip reading the columns we don't care about for Harvest\n", + "cols = list(dtypes) + [\n", + " \"Start date\",\n", + " \"Start time\",\n", + " \"Duration\",\n", + " \"Description\"\n", + "]\n", + "# read CSV file, parsing dates and times\n", + "source = pd.read_csv(DATA_SOURCE, dtype=dtypes, usecols=cols, parse_dates=[\"Start date\"], cache_dates=True)\n", + "source[\"Start time\"] = source[\"Start time\"].apply(str_timedelta)\n", + "source[\"Duration\"] = source[\"Duration\"].apply(str_timedelta)\n", + "source.sort_values([\"Start date\", \"Start time\", \"Email\"], inplace=True)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# rename columns that can be imported as-is\n", + "source.rename(columns={\"Task\": \"Project\", \"Description\": \"Notes\", \"Start date\": \"Date\"}, inplace=True)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# update static calculated columns\n", + "source[\"Client\"] = CLIENT_NAME\n", + "source[\"Client\"] = source[\"Client\"].astype(\"category\")\n", + "source[\"Task\"] = \"Project Consulting\"\n", + "source[\"Task\"] = source[\"Task\"].astype(\"category\")" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# cache of previously seen project information, keyed on Toggl project name\n", + "PROJECT_INFO = {}\n", + "\n", + "if PROJECT_INFO_FILE:\n", + " file_info = read_info_file(PROJECT_INFO_FILE)\n", + " PROJECT_INFO.update(file_info)\n", + " print(f\"Project info: {', '.join(PROJECT_INFO.keys())}\")" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# get cached project name if any\n", + "source[\"Project\"] = source[\"Project\"].apply(lambda x: PROJECT_INFO.get(x, x))" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# cache of previously seen user information, keyed on email\n", + "USER_INFO = {}\n", + "NOT_FOUND = \"NOT FOUND\"\n", + "\n", + "if USER_INFO_FILE:\n", + " file_info = read_info_file(USER_INFO_FILE)\n", + " USER_INFO.update(file_info)\n", + " print(f\"User info: {', '.join(USER_INFO.keys())}\")" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# get cached first name or derive from email\n", + "def get_first_name(email: str):\n", + " user = USER_INFO.get(email)\n", + " first_name = user.get(\"First Name\") if user else None\n", + " if first_name is None:\n", + " parts = email.split(\"@\")\n", + " first_name = parts[0].capitalize()\n", + " data = {\"First Name\": first_name}\n", + " if email in USER_INFO:\n", + " USER_INFO[email].update(data)\n", + " else:\n", + " USER_INFO[email] = data\n", + " return first_name\n", + "\n", + "source[\"First Name\"] = source[\"Email\"].apply(get_first_name)\n", + "source[\"First Name\"] = source[\"First Name\"].astype(\"category\")" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# Get cached last name or query from Google\n", + "def get_last_name(email: str):\n", + " user = USER_INFO.get(email)\n", + " last_name = user.get(\"Last Name\") if user else None\n", + " if last_name is None:\n", + " user = google_user_info(email)\n", + " last_name = user.get(\"Last Name\") if user else None\n", + " if email in USER_INFO:\n", + " USER_INFO[email].update(user)\n", + " else:\n", + " USER_INFO[email] = user\n", + " return last_name\n", + "\n", + "source[\"Last Name\"] = source[\"Email\"].apply(get_last_name)\n", + "source[\"Last Name\"] = source[\"Last Name\"].astype(\"category\")" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "if len(USER_INFO) > 0 and USER_INFO_FILE:\n", + " write_info_file(USER_INFO_FILE, USER_INFO)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "source[\"Hours\"] = (source[\"Duration\"].dt.total_seconds()/3600).round(2)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "output_path = DATA_DIR / re.sub(r\"[Tt]oggl\", \"harvest\", DATA_SOURCE.name)\n", + "output_columns = [\"Date\", \"Client\", \"Project\", \"Task\", \"Notes\", \"Hours\", \"First Name\", \"Last Name\"]\n", + "source.to_csv(output_path, index=False, columns=output_columns)" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.11.6" + } + }, + "nbformat": 4, + "nbformat_minor": 2 +} diff --git a/pyproject.toml b/pyproject.toml index 49f92e3..2c1640a 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -23,6 +23,8 @@ dev = [ "black", "build", "flake8", + "ipykernel", + "pandas", "pre-commit", "setuptools_scm>=8" ] @@ -64,5 +66,8 @@ norecursedirs = [ ".vscode", ] +[tool.setuptools] +packages = ["compiler_admin"] + [tool.setuptools_scm] # intentionally left blank, but we need the section header to activate the tool diff --git a/tests/commands/test_convert.py b/tests/commands/test_convert.py index f102bba..307715d 100644 --- a/tests/commands/test_convert.py +++ b/tests/commands/test_convert.py @@ -1,7 +1,7 @@ from argparse import Namespace import pytest -from compiler_admin.commands import RESULT_FAILURE, RESULT_SUCCESS +from compiler_admin import RESULT_FAILURE, RESULT_SUCCESS from compiler_admin.commands.convert import convert, __name__ as MODULE diff --git a/tests/commands/test_create.py b/tests/commands/test_create.py index 4de12db..285d54a 100644 --- a/tests/commands/test_create.py +++ b/tests/commands/test_create.py @@ -1,7 +1,7 @@ from argparse import Namespace import pytest -from compiler_admin.commands import RESULT_FAILURE, RESULT_SUCCESS +from compiler_admin import RESULT_FAILURE, RESULT_SUCCESS from compiler_admin.commands.create import create, __name__ as MODULE from compiler_admin.services.google import USER_HELLO diff --git a/tests/commands/test_delete.py b/tests/commands/test_delete.py index 7728cc9..a714c14 100644 --- a/tests/commands/test_delete.py +++ b/tests/commands/test_delete.py @@ -1,7 +1,7 @@ from argparse import Namespace import pytest -from compiler_admin.commands import RESULT_FAILURE, RESULT_SUCCESS +from compiler_admin import RESULT_FAILURE, RESULT_SUCCESS from compiler_admin.commands.delete import delete, __name__ as MODULE diff --git a/tests/commands/test_info.py b/tests/commands/test_info.py index 1939366..3887c36 100644 --- a/tests/commands/test_info.py +++ b/tests/commands/test_info.py @@ -1,7 +1,6 @@ import pytest -from compiler_admin import __version__ as version -from compiler_admin.commands import RESULT_SUCCESS +from compiler_admin import __version__ as version, RESULT_SUCCESS from compiler_admin.commands.info import info, __name__ as MODULE from compiler_admin.services.google import DOMAIN diff --git a/tests/commands/test_offboard.py b/tests/commands/test_offboard.py index 5bddbfe..08de141 100644 --- a/tests/commands/test_offboard.py +++ b/tests/commands/test_offboard.py @@ -1,7 +1,7 @@ from argparse import Namespace import pytest -from compiler_admin.commands import RESULT_FAILURE, RESULT_SUCCESS +from compiler_admin import RESULT_FAILURE, RESULT_SUCCESS from compiler_admin.commands.offboard import offboard, __name__ as MODULE @@ -20,8 +20,8 @@ def mock_input_no(mock_input): @pytest.fixture -def mock_NamedTemporaryFile(mock_NamedTemporaryFile): - return mock_NamedTemporaryFile(MODULE, ["Overall Transfer Status: completed"]) +def mock_NamedTemporaryFile(mock_NamedTemporaryFile_with_readlines): + return mock_NamedTemporaryFile_with_readlines(MODULE, ["Overall Transfer Status: completed"]) @pytest.fixture diff --git a/tests/commands/test_reset_password.py b/tests/commands/test_reset_password.py index 909215d..5d56269 100644 --- a/tests/commands/test_reset_password.py +++ b/tests/commands/test_reset_password.py @@ -1,7 +1,7 @@ from argparse import Namespace import pytest -from compiler_admin.commands import RESULT_FAILURE, RESULT_SUCCESS +from compiler_admin import RESULT_FAILURE, RESULT_SUCCESS from compiler_admin.commands.reset_password import reset_password, __name__ as MODULE from compiler_admin.services.google import USER_HELLO diff --git a/tests/commands/test_restore.py b/tests/commands/test_restore.py index f2e20d7..cfd05dd 100644 --- a/tests/commands/test_restore.py +++ b/tests/commands/test_restore.py @@ -1,7 +1,7 @@ from argparse import Namespace import pytest -from compiler_admin.commands import RESULT_FAILURE, RESULT_SUCCESS +from compiler_admin import RESULT_FAILURE, RESULT_SUCCESS from compiler_admin.commands.restore import restore, __name__ as MODULE diff --git a/tests/commands/test_signout.py b/tests/commands/test_signout.py index 3caaf45..06419d0 100644 --- a/tests/commands/test_signout.py +++ b/tests/commands/test_signout.py @@ -1,7 +1,7 @@ from argparse import Namespace import pytest -from compiler_admin.commands import RESULT_FAILURE, RESULT_SUCCESS +from compiler_admin import RESULT_FAILURE, RESULT_SUCCESS from compiler_admin.commands.signout import signout, __name__ as MODULE diff --git a/tests/conftest.py b/tests/conftest.py index d57416c..549aeae 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -1,6 +1,6 @@ import pytest -from compiler_admin.commands import RESULT_SUCCESS +from compiler_admin import RESULT_SUCCESS @pytest.fixture @@ -118,6 +118,12 @@ def mock_google_user_exists(mock_module_name): return mock_module_name("user_exists") +@pytest.fixture +def mock_google_user_info(mock_module_name): + """Fixture returns a function that patches the user_info function from a given module.""" + return mock_module_name("user_info") + + @pytest.fixture def mock_google_user_in_group(mock_module_name): """Fixture returns a function that patches the user_in_group function from a given module.""" @@ -137,7 +143,7 @@ def mock_google_user_is_staff(mock_module_name): @pytest.fixture -def mock_NamedTemporaryFile(mocker): +def mock_NamedTemporaryFile_with_readlines(mocker): """Fixture returns a function that patches NamedTemporaryFile in a given module. Optionally provide a value for GAM stdout.readlines(). diff --git a/tests/services/test_google.py b/tests/services/test_google.py index 476e6c6..15a192d 100644 --- a/tests/services/test_google.py +++ b/tests/services/test_google.py @@ -3,6 +3,7 @@ import pytest +from compiler_admin import RESULT_SUCCESS, RESULT_FAILURE from compiler_admin.services.google import ( DOMAIN, GAM, @@ -19,6 +20,7 @@ remove_user_from_group, user_exists, user_in_group, + user_info, user_is_partner, user_is_staff, __name__ as MODULE, @@ -40,6 +42,11 @@ def mock_google_user_exists(mock_google_user_exists): return mock_google_user_exists(MODULE) +@pytest.fixture +def mock_google_user_info(mock_google_user_info): + return mock_google_user_info(MODULE) + + @pytest.fixture def mock_google_user_in_group(mock_google_user_in_group): return mock_google_user_in_group(MODULE) @@ -50,11 +57,6 @@ def mock_subprocess_call(mocker): return mocker.patch(f"{MODULE}.subprocess.call") -@pytest.fixture -def mock_NamedTemporaryFile(mock_NamedTemporaryFile): - return mock_NamedTemporaryFile(MODULE, ["group"]) - - def test_user_account_name_None(): username = None account = user_account_name(username) @@ -182,22 +184,39 @@ def test_user_exists_username_not_in_domain(capfd): assert "User not in domain" in captured.out -def test_user_exists_user_exists(mock_google_CallGAMCommand): - mock_google_CallGAMCommand.return_value = 0 +def test_user_exists_user_exists(mock_google_user_info): + mock_google_user_info.return_value = {"First Name": "Test", "Last Name": "User"} res = user_exists(user_account_name("username")) assert res is True -def test_user_exists_user_does_not_exists(mock_google_CallGAMCommand): - mock_google_CallGAMCommand.return_value = -1 +def test_user_exists_user_does_not_exist(mock_google_user_info): + mock_google_user_info.return_value = {} res = user_exists(user_account_name("username")) assert res is False +def test_user_info_user_exists(mock_gam_CallGAMCommand, mock_NamedTemporaryFile_with_readlines): + mock_NamedTemporaryFile_with_readlines(MODULE, ["First Name:Test", "Last Name:User"]) + mock_gam_CallGAMCommand.return_value = RESULT_SUCCESS + + res = user_info(user_account_name("username")) + + assert res == {"First Name": "Test", "Last Name": "User"} + + +def test_user_info_user_does_not_exists(mock_gam_CallGAMCommand): + mock_gam_CallGAMCommand.return_value = RESULT_FAILURE + + res = user_info(user_account_name("username")) + + assert res == {} + + def test_user_in_group_user_does_not_exist(mock_google_user_exists, capfd): mock_google_user_exists.return_value = False @@ -208,18 +227,20 @@ def test_user_in_group_user_does_not_exist(mock_google_user_exists, capfd): assert "User does not exist" in captured.out -@pytest.mark.usefixtures("mock_NamedTemporaryFile", "mock_google_CallGAMCommand") -def test_user_in_group_user_exists_in_group(mock_google_user_exists): +@pytest.mark.usefixtures("mock_google_CallGAMCommand") +def test_user_in_group_user_exists_in_group(mock_google_user_exists, mock_NamedTemporaryFile_with_readlines): mock_google_user_exists.return_value = True + mock_NamedTemporaryFile_with_readlines(MODULE, ["group"]) res = user_in_group("username", "group") assert res is True -@pytest.mark.usefixtures("mock_NamedTemporaryFile", "mock_google_CallGAMCommand") -def test_user_in_group_user_exists_not_in_group(mock_google_user_exists): +@pytest.mark.usefixtures("mock_google_CallGAMCommand") +def test_user_in_group_user_exists_not_in_group(mock_google_user_exists, mock_NamedTemporaryFile_with_readlines): mock_google_user_exists.return_value = True + mock_NamedTemporaryFile_with_readlines(MODULE, ["group"]) res = user_in_group("username", "nope")