{"action":"created","comment":{"url":"https://api.github.com/repos/google/ggrc-core/pulls/comments/125518206","pull_request_review_id":47914189,"id":125518206,"diff_hunk":"@@ -87,14 +87,29 @@ def add_cycle_task_due_notifications(task):\n   if not task.cycle_task_group.cycle.is_current:\n     return\n \n+  today = date.today()\n+\n+  # NOTE: when deciding whether or not to create a new notification, we require\n+  # the send_on date to be strictly greater than TODAY - new notifications with\n+  # send_on date equal to TODAY will not be sent in time, because the cron job\n+  # for sending notifications runs soon after midnight (1 AM?)\n+  #\n+  # Yes, there is a small time window between midnight and the time the daily\n+  # notifications are processed and sent, but it unlikely users will work at\n+  # those hours. Also, this issue is likely already affecting several other\n+  # existing notifications and time checks revolving around TODAY, requiring\n+  # a holistic approac to solving it.\n+\n   notif_type = get_notification_type(\"{}_cycle_task_due_in\".format(\n       task.cycle_task_group.cycle.workflow.frequency))\n   send_on = task.end_date - timedelta(notif_type.advance_notice)\n-  add_notif(task, notif_type, send_on)\n+  if send_on > today:\n+    add_notif(task, notif_type, send_on)\n \n   notif_type = get_notification_type(\"cycle_task_due_today\")\n   send_on = task.end_date - timedelta(notif_type.advance_notice)\n-  add_notif(task, notif_type, send_on)\n+  if send_on > today:","path":"src/ggrc_workflows/notification/notification_handler.py","position":27,"original_position":27,"commit_id":"917a413fa47babd0dfa92bf50efed57fb500244a","original_commit_id":"917a413fa47babd0dfa92bf50efed57fb500244a","user":{"login":"plamut","id":1235663,"avatar_url":"https://avatars3.githubusercontent.com/u/1235663?v=3","gravatar_id":"","url":"https://api.github.com/users/plamut","html_url":"https://github.com/plamut","followers_url":"https://api.github.com/users/plamut/followers","following_url":"https://api.github.com/users/plamut/following{/other_user}","gists_url":"https://api.github.com/users/plamut/gists{/gist_id}","starred_url":"https://api.github.com/users/plamut/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/plamut/subscriptions","organizations_url":"https://api.github.com/users/plamut/orgs","repos_url":"https://api.github.com/users/plamut/repos","events_url":"https://api.github.com/users/plamut/events{/privacy}","received_events_url":"https://api.github.com/users/plamut/received_events","type":"User","site_admin":false},"body":"Unfortunately not, at least not without carefully examining all notification types and checking how such a change would affect them.\r\n\r\nFor example, a \"task overdue\" notification is not constrained to a particular date and still has relevance even if it is sent a few days after the Task's `end_date`. If somebody creates a Task that was due, say, a week ago already, notification should still be sent, even though its `send_on` on date would already be in the past.\r\n\r\nThe date check in this PR is thus limited to a specific notification type only.\r\n\r\n","created_at":"2017-07-04T18:28:56Z","updated_at":"2017-07-04T18:28:57Z","html_url":"https://github.com/google/ggrc-core/pull/5817#discussion_r125518206","pull_request_url":"https://api.github.com/repos/google/ggrc-core/pulls/5817","_links":{"self":{"href":"https://api.github.com/repos/google/ggrc-core/pulls/comments/125518206"},"html":{"href":"https://github.com/google/ggrc-core/pull/5817#discussion_r125518206"},"pull_request":{"href":"https://api.github.com/repos/google/ggrc-core/pulls/5817"}}},"pull_request":{"url":"https://api.github.com/repos/google/ggrc-core/pulls/5817","id":126328662,"html_url":"https://github.com/google/ggrc-core/pull/5817","diff_url":"https://github.com/google/ggrc-core/pull/5817.diff","patch_url":"https://github.com/google/ggrc-core/pull/5817.patch","issue_url":"https://api.github.com/repos/google/ggrc-core/issues/5817","number":5817,"state":"open","locked":false,"title":"GGRC-1603 Show exact date in task due today notification","user":{"login":"plamut","id":1235663,"avatar_url":"https://avatars3.githubusercontent.com/u/1235663?v=3","gravatar_id":"","url":"https://api.github.com/users/plamut","html_url":"https://github.com/plamut","followers_url":"https://api.github.com/users/plamut/followers","following_url":"https://api.github.com/users/plamut/following{/other_user}","gists_url":"https://api.github.com/users/plamut/gists{/gist_id}","starred_url":"https://api.github.com/users/plamut/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/plamut/subscriptions","organizations_url":"https://api.github.com/users/plamut/orgs","repos_url":"https://api.github.com/users/plamut/repos","events_url":"https://api.github.com/users/plamut/events{/privacy}","received_events_url":"https://api.github.com/users/plamut/received_events","type":"User","site_admin":false},"body":"This PR changes the email text for the \"cycle task due today\" notifications.\r\n\r\n---\r\n\r\nHow to test:\r\n- create a Workflow (best to use one-time WF) with a few tasks, with some of them scheduled to be finished _tomorrow_, i.e. current date + 1 day.\r\n- Activate workflow\r\n- Change system time to tomorrow and visit the daily digest preview page `/_notifications/show_daily_digest`.\r\n- Search for the \"due on\" text\r\n\r\n**Expected result:**\r\nThe tasks due on fake \"today\" (i.e. real current date + 1 day) are indeed listed, there is no ambiguous word _\"today\"_ - instead, the actual date (in US format) the tasks are due on is displayed.\r\n\r\nNOTE:\r\nSingular or plural form should be used for the word \"task\" depending on the number of items in the list.\r\n\r\nNOTE 2:\r\nNotification should not be sent if is relevant for a past date, e.g. if creating a task that is already overdue.\r\n\r\nAlso, if creating a task that is due on the current date, a notification **is not created**, because by the time such notification would be sent (next day at ~1 AM), it would already be obsolete. Please see the comment in the code for additional explanation.\r\n\r\nNOTE 3:\r\nFor the same reason, if you create a task that is due \"tomorrow\", you will not see the _\"task due very soon\" notification - this PR also fixes the problem with those notifications that were being sent even for overdue tasks or tasks due \"today\".\r\n","created_at":"2017-06-19T15:16:30Z","updated_at":"2017-07-04T18:28:57Z","closed_at":null,"merged_at":null,"merge_commit_sha":"21df4d5d9d5ef1a0ec0ea4815f5234aa9acafabc","assignee":{"login":"pod2metra","id":2368067,"avatar_url":"https://avatars0.githubusercontent.com/u/2368067?v=3","gravatar_id":"","url":"https://api.github.com/users/pod2metra","html_url":"https://github.com/pod2metra","followers_url":"https://api.github.com/users/pod2metra/followers","following_url":"https://api.github.com/users/pod2metra/following{/other_user}","gists_url":"https://api.github.com/users/pod2metra/gists{/gist_id}","starred_url":"https://api.github.com/users/pod2metra/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/pod2metra/subscriptions","organizations_url":"https://api.github.com/users/pod2metra/orgs","repos_url":"https://api.github.com/users/pod2metra/repos","events_url":"https://api.github.com/users/pod2metra/events{/privacy}","received_events_url":"https://api.github.com/users/pod2metra/received_events","type":"User","site_admin":false},"assignees":[{"login":"pod2metra","id":2368067,"avatar_url":"https://avatars0.githubusercontent.com/u/2368067?v=3","gravatar_id":"","url":"https://api.github.com/users/pod2metra","html_url":"https://github.com/pod2metra","followers_url":"https://api.github.com/users/pod2metra/followers","following_url":"https://api.github.com/users/pod2metra/following{/other_user}","gists_url":"https://api.github.com/users/pod2metra/gists{/gist_id}","starred_url":"https://api.github.com/users/pod2metra/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/pod2metra/subscriptions","organizations_url":"https://api.github.com/users/pod2metra/orgs","repos_url":"https://api.github.com/users/pod2metra/repos","events_url":"https://api.github.com/users/pod2metra/events{/privacy}","received_events_url":"https://api.github.com/users/pod2metra/received_events","type":"User","site_admin":false}],"requested_reviewers":[],"milestone":{"url":"https://api.github.com/repos/google/ggrc-core/milestones/54","html_url":"https://github.com/google/ggrc-core/milestone/54","labels_url":"https://api.github.com/repos/google/ggrc-core/milestones/54/labels","id":2620940,"number":54,"title":"0.10.22-Raspberry","description":"","creator":{"login":"alieh-rymasheuski","id":9883236,"avatar_url":"https://avatars1.githubusercontent.com/u/9883236?v=3","gravatar_id":"","url":"https://api.github.com/users/alieh-rymasheuski","html_url":"https://github.com/alieh-rymasheuski","followers_url":"https://api.github.com/users/alieh-rymasheuski/followers","following_url":"https://api.github.com/users/alieh-rymasheuski/following{/other_user}","gists_url":"https://api.github.com/users/alieh-rymasheuski/gists{/gist_id}","starred_url":"https://api.github.com/users/alieh-rymasheuski/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/alieh-rymasheuski/subscriptions","organizations_url":"https://api.github.com/users/alieh-rymasheuski/orgs","repos_url":"https://api.github.com/users/alieh-rymasheuski/repos","events_url":"https://api.github.com/users/alieh-rymasheuski/events{/privacy}","received_events_url":"https://api.github.com/users/alieh-rymasheuski/received_events","type":"User","site_admin":false},"open_issues":32,"closed_issues":3,"state":"open","created_at":"2017-07-04T11:58:30Z","updated_at":"2017-07-04T14:30:29Z","due_on":"2017-07-11T07:00:00Z","closed_at":null},"commits_url":"https://api.github.com/repos/google/ggrc-core/pulls/5817/commits","review_comments_url":"https://api.github.com/repos/google/ggrc-core/pulls/5817/comments","review_comment_url":"https://api.github.com/repos/google/ggrc-core/pulls/comments{/number}","comments_url":"https://api.github.com/repos/google/ggrc-core/issues/5817/comments","statuses_url":"https://api.github.com/repos/google/ggrc-core/statuses/917a413fa47babd0dfa92bf50efed57fb500244a","head":{"label":"plamut:ggrc-1603","ref":"ggrc-1603","sha":"917a413fa47babd0dfa92bf50efed57fb500244a","user":{"login":"plamut","id":1235663,"avatar_url":"https://avatars3.githubusercontent.com/u/1235663?v=3","gravatar_id":"","url":"https://api.github.com/users/plamut","html_url":"https://github.com/plamut","followers_url":"https://api.github.com/users/plamut/followers","following_url":"https://api.github.com/users/plamut/following{/other_user}","gists_url":"https://api.github.com/users/plamut/gists{/gist_id}","starred_url":"https://api.github.com/users/plamut/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/plamut/subscriptions","organizations_url":"https://api.github.com/users/plamut/orgs","repos_url":"https://api.github.com/users/plamut/repos","events_url":"https://api.github.com/users/plamut/events{/privacy}","received_events_url":"https://api.github.com/users/plamut/received_events","type":"User","site_admin":false},"repo":{"id":46784845,"name":"ggrc-core","full_name":"plamut/ggrc-core","owner":{"login":"plamut","id":1235663,"avatar_url":"https://avatars3.githubusercontent.com/u/1235663?v=3","gravatar_id":"","url":"https://api.github.com/users/plamut","html_url":"https://github.com/plamut","followers_url":"https://api.github.com/users/plamut/followers","following_url":"https://api.github.com/users/plamut/following{/other_user}","gists_url":"https://api.github.com/users/plamut/gists{/gist_id}","starred_url":"https://api.github.com/users/plamut/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/plamut/subscriptions","organizations_url":"https://api.github.com/users/plamut/orgs","repos_url":"https://api.github.com/users/plamut/repos","events_url":"https://api.github.com/users/plamut/events{/privacy}","received_events_url":"https://api.github.com/users/plamut/received_events","type":"User","site_admin":false},"private":false,"html_url":"https://github.com/plamut/ggrc-core","description":"GGRC Core","fork":true,"url":"https://api.github.com/repos/plamut/ggrc-core","forks_url":"https://api.github.com/repos/plamut/ggrc-core/forks","keys_url":"https://api.github.com/repos/plamut/ggrc-core/keys{/key_id}","collaborators_url":"https://api.github.com/repos/plamut/ggrc-core/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/plamut/ggrc-core/teams","hooks_url":"https://api.github.com/repos/plamut/ggrc-core/hooks","issue_events_url":"https://api.github.com/repos/plamut/ggrc-core/issues/events{/number}","events_url":"https://api.github.com/repos/plamut/ggrc-core/events","assignees_url":"https://api.github.com/repos/plamut/ggrc-core/assignees{/user}","branches_url":"https://api.github.com/repos/plamut/ggrc-core/branches{/branch}","tags_url":"https://api.github.com/repos/plamut/ggrc-core/tags","blobs_url":"https://api.github.com/repos/plamut/ggrc-core/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/plamut/ggrc-core/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/plamut/ggrc-core/git/refs{/sha}","trees_url":"https://api.github.com/repos/plamut/ggrc-core/git/trees{/sha}","statuses_url":"https://api.github.com/repos/plamut/ggrc-core/statuses/{sha}","languages_url":"https://api.github.com/repos/plamut/ggrc-core/languages","stargazers_url":"https://api.github.com/repos/plamut/ggrc-core/stargazers","contributors_url":"https://api.github.com/repos/plamut/ggrc-core/contributors","subscribers_url":"https://api.github.com/repos/plamut/ggrc-core/subscribers","subscription_url":"https://api.github.com/repos/plamut/ggrc-core/subscription","commits_url":"https://api.github.com/repos/plamut/ggrc-core/commits{/sha}","git_commits_url":"https://api.github.com/repos/plamut/ggrc-core/git/commits{/sha}","comments_url":"https://api.github.com/repos/plamut/ggrc-core/comments{/number}","issue_comment_url":"https://api.github.com/repos/plamut/ggrc-core/issues/comments{/number}","contents_url":"https://api.github.com/repos/plamut/ggrc-core/contents/{+path}","compare_url":"https://api.github.com/repos/plamut/ggrc-core/compare/{base}...{head}","merges_url":"https://api.github.com/repos/plamut/ggrc-core/merges","archive_url":"https://api.github.com/repos/plamut/ggrc-core/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/plamut/ggrc-core/downloads","issues_url":"https://api.github.com/repos/plamut/ggrc-core/issues{/number}","pulls_url":"https://api.github.com/repos/plamut/ggrc-core/pulls{/number}","milestones_url":"https://api.github.com/repos/plamut/ggrc-core/milestones{/number}","notifications_url":"https://api.github.com/repos/plamut/ggrc-core/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/plamut/ggrc-core/labels{/name}","releases_url":"https://api.github.com/repos/plamut/ggrc-core/releases{/id}","deployments_url":"https://api.github.com/repos/plamut/ggrc-core/deployments","created_at":"2015-11-24T10:37:33Z","updated_at":"2016-11-07T17:12:47Z","pushed_at":"2017-07-04T17:21:01Z","git_url":"git://github.com/plamut/ggrc-core.git","ssh_url":"git@github.com:plamut/ggrc-core.git","clone_url":"https://github.com/plamut/ggrc-core.git","svn_url":"https://github.com/plamut/ggrc-core","homepage":null,"size":61755,"stargazers_count":1,"watchers_count":1,"language":"Python","has_issues":false,"has_projects":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":0,"mirror_url":null,"open_issues_count":0,"forks":0,"open_issues":0,"watchers":1,"default_branch":"develop"}},"base":{"label":"google:dev","ref":"dev","sha":"164b7f7006231e8fc29c93ad36a4572b9fd4b89f","user":{"login":"google","id":1342004,"avatar_url":"https://avatars2.githubusercontent.com/u/1342004?v=3","gravatar_id":"","url":"https://api.github.com/users/google","html_url":"https://github.com/google","followers_url":"https://api.github.com/users/google/followers","following_url":"https://api.github.com/users/google/following{/other_user}","gists_url":"https://api.github.com/users/google/gists{/gist_id}","starred_url":"https://api.github.com/users/google/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/google/subscriptions","organizations_url":"https://api.github.com/users/google/orgs","repos_url":"https://api.github.com/users/google/repos","events_url":"https://api.github.com/users/google/events{/privacy}","received_events_url":"https://api.github.com/users/google/received_events","type":"Organization","site_admin":false},"repo":{"id":9304637,"name":"ggrc-core","full_name":"google/ggrc-core","owner":{"login":"google","id":1342004,"avatar_url":"https://avatars2.githubusercontent.com/u/1342004?v=3","gravatar_id":"","url":"https://api.github.com/users/google","html_url":"https://github.com/google","followers_url":"https://api.github.com/users/google/followers","following_url":"https://api.github.com/users/google/following{/other_user}","gists_url":"https://api.github.com/users/google/gists{/gist_id}","starred_url":"https://api.github.com/users/google/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/google/subscriptions","organizations_url":"https://api.github.com/users/google/orgs","repos_url":"https://api.github.com/users/google/repos","events_url":"https://api.github.com/users/google/events{/privacy}","received_events_url":"https://api.github.com/users/google/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/google/ggrc-core","description":"GGRC Core","fork":false,"url":"https://api.github.com/repos/google/ggrc-core","forks_url":"https://api.github.com/repos/google/ggrc-core/forks","keys_url":"https://api.github.com/repos/google/ggrc-core/keys{/key_id}","collaborators_url":"https://api.github.com/repos/google/ggrc-core/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/google/ggrc-core/teams","hooks_url":"https://api.github.com/repos/google/ggrc-core/hooks","issue_events_url":"https://api.github.com/repos/google/ggrc-core/issues/events{/number}","events_url":"https://api.github.com/repos/google/ggrc-core/events","assignees_url":"https://api.github.com/repos/google/ggrc-core/assignees{/user}","branches_url":"https://api.github.com/repos/google/ggrc-core/branches{/branch}","tags_url":"https://api.github.com/repos/google/ggrc-core/tags","blobs_url":"https://api.github.com/repos/google/ggrc-core/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/google/ggrc-core/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/google/ggrc-core/git/refs{/sha}","trees_url":"https://api.github.com/repos/google/ggrc-core/git/trees{/sha}","statuses_url":"https://api.github.com/repos/google/ggrc-core/statuses/{sha}","languages_url":"https://api.github.com/repos/google/ggrc-core/languages","stargazers_url":"https://api.github.com/repos/google/ggrc-core/stargazers","contributors_url":"https://api.github.com/repos/google/ggrc-core/contributors","subscribers_url":"https://api.github.com/repos/google/ggrc-core/subscribers","subscription_url":"https://api.github.com/repos/google/ggrc-core/subscription","commits_url":"https://api.github.com/repos/google/ggrc-core/commits{/sha}","git_commits_url":"https://api.github.com/repos/google/ggrc-core/git/commits{/sha}","comments_url":"https://api.github.com/repos/google/ggrc-core/comments{/number}","issue_comment_url":"https://api.github.com/repos/google/ggrc-core/issues/comments{/number}","contents_url":"https://api.github.com/repos/google/ggrc-core/contents/{+path}","compare_url":"https://api.github.com/repos/google/ggrc-core/compare/{base}...{head}","merges_url":"https://api.github.com/repos/google/ggrc-core/merges","archive_url":"https://api.github.com/repos/google/ggrc-core/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/google/ggrc-core/downloads","issues_url":"https://api.github.com/repos/google/ggrc-core/issues{/number}","pulls_url":"https://api.github.com/repos/google/ggrc-core/pulls{/number}","milestones_url":"https://api.github.com/repos/google/ggrc-core/milestones{/number}","notifications_url":"https://api.github.com/repos/google/ggrc-core/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/google/ggrc-core/labels{/name}","releases_url":"https://api.github.com/repos/google/ggrc-core/releases{/id}","deployments_url":"https://api.github.com/repos/google/ggrc-core/deployments","created_at":"2013-04-08T19:16:28Z","updated_at":"2017-06-23T13:09:25Z","pushed_at":"2017-07-04T18:20:30Z","git_url":"git://github.com/google/ggrc-core.git","ssh_url":"git@github.com:google/ggrc-core.git","clone_url":"https://github.com/google/ggrc-core.git","svn_url":"https://github.com/google/ggrc-core","homepage":null,"size":60507,"stargazers_count":214,"watchers_count":214,"language":"Python","has_issues":true,"has_projects":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":150,"mirror_url":null,"open_issues_count":34,"forks":150,"open_issues":34,"watchers":214,"default_branch":"dev"}},"_links":{"self":{"href":"https://api.github.com/repos/google/ggrc-core/pulls/5817"},"html":{"href":"https://github.com/google/ggrc-core/pull/5817"},"issue":{"href":"https://api.github.com/repos/google/ggrc-core/issues/5817"},"comments":{"href":"https://api.github.com/repos/google/ggrc-core/issues/5817/comments"},"review_comments":{"href":"https://api.github.com/repos/google/ggrc-core/pulls/5817/comments"},"review_comment":{"href":"https://api.github.com/repos/google/ggrc-core/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/google/ggrc-core/pulls/5817/commits"},"statuses":{"href":"https://api.github.com/repos/google/ggrc-core/statuses/917a413fa47babd0dfa92bf50efed57fb500244a"}}}}
{"actor":{"display_login":"plamut"}}