diff --git a/media/css/main.css b/media/css/main.css index 8b1d639..be359a7 100644 --- a/media/css/main.css +++ b/media/css/main.css @@ -323,6 +323,20 @@ span.pager { background: #dfd; } +.report { + border: 1px #ddd solid; + padding: 1ex; + margin-bottom: 1em; +} + +.related-tasks { + border: 1px #888 solid; + text-align: right; + float: right; + background: white; + padding: 0.5ex; +} + .git-tags { border-left: 1px #888 solid; float: right; diff --git a/mgmt/forms.py b/mgmt/forms.py index ba7c1f3..231d27b 100644 --- a/mgmt/forms.py +++ b/mgmt/forms.py @@ -3,7 +3,7 @@ import django.newforms as forms from django.contrib.auth.models import User from django.conf import settings -from models import Bug,Request,Project,Task +from models import Bug,Request,Project,Task,Report ############ # Forms @@ -52,3 +52,8 @@ class TaskModelForm(forms.ModelForm): class TaskStateForm(forms.Form): state = forms.ChoiceField(settings.TASK_STATES) +class ReportModelForm(forms.ModelForm): + class Meta: + model = Report + exclude = ("created","author","task") + diff --git a/mgmt/rights.py b/mgmt/rights.py index 3161be8..723634a 100644 --- a/mgmt/rights.py +++ b/mgmt/rights.py @@ -32,6 +32,8 @@ def can(user,action,object=None,target=None): return user in object.project.team.iterator() if cls == 'Task': return user.id == object.author.id or user.is_staff + if cls == 'Report': + return user.id == object.author.id if action == 'document': return user in object.team.iterator() if action == 'create task': diff --git a/mgmt/views.py b/mgmt/views.py index 27da8ed..e7dd130 100644 --- a/mgmt/views.py +++ b/mgmt/views.py @@ -221,6 +221,7 @@ def one_bug(request,id): edit_link = None for comment in comments: comment.can_delete = can(request.user,'delete',comment) + tasks = bug.task_set.all() priority = dict(settings.PRIORITY_CHOICES).get(bug.priority,u'Unset') complexity = dict(settings.COMPLEXITY_CHOICES).get(bug.complexity,'Unknown') return render_it('bug.html', @@ -231,6 +232,7 @@ def one_bug(request,id): 'current_page': curr, 'page_numbers': pages, 'comments': comments, + 'tasks': tasks, 'priority': priority, 'complexity': complexity, 'priority_form': priority_form, @@ -327,11 +329,12 @@ def user_page(request,name): messages = None form = MessageForm() - pr_admin = Project.objects.filter(admins=user) - pr_team = Project.objects.filter(team=user) + pr_admin = user.admin_projects.all() + pr_team = user.in_projects.all() bugs_resp = Bug.objects.filter(responsible=user,status__id__lt=4) tasks = user.task_set.select_related().filter(status__lt=2) + reports = user.report_set.select_related().all() return render_it('user_page.html', {'user_view': user, @@ -340,12 +343,69 @@ def user_page(request,name): 'projects_admin': pr_admin, 'projects_team': pr_team, 'tasks': tasks, + 'reports': reports, 'bugs_resp': bugs_resp}, request) def my_page(request): return user_page(request,request.user.username) +def one_report(request,rid): + report = Report.objects.select_related().get(pk=rid) + can_edit = can(request.user,'edit',report) + return render_it('report.html', + {'report': report, + 'can_edit': can_edit}, + request) + +def task_reports(request,tid): + task = Task.objects.get(pk=tid) + reports = task.report_set.select_related().all() + return render_it('task_reports.html', + {'task': task, + 'reports': reports}, + request) + +@login_required +def create_report(request,tid): + if request.method=='POST': + form = ReportModelForm(request.POST) + if form.is_valid(): + report = form.save(commit=False) + report.created = datetime.now() + report.author = request.user + report.task = Task.objects.get(pk=tid) + report.save() + return HttpResponseRedirect(reverse('mgmt.views.one_task',args=(tid,))) + else: + return render_it('create_report.html', + {'form': form}, + request) + else: + form = ReportModelForm() + return render_it('create_report.html', + {'form': form}, + request) + +@check_auth(Report,'edit') +def edit_report(request,report): + if request.method=='POST': + form = ReportModelForm(request.POST,instance=report) + if form.is_valid(): + form.save() + return HttpResponseRedirect(reverse('mgmt.views.one_report',args=(report.id,))) + else: + return render_it('edit_report.html', + {'form': form, + 'report': report}, + request) + else: + form = ReportModelForm(instance=report) + return render_it('edit_report.html', + {'form': form, + 'report': report}, + request) + def project_tasks(request,pid): project = Project.objects.get(pk=pid) tasks = project.task_set.all() @@ -362,12 +422,16 @@ def one_task(request,tid): task.status = request.POST['state'] task.save() can_edit = can(request.user,'edit',task) + can_report = request.user.id == task.to.id + reports = task.report_set.all() if can(request.user,'change_state',task): state_form = TaskStateForm({'state': task.status}) else: state_form = None return render_it('task.html', {'task': task, + 'can_report': can_report, + 'reports': reports, 'state_form': state_form, 'can_edit': can_edit}, request) @@ -507,19 +571,43 @@ def edit_request(request,rq): def one_request(request,rid): rq = Request.objects.get(pk=rid) if request.method=='POST': - new_state = request.POST['state'] - rq.status = new_state - rq.save() + if request.POST['action']=='change_state': + new_state = request.POST['state'] + rq.status = new_state + rq.save() + else: + title = request.POST['title'] + text = request.POST['text'] + if not title: + title = text[:20]+'...' + c = Comment(created=datetime.now(), + author = request.user, + object_id = rid, + object_type = 'Request', + title = title, + text = text) + c.save() can_change_state = can(request.user,'change_state',rq) if can_change_state: state_form = RequestStateForm({'state': rq.status}) else: state_form = None can_edit = can(request.user,'edit',rq) + tasks = rq.task_set.all() + page,pages,comments = get_comments(request,rid,'Request') + if can(request.user,'comment'): + form = CommentForm() + else: + form = None return render_it('request.html', {'request': rq, + 'tasks': tasks, 'can_edit': can_edit, - 'state_form': state_form}, + 'state_form': state_form, + 'current_page': page, + 'page_numbers': pages, + 'comments': comments, + 'form': form}, request) def message_preview(request): diff --git a/templates/bug_body.html b/templates/bug_body.html index 24ae9ab..290e95c 100644 --- a/templates/bug_body.html +++ b/templates/bug_body.html @@ -18,4 +18,13 @@ <p><strong>Что ожидали:</strong> {{bug.expected|markdown|safe}}</p> <p><strong>Что получили:</strong> {{bug.unexpected|markdown|safe}}</p> <div>{{bug.text|markdown|safe}}</div> + {% if tasks %} + <div class='related-tasks'> + Связанные задания: + {% for task in tasks %} + <a href='{% url mgmt.views.one_task task.id %}'>{{task.name}}</a> + {% endfor %} + </div> + {% endif %} + </div> diff --git a/templates/create_report.html b/templates/create_report.html new file mode 100644 index 0000000..4565fd7 --- /dev/null +++ b/templates/create_report.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_report.html b/templates/edit_report.html new file mode 100644 index 0000000..8dcf1ea --- /dev/null +++ b/templates/edit_report.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_report report.id %}'>Просмотреть</a> +</div> +<h2>Редактировать отчет: {{report.name}}</h2> + +{% form form %} +{% endblock %} diff --git a/templates/report.html b/templates/report.html new file mode 100644 index 0000000..a11029c --- /dev/null +++ b/templates/report.html @@ -0,0 +1,20 @@ +{% extends "base.html" %} +{% load prj_filters %} + +{% block title %}Отчет: {{report.name}}{% endblock %} + +{% block main %} +{% if can_edit %} +<div class='links'> + <a href='{% url mgmt.views.edit_report report.id %}'>Изменить</a> +</div> +{% endif %} +<h2>Отчет: {{report.name}}</h2> + +<div class='report'> + <p><strong>Автор:</strong> <a href='{% url mgmt.views.user_page report.author.username %}'>{{report.author.username}}</a></p> + <p><strong>Задание:</strong> <a href='{% url mgmt.views.one_task report.task.id %}'>{{report.task.name}}</a></p> + + {{report.text|markdown|safe}} +</div> +{% endblock %} diff --git a/templates/request.html b/templates/request.html index 2c2452a..0f1b5cc 100644 --- a/templates/request.html +++ b/templates/request.html @@ -14,12 +14,23 @@ {% endif %} <h2>Запрос функциональности #{{request.id}}: {{request.name}}</h2> +{% if tasks %} + <div class='related-tasks'> + Связанные задания: + {% for task in tasks %} + <a href='{% url mgmt.views.one_task task.id %}'>{{task.name}}</a> + {% endfor %} + </div> +{% endif %} + <div class='request request-state-{{request.status}}'> {{request.text|markdown|safe}} </div> {% if state_form %} - {% form state_form %} + {% form state_form "<input type='hidden' name='action' value='change_state'/>"%} {% endif %} +{% include "comments.html" %} + {% endblock %} diff --git a/templates/task.html b/templates/task.html index 929e177..5ebe811 100644 --- a/templates/task.html +++ b/templates/task.html @@ -12,6 +12,7 @@ <h2>Задание: {{task.name}}</h2> <div class='task task-state-{{task.status}}'> + <p><strong>Проект:</strong> <a href='{% url mgmt.views.one_project task.project.id %}'>{{task.project.name}}</a></p> <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> @@ -29,5 +30,22 @@ {% if state_form %} {% form state_form %} {% endif %} + +{% if reports %} + {% if can_report %} + <p><a href='{% url mgmt.views.create_report task.id %}'>Создать отчет</a></p> + {% endif %} + <h3>Отчеты:</h3> + {% for report in reports %} + <div class='report'> + <h4><a href='{% url mgmt.views.one_report report.id %}'>{{report.name}}</a></h4> + {{report.text|markdown|safe}} + </div> + {% endfor %} +{% endif %} + +{% if can_report %} + <p><a href='{% url mgmt.views.create_report task.id %}'>Создать отчет</a></p> +{% endif %} {% endblock %} diff --git a/templates/user_page.html b/templates/user_page.html index fb57045..e2f7590 100644 --- a/templates/user_page.html +++ b/templates/user_page.html @@ -45,6 +45,19 @@ {% include "tasks_table.html" %} {% endif %} +{% if reports %} + <h3>Отчеты:</h3> + <table> + {% for report in reports %} + <tr> + <td><a href='{% url mgmt.views.one_task report.task.id%}'>{{report.task.name}}</a></td> + <td><a href='{% url mgmt.views.one_report report.id %}'>{{report.name}}</a></td> + <td><a href='{% url mgmt.views.edit_report report.id %}'>Изменить</a></td> + </tr> + {% endfor %} + </table> +{% endif %} + {% if bugs_resp %} <h3>Отвечает за баги:</h3> <div class='bugs'> diff --git a/urls.py b/urls.py index 99bdf3c..d03edc0 100644 --- a/urls.py +++ b/urls.py @@ -23,6 +23,9 @@ urlpatterns = patterns('', (r'^tasks/(\d+)/$', 'mgmt.views.one_task'), (r'^tasks/(\d+)/edit/$', 'mgmt.views.edit_task'), (r'^tasks/create/(\d+)/$', 'mgmt.views.create_task'), + (r'^reports/(\d+)/$', 'mgmt.views.one_report'), + (r'^reports/(\d+)/edit/$', 'mgmt.views.edit_report'), + (r'^reports/create/(\d+)/$', 'mgmt.views.create_report'), (r'^message/(\d+)/$', 'mgmt.views.private_message'), (r'^message/(\d+)/delete/$', 'mgmt.views.delete_private_message'), (r'^preview/$', 'mgmt.views.message_preview'),