def update_cycle_task_group_parent_state(objs): """Update cycle status for sent cycle task group""" objs = [obj for obj in objs or [] if obj.cycle.workflow.kind != "Backlog"] if not objs: return cycles_dict = {} cycle_groups_dict = collections.defaultdict(set) group_ids = [] for obj in objs: cycle_groups_dict[obj.cycle].add(obj) group_ids.append(obj.id) cycles_dict[obj.cycle.id] = obj.cycle # collect all groups that are in same cycles that group from sent list groups = models.CycleTaskGroup.query.filter( models.CycleTaskGroup.cycle_id.in_([c.id for c in cycle_groups_dict]), ).options( orm.undefer_group("CycleTaskGroup_complete") ).distinct().with_for_update().all() for group in groups: cycle_groups_dict[cycles_dict[group.cycle_id]].add(group) updated_cycles = [] for cycle in cycles_dict.itervalues(): old_status = cycle.status _update_parent_status(cycle, {g.status for g in cycle_groups_dict[cycle]}) cycle.start_date, cycle.end_date = _get_date_range( cycle_groups_dict[cycle]) cycle.next_due_date = _get_min_next_due_date(cycle_groups_dict[cycle]) if old_status != cycle.status: updated_cycles.append(Signals.StatusChangeSignalObjectContext( instance=cycle, old_status=old_status, new_status=cycle.status)) if updated_cycles: Signals.status_change.send(models.Cycle, objs=updated_cycles)
def handle_cycle_task_group_object_task_put( sender, obj=None, src=None, service=None): # noqa pylint: disable=unused-argument if inspect(obj).attrs.status.history.has_changes(): # TODO: check why update_cycle_object_parent_state destroys object history # when accepting the only task in a cycle. The listener below is a # workaround because of that. Signals.status_change.send( obj.__class__, objs=[ Signals.StatusChangeSignalObjectContext( instance=obj, new_status=obj.status, old_status=inspect(obj).attrs.status.history.deleted[0], ) ] ) # Doing this regardless of status.history.has_changes() is important in order # to update objects that have been declined. It updates the os_last_updated # date and last_updated_by. if getattr(obj.task_group_task, 'object_approval', None): for tgobj in obj.task_group_task.task_group.objects: if obj.status == 'Verified': tgobj.modified_by = get_current_user() tgobj.set_reviewed_state() db.session.flush()
def update_cycle_task_child_state(obj): """Update child attributes state of cycle task Args: obj: Cycle task instance """ status_order = (None, 'Assigned', 'InProgress', 'Declined', 'Finished', 'Verified') status = obj.status children_attrs = _cycle_task_children_attr.get(type(obj), []) for children_attr in children_attrs: if children_attr: children = getattr(obj, children_attr, None) for child in children: if status == 'Declined' or \ status_order.index(status) > status_order.index(child.status): if is_allowed_update(child.__class__.__name__, child.id, child.context.id): old_status = child.status child.status = status Signals.status_change.send( child.__class__, objs=[ Signals.StatusChangeSignalObjectContext( instance=child, new_status=child.status, old_status=old_status, ) ] ) update_cycle_task_child_state(child)
def update_cycle_task_group_parent_state(objs): """Update cycle status for sent cycle task group""" objs = [obj for obj in objs or [] if obj.cycle.workflow.kind != "Backlog"] if not objs: return cycles_dict = {} cycle_statuses_dict = collections.defaultdict(set) group_ids = [] for obj in objs: cycle_statuses_dict[obj.cycle].add(obj.status) group_ids.append(obj.id) cycles_dict[obj.cycle.id] = obj.cycle # collect all groups that are in same cycles that group from sent list child_statuses = models.CycleTaskGroup.query.filter( models.CycleTaskGroup.cycle_id.in_([c.id for c in cycle_statuses_dict]), models.CycleTaskGroup.id.notin_(group_ids) ).distinct().with_for_update() for cycle_id, status in child_statuses.values("cycle_id", "status"): cycle_statuses_dict[cycles_dict[cycle_id]].add(status) updated_cycles = [] for cycle, group_statuses in cycle_statuses_dict.iteritems(): old_status = cycle.status _update_parent_state(cycle, group_statuses) if old_status != cycle.status: updated_cycles.append(Signals.StatusChangeSignalObjectContext( instance=cycle, old_status=old_status, new_status=cycle.status)) if updated_cycles: Signals.status_change.send(models.Cycle, objs=updated_cycles)
def update_cycle_task_object_task_parent_state(objs): """Update cycle task group status for sent cycle task""" objs = [o for o in objs or [] if o.cycle.workflow.kind != "Backlog"] if not objs: return groups_dict = {i.cycle_task_group_id: i.cycle_task_group for i in objs} group_status_dict = collections.defaultdict(set) # load all tasks that are in the same groups there are tasks that be updated task_ids = [t.id for t in db.session.deleted if isinstance(t, models.CycleTaskGroupObjectTask)] for task in itertools.chain(db.session.dirty, db.session.new): if not isinstance(task, models.CycleTaskGroupObjectTask): continue group_status_dict[task.cycle_task_group].add(task.status) if task.id: task_ids.append(task.id) query = models.CycleTaskGroupObjectTask.query.filter( models.CycleTaskGroupObjectTask.cycle_task_group_id.in_(groups_dict) ) if task_ids: query = query.filter(models.CycleTaskGroupObjectTask.id.notin_(task_ids)) query = query.distinct().with_for_update() for group_id, status in query.values("cycle_task_group_id", "status"): group_status_dict[groups_dict[group_id]].add(status) updated_groups = [] for group, task_statuses in group_status_dict.iteritems(): old_status = group.status _update_parent_state(group, task_statuses) if old_status != group.status: # if status updated then add it in list. require to update cycle state updated_groups.append(Signals.StatusChangeSignalObjectContext( instance=group, old_status=old_status, new_status=group.status)) if updated_groups: Signals.status_change.send(models.CycleTaskGroup, objs=updated_groups) update_cycle_task_group_parent_state([i.instance for i in updated_groups])
def handle_cycle_task_group_object_task_post( sender, obj=None, src=None, service=None): # noqa pylint: disable=unused-argument Signals.status_change.send( obj.__class__, objs=[ Signals.StatusChangeSignalObjectContext( instance=obj, new_status=obj.status, old_status=None, ) ] ) db.session.flush()
def handle_cycle_task_group_object_task_put( sender, obj=None, src=None, service=None): # noqa pylint: disable=unused-argument if inspect(obj).attrs.status.history.has_changes(): # TODO: check why update_cycle_object_parent_state destroys object history # when accepting the only task in a cycle. The listener below is a # workaround because of that. Signals.status_change.send( obj.__class__, objs=[ Signals.StatusChangeSignalObjectContext( instance=obj, new_status=obj.status, old_status=inspect(obj).attrs.status.history.deleted[0], ) ] )
def handle_cycle_task_group_object_task_post( sender, obj=None, src=None, service=None): # noqa pylint: disable=unused-argument if obj.cycle.workflow.kind != "Backlog": for person_id in obj.get_person_ids_for_rolename("Task Assignees"): ensure_assignee_is_workflow_member(obj.cycle.workflow, None, person_id) update_cycle_dates(obj.cycle) Signals.status_change.send( obj.__class__, objs=[ Signals.StatusChangeSignalObjectContext( instance=obj, new_status=obj.status, old_status=None, ) ] ) db.session.flush()