Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[ITG-111] Przystosować backend do nowej mechaniki dodawania i edycji zadań #54

Merged
merged 6 commits into from
Jun 19, 2022
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
162 changes: 138 additions & 24 deletions bode/bode/models/task/actions.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,11 @@
from bode.models.enums import RelationType, TaskStatus
from bode.models.tag.actions import create_tag, get_tag_by_name
from bode.models.task.model import Task
from bode.models.task_relation.actions import delete_task_relation, get_related_tasks
from bode.models.task_relation.actions import (
create_task_relation,
delete_task_relation,
get_related_tasks,
)


def delete_task(task_id):
Expand All @@ -27,39 +31,101 @@ def is_subtask_relation(relation):


def edit_task(task_id, **task_data):
"""Function edits task. If task is checked, all interchangable tasks with status todo will be indirectly checked."""

def is_interchangable_relation(relation):
return relation.type == RelationType.Interchangable.value and str(relation.first_task_id) == task_id

def is_subtask_relation(relation):
return relation.type == RelationType.Subtask.value and str(relation.first_task_id) == task_id

"""Edit task data"""
task = get_task(task_id)

for key, value in task_data.items():
if key == "tags":
continue
edit_task_data = {key: task_data[key] for key in task_data.keys() & {"title", "description", "due_date", "status"}}
bkulawska marked this conversation as resolved.
Show resolved Hide resolved
for key, value in edit_task_data.items():
setattr(task, key, value)

db.session.commit()

if task_data["status"] != TaskStatus.TODO.value:
for relation, related_task in get_related_tasks(task_id):
if is_interchangable_relation(relation):
if related_task.status != TaskStatus.TODO.value:
continue
inter_task_data = {
"status": TaskStatus.INDIRECTLY_DONE.value,
"""If task is checked, check all interchangable tasks indirectly as well."""
new_status = {key: task_data[key] for key in task_data.keys() & {"status"}}
bkulawska marked this conversation as resolved.
Show resolved Hide resolved
if new_status:
if new_status["status"] != TaskStatus.TODO.value:
for relation, related_task in get_related_tasks(task_id):
if is_interchangable_relation(relation):
if related_task.status != TaskStatus.TODO.value:
continue
inter_task_data = {
"status": TaskStatus.INDIRECTLY_DONE.value,
}
edit_task(str(related_task.id), **inter_task_data)
if is_subtask_relation(relation):
if related_task.status == TaskStatus.DONE.value:
continue
subtask_data = {
"status": TaskStatus.DONE.value,
}
edit_task(str(related_task.id), **subtask_data)

"""Delete tags"""
tags_to_delete_data = {key: task_data[key] for key in task_data.keys() & {"tags_to_delete"}}
if tags_to_delete_data:
for tag_name in tags_to_delete_data["tags_to_delete"]:
tag = get_tag_by_name(tag_name)
if tag not in task.tags:
raise NoResultFound
task.tags.remove(tag)
db.session.commit()

"""Add tags"""
tags_to_add_data = {key: task_data[key] for key in task_data.keys() & {"tags_to_add"}}
if tags_to_add_data:
for tag_name in tags_to_add_data["tags_to_add"]:
tag = get_tag_by_name(tag_name)
if tag is None:
tag = create_tag(tag_name)
if tag in task.tags:
raise IntegrityError
task.tags.append(tag)
db.session.commit()

"""Delete relations"""
relations_to_delete_data = {key: task_data[key] for key in task_data.keys() & {"relations_to_delete"}}
if relations_to_delete_data:
for relation_id in relations_to_delete_data["relations_to_delete"]:
delete_task_relation(relation_id)

"""Create relations"""
relations_to_add_data = {key: task_data[key] for key in task_data.keys() & {"relations_to_add"}}
if relations_to_add_data:
for relation_data in relations_to_add_data["relations_to_add"]:
if relation_data["type"] == "blocks":
relation_input = {
"first_task_id": relation_data["task_id"],
"second_task_id": task.id,
"type": "DEPENDENT",
}
bkulawska marked this conversation as resolved.
Show resolved Hide resolved
edit_task(str(related_task.id), **inter_task_data)
if is_subtask_relation(relation):
if related_task.status == TaskStatus.DONE.value:
continue
subtask_data = {
"status": TaskStatus.DONE.value,
if relation_data["type"] == "is_blocked_by":
relation_input = {
"first_task_id": task.id,
"second_task_id": relation_data["task_id"],
"type": "DEPENDENT",
}
edit_task(str(related_task.id), **subtask_data)
if relation_data["type"] == "interchangable":
relation_input = {
"first_task_id": task.id,
"second_task_id": relation_data["task_id"],
"type": "INTERCHANGABLE",
}
create_task_relation(**relation_input)

"""Create subtasks"""
subtasks_to_add_data = {key: task_data[key] for key in task_data.keys() & {"subtasks_to_add"}}
if subtasks_to_add_data:
for subtask_title in subtasks_to_add_data["subtasks_to_add"]:
subtask_input = {"title": subtask_title}
subtask = Task(**subtask_input)
db.session.add(subtask)
db.session.commit()
subtask_relation_input = {"first_task_id": task.id, "second_task_id": subtask.id, "type": "SUBTASK"}
create_task_relation(**subtask_relation_input)

return task

Expand All @@ -69,11 +135,59 @@ def get_task(task_id):


def create_task(**task_data):
task = Task(**task_data)

"""Create task"""
create_task_data = {
key: task_data[key] for key in task_data.keys() & {"title", "description", "due_date", "status"}
}
task = Task(**create_task_data)
db.session.add(task)
db.session.commit()

"""Add specified tags to task"""
tags_data = {key: task_data[key] for key in task_data.keys() & {"tags"}}
if tags_data:
for tag_name in tags_data["tags"]:
tag = get_tag_by_name(tag_name)
if tag is None:
tag = create_tag(tag_name)
task.tags.append(tag)
db.session.commit()

"""Create specified relations"""
relations_data = {key: task_data[key] for key in task_data.keys() & {"relations"}}
if relations_data:
for relation_data in relations_data["relations"]:
if relation_data["type"] == "blocks":
relation_input = {
"first_task_id": relation_data["task_id"],
"second_task_id": task.id,
"type": "DEPENDENT",
}
if relation_data["type"] == "is_blocked_by":
relation_input = {
"first_task_id": task.id,
"second_task_id": relation_data["task_id"],
"type": "DEPENDENT",
}
if relation_data["type"] == "interchangable":
relation_input = {
"first_task_id": task.id,
"second_task_id": relation_data["task_id"],
"type": "INTERCHANGABLE",
}
create_task_relation(**relation_input)

"""Create specified subtasks"""
subtasks_data = {key: task_data[key] for key in task_data.keys() & {"subtasks"}}
if subtasks_data:
for subtask_title in subtasks_data["subtasks"]:
subtask_input = {"title": subtask_title}
subtask = Task(**subtask_input)
db.session.add(subtask)
db.session.commit()
subtask_relation_input = {"first_task_id": task.id, "second_task_id": subtask.id, "type": "SUBTASK"}
create_task_relation(**subtask_relation_input)
bkulawska marked this conversation as resolved.
Show resolved Hide resolved

return task


Expand Down
9 changes: 7 additions & 2 deletions bode/bode/resources/tasks/api.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,12 @@
)
from bode.models.task.model import Task
from bode.resources.tags.schemas import TagInputSchema
from bode.resources.tasks.schemas import TaskFiltersSchema, TaskInputSchema, TaskSchema
from bode.resources.tasks.schemas import (
TaskEditionInputSchema,
TaskFiltersSchema,
TaskInputSchema,
TaskSchema,
)

blueprint = Blueprint("tasks", "tasks", url_prefix="/tasks")

Expand Down Expand Up @@ -60,7 +65,7 @@ def get(self, task_id):
except DataError:
abort(404)

@blueprint.arguments(TaskInputSchema)
@blueprint.arguments(TaskEditionInputSchema)
@blueprint.response(200, TaskSchema)
def put(self, task_data, task_id):
try:
Expand Down
26 changes: 24 additions & 2 deletions bode/bode/resources/tasks/schemas.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,12 @@
from bode.models.enums import DirectedRelationType, TaskStatus
from bode.models.task_relation.actions import is_task_blocked
from bode.resources.base_schema import BaseSchema
from bode.resources.tags.schemas import TagInputSchema, TagSchema
from bode.resources.tags.schemas import TagSchema


class RelationInputSchema(BaseSchema):
task_id = fields.UUID(required=True)
type = fields.String(validate=validate.OneOf(DirectedRelationType.list()), required=True)
bkulawska marked this conversation as resolved.
Show resolved Hide resolved


def validate_rrule(rrule_str: str):
Expand All @@ -18,12 +23,29 @@ class TaskInputSchema(BaseSchema):
class Meta:
unknown = EXCLUDE

title = fields.String(validate=validate.Length(1, 80), required=True)
description = fields.String(validate=validate.Length(0, 1024), default="")
due_date = fields.DateTime(allow_none=True)
rrule = fields.String(allow_none=True, required=False, validate=validate_rrule)
status = fields.String(validate=validate.OneOf(TaskStatus.list()), default=TaskStatus.TODO.value)
tags = fields.List(fields.Nested(TagInputSchema), default=[])
tags = fields.List(fields.String, default=[])
relations = fields.List(fields.Nested(RelationInputSchema), default=[])
subtasks = fields.List(fields.String, default=[])


class TaskEditionInputSchema(BaseSchema):
class Meta:
unknown = EXCLUDE

title = fields.String(validate=validate.Length(1, 80), required=True)
description = fields.String(validate=validate.Length(0, 1024), default="")
due_date = fields.DateTime(allow_none=True)
status = fields.String(validate=validate.OneOf(TaskStatus.list()), default=TaskStatus.TODO.value)
tags_to_add = fields.List(fields.String, default=[])
tags_to_delete = fields.List(fields.String, default=[])
relations_to_add = fields.List(fields.Nested(RelationInputSchema), default=[])
relations_to_delete = fields.List(fields.String, default=[])
subtasks_to_add = fields.List(fields.String, default=[])


class TaskSchema(BaseSchema):
Expand Down