diff --git a/mgmt/decorators.py b/mgmt/decorators.py index 3e3851d..845d544 100644 --- a/mgmt/decorators.py +++ b/mgmt/decorators.py @@ -1,4 +1,5 @@ from django.http import HttpResponseForbidden +from rights import can #################### # User auth tests diff --git a/mgmt/forms.py b/mgmt/forms.py index 5ce9f8a..04c335e 100644 --- a/mgmt/forms.py +++ b/mgmt/forms.py @@ -1,5 +1,9 @@ -import django.newforms as forms #encoding: utf-8 +import django.newforms as forms +from django.contrib.auth.models import User +from django.conf import settings + +from models import Bug,Request,Project,Task ############ # Forms @@ -38,3 +42,10 @@ class MessageForm(forms.Form): name = forms.CharField() text = forms.CharField(widget=forms.Textarea()) +class TaskModelForm(forms.ModelForm): + bug = forms.ModelChoiceField(queryset=Bug.objects.all(),required=False) + request = forms.ModelChoiceField(queryset=Request.objects.all(),required=False) + class Meta: + model = Task + exclude = ("created","author","status","project") + diff --git a/mgmt/rights.py b/mgmt/rights.py index 774271e..8705bea 100644 --- a/mgmt/rights.py +++ b/mgmt/rights.py @@ -30,8 +30,12 @@ def can(user,action,object=None,target=None): return user in object.project.team.iterator() if cls == 'Request': return user in object.project.team.iterator() + if cls == 'Task': + return user.id == object.author.id or user.is_staff if action == 'document': return user in object.team.iterator() + if action == 'create task': + return user in object.admins.iterator() if cls == 'PrivateMsg': if action == 'delete': diff --git a/mgmt/templatetags/prj_filters.py b/mgmt/templatetags/prj_filters.py index 16ac137..082a8c9 100644 --- a/mgmt/templatetags/prj_filters.py +++ b/mgmt/templatetags/prj_filters.py @@ -4,10 +4,6 @@ import markdown as MD from django import template register = template.Library() -from os.path import dirname -import sys -sys.path.append(dirname(__file__)) - @register.filter('link') def link(obj,type='projects'): return "<a href='/%s/%s/'>%s</a>" % (type,obj.id,obj.name) @@ -16,6 +12,9 @@ def link(obj,type='projects'): def markdown(value): return MD.markdown(value,extensions=['codehilite'],safe_mode='escape') +@register.filter +def teaser(value): + return value[:50]+'...' class FormNode(template.Node): def __init__(self,obj,add=''): diff --git a/mgmt/utils.py b/mgmt/utils.py index 6a1cc7d..696dea6 100644 --- a/mgmt/utils.py +++ b/mgmt/utils.py @@ -2,7 +2,9 @@ from django.template import RequestContext from django.template.loader import get_template from django.http import HttpResponse from django.core.paginator import Paginator +from django.conf import settings +from context import add_blocks,debug_messages,add_menu from models import * ############# diff --git a/mgmt/views.py b/mgmt/views.py index ef1a556..2f386eb 100644 --- a/mgmt/views.py +++ b/mgmt/views.py @@ -13,7 +13,6 @@ from django.conf import settings import debug from models import * -from context import add_blocks,debug_messages,add_menu from rights import can,possible_changes from utils import * from forms import * @@ -327,18 +326,81 @@ def user_page(request,name): pr_team = Project.objects.filter(team=user) bugs_resp = Bug.objects.filter(responsible=user,status__id__lt=4) + tasks = user.task_set.select_related().all() + return render_it('user_page.html', {'user_view': user, 'private_messages': messages, 'form': form, 'projects_admin': pr_admin, 'projects_team': pr_team, + 'tasks': tasks, 'bugs_resp': bugs_resp}, request) def my_page(request): return user_page(request,request.user.username) +def project_tasks(request,pid): + project = Project.objects.get(pk=pid) + tasks = project.task_set.all() + can_task = can(request.user,'create task',project) + return render_it('project_tasks.html', + {'project': project, + 'can_task': can_task, + 'tasks': tasks}, + request) + +def one_task(request,tid): + task = Task.objects.select_related().get(pk=tid) + can_edit = can(request.user,'edit',task) + return render_it('task.html', + {'task': task, + 'can_edit': can_edit}, + request) + +@check_auth(Task,'edit') +def edit_task(request,task): + if request.method=='POST': + form = TaskModelForm(request.POST,instance=task) + if form.is_valid(): + task = form.save(commit=False) + task.save() + return HttpResponseRedirect(reverse('mgmt.views.one_task',args=(task.id,))) + else: + return render_it('edit_task.html', + {'form': form, + 'task': task}, + request) + else: + form = TaskModelForm(instance=task) + return render_it('edit_task.html', + {'form': form, + 'task': task}, + request) + +@check_auth(Project,'create task') +def create_task(request,project): + if request.method=='POST': + form = TaskModelForm(request.POST) + if form.is_valid(): + task = form.save(commit=False) + task.project = project + task.created = datetime.now() + task.author = request.user + task.status = 0 + task = task.save() + return HttpResponseRedirect(reverse('mgmt.views.project_tasks',args=(project.id,))) + else: + return render_it('create_task.html', + {'form': form}, + request) + else: + form = TaskModelForm() + return render_it('create_task.html', + {'form': form}, + request) + @login_required def private_message(request,mid): msg = PrivateMsg.objects.get(pk=mid) diff --git a/settings.py b/settings.py index abe25c2..a0b23e8 100644 --- a/settings.py +++ b/settings.py @@ -143,3 +143,7 @@ REQUEST_STATES = [(0,u'Не рассмотрен'), (2,u'Принят'), (3,u'В работе'), (4,u'Реализован')] + +TASK_STATES = [(0,u'Не прочитано'), + (1,u'Принято'), + (2,u'Выполнено')] diff --git a/templates/create_task.html b/templates/create_task.html new file mode 100644 index 0000000..cbeeae4 --- /dev/null +++ b/templates/create_task.html @@ -0,0 +1,10 @@ +{% extends "base.html" %} +{% load prj_filters %} + +{% block title %}Создать задание{% endblock %} + +{% block main %} +<h2>Создать задание</h2> + +{% form form %} +{% endblock %} diff --git a/templates/edit_task.html b/templates/edit_task.html new file mode 100644 index 0000000..f5e26b2 --- /dev/null +++ b/templates/edit_task.html @@ -0,0 +1,13 @@ +{% extends "base.html" %} +{% load prj_filters %} + +{% block title %}Редактировать задание{% endblock %} + +{% block main %} +<div class='links'> + <a href='{% url mgmt.views.one_task task.id %}'>Просмотреть</a> +</div> +<h2>Редактировать задание</h2> + +{% form form %} +{% endblock %} diff --git a/templates/project_body.html b/templates/project_body.html index c44b34b..883779a 100644 --- a/templates/project_body.html +++ b/templates/project_body.html @@ -12,5 +12,6 @@ <a href='{% url mgmt.views.project_documents project.id %}'>Документация</a> <a href='{% url mgmt.views.project_bugs project.id %}'>Баги</a> <a href='{% url mgmt.views.requests project.id %}'>Запросы функциональности</a> + <a href='{% url mgmt.views.project_tasks project.id %}'>Задания</a> </p> </div> diff --git a/templates/project_tasks.html b/templates/project_tasks.html new file mode 100644 index 0000000..0e31028 --- /dev/null +++ b/templates/project_tasks.html @@ -0,0 +1,23 @@ +{% extends "base.html" %} +{% load prj_filters %} + +{% block title %}Задания по проекту {{project.name}}{% endblock %} + +{% block main %} +<h2>Задания по проекту {{project.name}}</h2> + +{% if tasks %} + {% if can_task %} + <p><a href='{% url mgmt.views.create_task project.id %}'>Добавить задание</a></p> + {% endif %} + + {% include "tasks_table.html" %} +{% else %} + <p>Заданий по этому проекту нет.</p> +{% endif %} + +{% if can_task %} +<p><a href='{% url mgmt.views.create_task project.id %}'>Добавить задание</a></p> +{% endif %} + +{% endblock %} diff --git a/templates/task.html b/templates/task.html new file mode 100644 index 0000000..3dae315 --- /dev/null +++ b/templates/task.html @@ -0,0 +1,27 @@ +{% extends "base.html" %} +{% load prj_filters %} + +{% block title %}Задание: {{task.name}}{% endblock %} + +{% block main %} +{% if can_edit %} +<div class='links'> + <a href='{% url mgmt.views.edit_task task.id %}'>Изменить</a> +</div> +{% endif %} +<h2>Задание: {{task.name}}</h2> + +<p><strong>Автор:</strong> <a href='{% url mgmt.views.user_page task.author.username %}'>{{task.author.username}}</a></p> +<p><strong>Кому:</strong> <a href='{% url mgmt.views.user_page task.to.username %}'>{{task.to.username}}</a></p> + +{% if task.bug %} +<p><strong>Связанный баг:</strong> <a href='{% url mgmt.views.one_bug task.bug.id %}'>{{task.bug.name}}</a></p> +{% endif %} + +{% if task.request %} +<p><strong>Связанный запрос функциональности:</strong> <a href='{% url mgmt.views.one_request task.request.id %}'>{{task.request.name}}</a></p> +{% endif %} + +{{task.text|markdown|safe}} + +{% endblock %} diff --git a/templates/tasks_table.html b/templates/tasks_table.html new file mode 100644 index 0000000..bf864c5 --- /dev/null +++ b/templates/tasks_table.html @@ -0,0 +1,13 @@ +{% load prj_filters %} + <table> + {% for task in tasks %} + <tr> + <td><a href='{% url mgmt.views.one_project task.project.id %}'>{{task.project.name}}</a></td> + <td><a href='{% url mgmt.views.one_task task.id %}'>{{task.name}}</a></td> + <td><a href='{% url mgmt.views.user_page task.author.username %}'>{{task.author.username}}</a></td> + <td><a href='{% url mgmt.views.user_page task.to.username %}'>{{task.to.username}}</a></td> + <td>{{task.created}}</td> + <td>{{task.text|teaser|markdown|safe}}</td> + </tr> + {% endfor %} + </table> diff --git a/templates/user_page.html b/templates/user_page.html index 784ad4c..fb57045 100644 --- a/templates/user_page.html +++ b/templates/user_page.html @@ -40,6 +40,11 @@ </ul> {% endif %} +{% if tasks %} + <h3>Задания:</h3> + {% include "tasks_table.html" %} +{% endif %} + {% if bugs_resp %} <h3>Отвечает за баги:</h3> <div class='bugs'> diff --git a/urls.py b/urls.py index 3697a0c..99bdf3c 100644 --- a/urls.py +++ b/urls.py @@ -7,6 +7,7 @@ urlpatterns = patterns('', (r'^projects/(\d+)/bugs/$', "mgmt.views.project_bugs"), (r'^projects/(\d+)/docs/$', "mgmt.views.project_documents"), (r'^projects/(\d+)/requests/$', 'mgmt.views.requests'), + (r'^projects/(\d+)/tasks/$', 'mgmt.views.project_tasks'), (r'^docs/(\d+)/$', "mgmt.views.one_document"), (r'^docs/(\d+)/edit/$', "mgmt.views.edit_document"), (r'^docs/create/(\d+)/$', "mgmt.views.create_document"), @@ -19,6 +20,9 @@ urlpatterns = patterns('', (r'^requests/(\d+)/edit/$', 'mgmt.views.edit_request'), (r'^requests/create/(\d+)/$', 'mgmt.views.create_request'), (r'^users/(\w+)/$', 'mgmt.views.user_page'), + (r'^tasks/(\d+)/$', 'mgmt.views.one_task'), + (r'^tasks/(\d+)/edit/$', 'mgmt.views.edit_task'), + (r'^tasks/create/(\d+)/$', 'mgmt.views.create_task'), (r'^message/(\d+)/$', 'mgmt.views.private_message'), (r'^message/(\d+)/delete/$', 'mgmt.views.delete_private_message'), (r'^preview/$', 'mgmt.views.message_preview'),