def update_task_pm_updates(task):
task = clean_instance(task, Task)
target_task = task
if task.parent:
# for sub-tasks, create all pm updates on the project
target_task = task.parent
if target_task.closed or target_task.is_task or not target_task.approved or not target_task.pm:
# only request pm updates for project which are approved and not closed
return
if target_task.update_interval and target_task.update_interval_units:
periodic_start_date = ProgressEvent.objects.filter(
Q(task=target_task) | Q(task__parent=target_task), type=PROGRESS_EVENT_TYPE_PM
).aggregate(latest_date=Max('due_at'))['latest_date']
now = datetime.datetime.utcnow()
if periodic_start_date and periodic_start_date > now:
return
if not periodic_start_date:
periodic_start_date = datetime.datetime.utcnow()
if periodic_start_date:
last_update_at = clean_update_datetime(periodic_start_date, target_task)
while True:
last_update_day = last_update_at.weekday()
next_update_at = last_update_at
if last_update_day < 3:
# Last was before Thursday so schedule for Thursday
next_update_at += relativedelta(days=3 - last_update_day)
else:
# Last was on after Thursday so schedule for Monday
next_update_at += relativedelta(days=7 - last_update_day)
if next_update_at >= now:
future_by_18_hours = now + relativedelta(hours=18)
if next_update_at <= future_by_18_hours and (
not target_task.deadline or next_update_at < target_task.deadline):
num_updates_within_on_same_day = ProgressEvent.objects.filter(
task=target_task, type=PROGRESS_EVENT_TYPE_PM,
due_at__contains=next_update_at.date()
).count()
if num_updates_within_on_same_day == 0:
# Schedule at most one pm update for any day
ProgressEvent.objects.update_or_create(
task=target_task, type=PROGRESS_EVENT_TYPE_PM,
due_at=next_update_at, defaults={'title': 'PM Report'}
)
break
else:
last_update_at = next_update_at
评论列表
文章目录