def get_burndown_data(self, user_id, group_id, start_date, end_date, worksheet_ids=None, assignee_ids=None): if group_id is None: raise RequiredError(label="cont_label_group") if start_date is None: raise RequiredError(label="rept_label_startdate") if end_date is None: raise RequiredError(label="rept_label_enddate") today = dtutil.localtoday(conf.get_preferred_timezone()) daysBurndownLine = stdModel(guide=[], actual=[], forecast=[], teamEffort=[], requireRate=[]) workdates = self.get_workdates(start_date, end_date, group_id) for date in workdates: daysBurndownLine.guide[date] = [date, 0] # [date, days] if date <= today: daysBurndownLine.actual[date] = [date, 0] # [date, days] else: daysBurndownLine.forecast[date] = [date, 0] # [date, days] daysBurndownLine.teamEffort = [date, 0] # [date, days] daysBurndownLine.requireRate = [date, 0] # [date, rate] tasks = self.fetch_tasks(user_id, group_id, worksheet_ids, assignee_ids) duration = self.get_workdays(start_date, end_date, group_id) for task in tasks: if task.due_startdate >= start_date and task.due_finishdate <= end_date: for date, guidearr in daysBurndownLine.guide.items(): task_workdays = self.get_workdays(task.due_startdate, task.due_finishdate, group_id) if task.t_status_code != "task_code_cancel": days = (duration - (date - start_date).days) / duration * task_workdays guidearr[1] += days if date <= today and task.actual: """"""
def create_task(self, task, modifier_id): task.is_trashed = False if task.t_status_code == 'task_code_inprogress': task.actual_startdate = dtutil.localtoday(conf.get_preferred_timezone()) task.put(modifier_id) self.create_taskcomponents(task.key(), task.component_ids, modifier_id) self.create_taskversions(task.key(), task.affected_version_ids, True, modifier_id) self.create_taskversions(task.key(), task.fixed_version_ids, False, modifier_id) return task
def update_task(self, task, modifier_id): nt = Task.get_by_key(task.uid) if task.creator_id != modifier_id and nt.worksheet_id != task.worksheet_id: raise Error("task_error_movesharedtask") if nt.is_trashed : raise Error("task_error_trashed_update") if task.t_status_code == 'task_code_closed': task.actual_finishdate = dtutil.localtoday(conf.get_preferred_timezone()) if nt.actual_startdate is None: task.actual_startdate = dtutil.localtoday(conf.get_preferred_timezone()) else: task.actual_finishdate = None if task.t_status_code == 'task_code_inprogress' and nt.t_status_code != 'task_code_inprogress' and task.actual_startdate != None: task.actual_startdate = dtutil.localtoday(conf.get_preferred_timezone()) task.put(modifier_id) self.create_taskcomponents(task.key(), task.component_ids, modifier_id) self.create_taskversions(task.key(), task.affected_version_ids, True, modifier_id) self.create_taskversions(task.key(), task.fixed_version_ids, False, modifier_id) return task
def to_dict(self): tdt = BaseModel.to_dict(self) tzstr = conf.get_preferred_timezone() ctp = self.get_property("created_time") ctp.fmt = conf.get_datesecond_py_format() created_time = dtutil.to_local(self.created_time, tzstr) tdt["createdTime"] = ctp.to_string(created_time) mtp = self.get_property("modified_time") mtp.fmt = conf.get_datesecond_py_format() modified_time = dtutil.to_local(self.modified_time, tzstr) tdt["modifiedTime"] = mtp.to_string(modified_time) return tdt
def resolve(self, query, **kwargs): if self._key != "dt": return query today = dtutil.localtoday(conf.get_preferred_timezone()) if self._value == self.OVERDUE_ID: query.filter('due_finishdate <', today) query.order('due_finishdate') elif self._value == self.NOTIMELIMIT_ID: query.filter("due_finishdate is", None, wrapper=False) else: query.filter('ex ex', "DATEDIFF(due_finishdate, '%s') <= %d" % (str(today), self._value), wrapper=False) query.order('due_finishdate') query.filter("t_status_code !=", 'task_code_closed') query.filter("t_status_code !=", 'task_code_cancel') return query
def get_plan_progress(self): planprogress = 'NA' if self.due_finishdate is not None and self.due_startdate is not None: starttime = self.due_startdate finishtime = self.due_finishdate plantd = finishtime - starttime + timedelta(days=1) now = dtutil.localtoday(conf.get_preferred_timezone()) nowtd = now - starttime if starttime < now : if plantd.total_seconds() != 0: planprogress = round(nowtd.total_seconds() / plantd.total_seconds(), 3) * 100 if planprogress > 100: ps = round(plantd.total_seconds() * (planprogress - 100) / (100 * 60 * 60 * 24), 1) planprogress = "100%%+%0.0f%s" % (ps, i18n.get_i18n_message(conf.get_preferred_language(), "core_label_day")) else: planprogress = "%0.0f%%" % planprogress else: planprogress = "100%" else: planprogress = "0%" self.planProgress = planprogress return planprogress
def get_progress_data(self, user_id, start_date, end_date, worksheet_ids, group_id=None, assignee_ids=None): if worksheet_ids is None or len(worksheet_ids) == 0: raise RequiredError("task_label_worksheet") if start_date is None: raise RequiredError(label="rept_label_startdate") if end_date is None: raise RequiredError(label="rept_label_enddate") if end_date <= start_date: raise CompareError( label="rept_label_enddate", limitlabel="rept_label_startdate", limit=start_date, operator=">" ) today = dtutil.localtoday(conf.get_preferred_timezone()) finishtaskcount = 0 progressLine = stdModel(plan={}, actual={}, forecast={}) progressBar = {} for priority in i18n.get_i18n_messages( conf.get_preferred_language(), "task_priority_code", rtn_dict=True ).keys(): statusTaskCount = [0, 0, 0] # planFinishCount, actualFinishCount, cancelCount progressBar[priority] = statusTaskCount rtn = stdModel(progressLine=progressLine, progressBar=progressBar, deviationTasks=[]) dates = self.get_workdates(start_date, end_date, group_id) for date in dates: progressLine.plan[date] = [date, 0] # [date, finish count] if date <= today: progressLine.actual[date] = [date, 0] # [date, finish count] else: progressLine.forecast[date] = [date, 0] # [date, finish count] tasks = self.fetch_tasks(user_id, None, worksheet_ids, assignee_ids) for task in tasks: for date, planstd in progressLine.plan.items(): if date <= today and task.t_status_code == "task_code_closed" and task.actual_finishdate <= date: progressLine.actual[date][1] += 1 if task.due_finishdate <= date and task.t_status_code != "task_code_cancel": planstd[1] += 1 if task.t_status_code != "task_code_closed" and task.t_status_code != "task_code_cancel": progress = task.get_plan_progress_int() if progress > task.actual_progress: task.deviationStatus = "rept_label_deviationdelay" elif progress < task.actual_progress: task.deviationStatus = "rept_label_deviationadvance" if progress != task.actual_progress: task.assigneeName = ContactService.get_instance().get_contact_name(task.assignee_id) comments = TaskService.get_instance().fetch_taskcomments(task.key(), limit=1) task.lastComment = comments[0].tc_content if len(comments) > 0 else "" rtn.deviationTasks.append(task) else: if ( task.t_status_code == "task_code_closed" and task.actual_startdate >= start_date and task.actual_finishdate <= today ): finishtaskcount += 1 statusTaskCount = progressBar[task.t_priority_code] if task.due_finishdate <= end_date: if task.t_status_code == "task_code_cancel": statusTaskCount[2] += 1 else: statusTaskCount[0] += 1 if task.t_status_code == "task_code_closed": statusTaskCount[1] += 1 speed = finishtaskcount / float(self.get_workdays(start_date, today, None, None)) for date, forestd in progressLine.forecast.items(): forestd[1] = finishtaskcount + speed * ((date - today).days + 1) if end_date > today: progressLine.forecast[today] = [today, float(progressLine.actual[today][1])] progressLine.plan = progressLine.plan.values() progressLine.actual = progressLine.actual.values() progressLine.forecast = progressLine.forecast.values() return rtn