{"id":25839683,"url":"https://github.com/netresearch/timetracker","last_synced_at":"2025-03-01T04:34:04.080Z","repository":{"id":8503807,"uuid":"58645540","full_name":"netresearch/timetracker","owner":"netresearch","description":"Simple time tracking front end with optional Jira synchronization, AD/LDAP integration and XLSX export.","archived":false,"fork":false,"pushed_at":"2025-02-26T16:32:46.000Z","size":46740,"stargazers_count":22,"open_issues_count":8,"forks_count":28,"subscribers_count":9,"default_branch":"main","last_synced_at":"2025-02-26T17:32:21.725Z","etag":null,"topics":["extjs","php","timetracker"],"latest_commit_sha":null,"homepage":"","language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"agpl-3.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/netresearch.png","metadata":{"files":{"readme":"README.rst","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2016-05-12T13:47:03.000Z","updated_at":"2025-02-26T16:25:36.000Z","dependencies_parsed_at":"2023-01-11T18:46:35.529Z","dependency_job_id":"11da841b-4276-46ca-9edb-5050a5d2fea4","html_url":"https://github.com/netresearch/timetracker","commit_stats":null,"previous_names":[],"tags_count":27,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/netresearch%2Ftimetracker","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/netresearch%2Ftimetracker/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/netresearch%2Ftimetracker/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/netresearch%2Ftimetracker/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/netresearch","download_url":"https://codeload.github.com/netresearch/timetracker/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":241317607,"owners_count":19943199,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["extjs","php","timetracker"],"created_at":"2025-03-01T04:34:03.490Z","updated_at":"2025-03-01T04:34:04.073Z","avatar_url":"https://github.com/netresearch.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":".. header::\n   .. image:: doc/netresearch.jpg\n      :height: 25px\n      :align: left\n\n=======================\nNetresearch TimeTracker\n=======================\n\nProject and customer based time tracking for company employees.\n\nFeatures:\n\n- Time tracking with autocompletion\n   - Bulk entry for sickness or vacation\n- Per-user, pre-project and company wide charts\n   - Additional statistics via timalytics__\n- Administration interface for customers, projects, users and teams\n- XLSX export for controlling tasks\n- AD/LDAP authentication\n- Jira integration: Creates and updates worklog entries in issues\n\n\n__ https://github.com/netresearch/timalytics\n\n\n\n.. sectnum::\n\n.. contents:: Table of Contents\n\nUsage\n=====\n\nAdd worklog entry\n-----------------\n\nClick the button **Add Entry**.\nOr use the keyboard shortcut **a**.\n\nEdit worklog entry\n------------------\n\nJust click inside any field of any existing worklog entry.\n\nDelete worklog entry\n--------------------\n\nRightclick on an worklog entry and select **Delete** from context menu.\nOr use keyboard shortcut **d** to delete focused worklog entry.\n\nFocus\n-----\n\nWorklog entry with focus has a yellow background.\nMove the focus with keyboard **up** and **down** keys.\n\nUser roles\n----------\n\nDEV (Developer)\n  is allowed to track times, do bulk entries (if presets where created) and view bar charts in the\n  **Interpretation** tab\n\nCTL (Controller)\n  Includes the role **DEV** and is additionally able export data to csv in the **Controlling** tab\n\nPL (Project leader)\n  Includes the role **CTL** and is additionally able manage customers, projects, user, teams, presets,\n  ticket systems and activities in **Administration** tab\n\n\nInstallation and set up\n=======================\n\nRequirements\n------------\n\n- PHP \u003e= 7.2\n- MySQL compatible database\n- Composer\n- For more details see ``composer.json``\n\n\nSetup - manual from from sources\n--------------------------------\n\n#. Fetch a local copy::\n\n   $ git clone git@github.com:netresearch/timetracker.git\n\n#. Create a MySQL database and import ``sql/full.sql`` into it\n\n#. Install dependencies::\n\n   $ composer install\n\n   It will ask you for some configuration options.\n\n   If you want to adjust that later, edit ``app/config/parameters.yml``\n\n   Also copy ``app/config/sentry.yml.dist`` to ``app/config/sentry.yml``,\n   and fill the ``dsn`` key if necessary.\n\n#. Make cache and log directory writable::\n\n   $ chmod -R og+w app/cache/ app/logs/\n\n#. For Apache, copy ``web/.htaccess_dev`` to ``web/.htaccess``.\n\n   For nginx, symlink ``web/app_dev.php`` or ``web/app.php`` to ``web/index.php``.\n\n#. Create a virtual host web server entry\n\n   pointing to ``/path/to/timetracker/web/``\n\n#. Open the timetracker URL in your browser. If you see a white page, run::\n\n   $ php app/console assets:install\n\n#. Import test data so that you have a set of data to work and play with::\n\n   $ mysql timetracker \u003c sql/testdata.sql\n\n   Change the username of user `1` to your LDAP username.\n\n#. Login with your LDAP credentials\n\n\nSetup - with prebuilt docker images\n-----------------------------------\n\n#. Create an empty folder\n#. Put the provided docker-composer.yml from this git repo in it\n#. Put the provided nginx configuration file from this repo into the above created folder\n#. Put the provided ``app/config/parameters.yml.dist`` from this repo as ``parameters.yml`` into the above created folder, and ``sentry.yml.dist`` as ``sentry.yml``.\n#. Check and adapt the copied confoguration files to your needs\n#. Run ``docker-compose up -d``\n\n\nTrusted proxies\n---------------\n\nTo work behind a proxy Symfony needs to know which proxies are allowed to trust.\n\nThere are two ENV variables which can be set to modify the proxy behavior of the\napp:\n\nTRUSTED_PROXY_LIST\n  The variable expects a valid JSON encoded list of IPs or IP ranges::\n\n    TRUSTED_PROXY_LIST=[\"192.0.0.1\",\"10.0.0.0\\/8\"]\n\nTRUSTED_PROXY_ALL\n  The variable expects a boolean 1/0 to indicate if the application\n  should handle each address in ``$_SERVER[REMOTE_ADDR]`` as a trusted proxy::\n\n    TRUSTED_PROXY_ALL=1\n\n\nConfiguration\n=============\n\nUsing OAuth to transmit work logs to Jira ticket system\n-------------------------------------------------------\n\n#. Configure your Jira ticket system\n\n   - https://confluence.atlassian.com/display/JIRA044/Configuring+OAuth+Authentication+for+an+Application+Link\n   - https://developer.atlassian.com/server/jira/platform/oauth/\n   - https://bitbucket.org/atlassian_tutorial/atlassian-oauth-examples\n\n#. Example for Jira 7\n\n   - Create a OpenSSL key pair with private and public pem file::\n\n       $ openssl genrsa -out jira_privatekey.pem 1024\n       $ openssl req -newkey rsa:1024 -x509 -key jira_privatekey.pem -out jira_publickey.cer -days 365\n       $ openssl pkcs8 -topk8 -nocrypt -in jira_privatekey.pem -out jira_privatekey.pcks8\n       $ openssl x509 -pubkey -noout -in jira_publickey.cer  \u003e jira_publickey.pem\n\n   - Open \"Application links\" page in your Jira: https://jira.example.com/plugins/servlet/applinks/listApplicationLinks\n   - \"Create new link\" with URL pointing to your TimeTracker installation\n   - Just click \"Continue\" if Jira is blaming \"no response\"\n   - Fill out the following form:\n      - Application Name:\n           timetracker (or chose any other name you like)\n      - Application Type:\n           Generic Application\n      - Ignore the rest and hit \"Continue\"\n\n   - After new Application is created click on action \"edit\" (the little pencil at the right to your new application)\n      - Select \"Incoming Authentication\"\n      - Consumer Key:\n           timetracker (or chose any other name you like)\n      - Consumer Name:\n           TimeTracker (or chose any other name you like)\n      - Public Key:\n           Insert here the public key you created above (``jira_publickey.pem``)\n      - Click on \"Save\"\n\n#. Create a ticket system in TimeTracker\n\n   - Set the type to **Jira**\n   - Check the field **timebooking**\n   - Enter the Base-URL to your Jira ticket system\n   - The ticket URL is used for referencing ticket names to Jira\n     \"%s\" serves is a placeholder for the ticket name in the URL\n     (your URL might look as the following: https://jira.example.com/browse/%s)\n   - The fields login, password, public and private key can be left empty\n   - Enter the OAuth consumer key you already entered in Jira (``timetracker``)\n   - Enter your private key you created above into OAuth consumer secret field\n     (``jira_privatekey.pcks8``).\n     Must begin with ``-----BEGIN PRIVATE KEY-----`` (not ``BEGIN RSA``!).\n\n#. Assign this ticket system to at least one project\n\n#. Start time tracking to this project\n\n   - The TimeTracker checks if a valid Jira access token is available\n   - If this is missing or incorrect the user is going to be forwarded to the Jira ticket system,\n     which asks for the permission to grant read / write access to the TimeTracker.\n   - If permitting, the user will receive an access token from Jira.\n   - If not, he won't be asked for permission again.\n   - With a valid access token the TimeTracker will add / edit a Jira work log for each entry with a valid\n     ticket name.\n   - The permission can be revoked by each user in its settings section in Jira.\n\nAutomatically create TimeTracker user on valid LDAP authentication\n------------------------------------------------------------------\n\nPer default every TimeTracker user has to be created manually.\nWhile setting **ldap_create_user** in **app/config/parameters.yml** to **true** new users of type **DEV** are going\nto be created automatically on a valid LDAP authentication. The type can be changed afterwards via the\nusers panel in the administration tab or directly in the database.\n\n\nTrack time for external ticket systems to internal ticket system\n----------------------------------------------------------------\n\nSometimes you not only want to track the times for the tickets from your ticket system.\nAssuming that you have a client providing an own ticket system, but you want to track the times\nfor work on this tickets into your ticket system.\n\nExample:\n\n* Your client provides tickets to your team via an own ticker system\n* The ticket numbers may be ``EXTERNAL-1``, ``EXTERNAL-200`` etc.\n* You share the information regarding the progress of the ticket in the clients ticket system\n* But you want to track the working time in your internal ticket system instance\n* Normally you would need to create a ticket in your ticket system e.g. name ``INTERNAL-1``\n* You then would be able to book you efforts to ``INTERNAL-1`` via Timetracker\n* That's quite ineffective because you always need to create an internal ticket\n\nThis feature tries to solve that problem.\n\n#. Create a project in Jira where the external times should be applied to\n\n   #. Create a Jira project the Timetracker user has access to\n   #. Ensure that the project provides the issue type ``task``\n   #. Let's assume it is named ``Customer Project`` with the key ``INTERNAL``\n\n#. Create the client's ticket system in TimeTracker\n\n   #. Go to ``Administration \u003e Ticket-Sytem`` and create a new one:\n\n      Name:\n        e.g. ``Customer ticket system``\n\n      Type:\n        ``Jira`` or ``Other`` or what you like\n\n        The type does not effect this feature in any way\n\n      URL:\n        e.g. ``https://ticketing.customer.org/%s``\n\n        This is used to generate links in the work log description\n\n      Timebooking:\n        No\n\n        This disables any contact to external ticket system\n\n   #. Save the entry\n\n#. Create the external project in TimeTracker\n\n   #. Go to ``Administration \u003e Projects`` and create a new one:\n\n      Name:\n        set to e.g. ``Customer Project``\n\n      Ticket-System:\n        Select the above created ``Customer ticket system``\n\n      Ticket-Prefix:\n        Enter the prefix of your customers project tickets e.g. ``EXTERNAL`` if the tickets are in the form\n        ``EXTERNAL-123``\n\n      Active:\n        Yes\n\n      \"Internal Jira project key\":\n        select ``INTERNAL``\n\n      \"Internal Jira ticket system\":\n        select your internal ticket system\n\nIf everything is correct, the following will happen:\n\n* If you are booking some working time to e.g. ``EXTERNAL-1`` in TimeTracker for project ``Customer Project``\n* TimeTracker will reach out for the configured internal Jira instance\n* It will search for an issue which name/summary starts with ``EXTERNAL-1`` in the configured internal Jira project\n* If it finds an entry, the work log is applied to this entry\n* If it does not find an entry, TimeTracker will create a new internal ticket with name ``EXTERNAL-1``\n* The link to the ticket in customer Jira will be applied as ticket description\n* The work log is applied to the newly created ticket\n\n\nExtras\n======\n\nJIRA cloud integration\n----------------------\n\n.. image:: doc/images/jira-cloud-1.png\n   :alt: Jira cloud: Button \"Zeiten aus Timetracker laden\"\n\n\n.. image:: doc/images/jira-cloud-2.png\n   :alt: Jira cloud displaying times\n\n\nIt is possible to show the timetracker times in Jira cloud,\neven when not syncing the times into such an instance.\n\nTo get it working, install the `Greasemonkey browser extension`__ and import\nthe ``scripts/timeSummaryForJira`` script.\n\nThen visit a ticket detail page of a cloud-hosted Jira instance.\nThe right sidebar will show a \"Zeiten aus Timetracker laden\" button.\nWhen it has been clicked, the statistics are fetched from the Timetracker API\nand displayed there.\n\n__ https://addons.mozilla.org/de/firefox/addon/greasemonkey/\n\n\nAPI documentation\n=================\nThe timetracker API is documented in ``web/api.yml`` (OpenAPI v3).\n\n\nDeveloper References\n====================\n\n- https://symfony.com/doc/current/setup/docker.html\n- https://github.com/friendsofphp/PHP-CS-Fixer\n- https://github.com/symfony/demo\n- https://github.com/rectorphp/rector\n  - https://github.com/rectorphp/rector/blob/main/docs/rector_rules_overview.md","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fnetresearch%2Ftimetracker","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fnetresearch%2Ftimetracker","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fnetresearch%2Ftimetracker/lists"}