remotes/origin/PR-39
ArturBaybulatov 10 years ago
parent 1f8713db24
commit 55f13883ba
  1. 24
      projects/migrations/0014_auto_20160823_1912.py
  2. 2
      projects/models.py
  3. 633
      projects/templates/project_detail.html
  4. 26
      projects/templatetags/project_tags.py
  5. 8
      projects/urls.py
  6. 42
      projects/views.py

@ -0,0 +1,24 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.9.7 on 2016-08-23 16:12
from __future__ import unicode_literals
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('projects', '0013_auto_20160819_1735'),
]
operations = [
migrations.AlterModelOptions(
name='project',
options={'ordering': ('-created',), 'verbose_name': 'Проект', 'verbose_name_plural': 'Проекты'},
),
migrations.AddField(
model_name='answer',
name='rejected',
field=models.BooleanField(default=False),
),
]

@ -89,7 +89,6 @@ class Project(models.Model, HitCountMixin):
name = models.CharField(max_length=255) name = models.CharField(max_length=255)
price_and_term_required = models.BooleanField(default=False) price_and_term_required = models.BooleanField(default=False)
realty = models.ForeignKey(Realty, blank=True, null=True, related_name='projects') realty = models.ForeignKey(Realty, blank=True, null=True, related_name='projects')
rejected_answers_count = models.PositiveIntegerField(default=0)
specialization = TreeForeignKey(Specialization, related_name='projects') specialization = TreeForeignKey(Specialization, related_name='projects')
state = models.CharField(default='active', max_length=20, choices=STATES) state = models.CharField(default='active', max_length=20, choices=STATES)
term = models.IntegerField(default=0) term = models.IntegerField(default=0)
@ -134,6 +133,7 @@ class Answer(models.Model):
term = models.IntegerField(blank=True, null=True) term = models.IntegerField(blank=True, null=True)
term_type = models.CharField(max_length=10, choices=TERMS, blank=True, null=True) term_type = models.CharField(max_length=10, choices=TERMS, blank=True, null=True)
is_archive = models.BooleanField(default=False) is_archive = models.BooleanField(default=False)
rejected = models.BooleanField(default=False)
content_type = models.ForeignKey(ContentType, limit_choices_to=Q(app_label='users', model='user') | Q(app_label='users', model='team')) content_type = models.ForeignKey(ContentType, limit_choices_to=Q(app_label='users', model='user') | Q(app_label='users', model='team'))
object_id = models.IntegerField() object_id = models.IntegerField()

@ -3,27 +3,28 @@
{% load humanize %} {% load humanize %}
{% load thumbnail %} {% load thumbnail %}
{% load specializtions_tags %} {% load specializtions_tags %}
{% load project_tags %}
{% block content %} {% block content %}
{% include 'partials/header.html' %} {% include 'partials/header.html' %}
<div class="container mainScore"> <div class="container mainScore">
<div class="row"> <div class="row">
<div class="col-lg-12"> <div class="col-lg-12">
<p class="titleScore">{{ project.name }}</p> <p class="titleScore">{{ project.name }}</p>
</div> </div>
<div class="doneBlock new-done disTab"> <div class="doneBlock new-done disTab">
<div class="triangle1"></div> <div class="triangle1"></div>
{% if request.user.is_contractor %} {% if request.user.is_contractor %}
<div class="col-lg-12 new-p"> <div class="col-lg-12 new-p">
<p>{{ project.budget|intcomma }} <i class="fa fa-rub"></i></p> <p>{{ project.budget|intcomma }} <i class="fa fa-rub"></i></p>
</div> </div>
{% endif %} {% endif %}
<div class="col-lg-4"> <div class="col-lg-4">
<a href="#" class="aLinkExe"> <a href="#" class="aLinkExe">
<div class="imgExecutor"> <div class="imgExecutor">
{% if project.customer.avatar %} {% if project.customer.avatar %}
<img src="{{ project.customer.avatar.url }}" alt="execitor-image"> <img src="{{ project.customer.avatar.url }}" alt="execitor-image">
@ -31,13 +32,13 @@
<img src="{% static 'img/profile.jpg' %}" alt="execitor-image"> <img src="{% static 'img/profile.jpg' %}" alt="execitor-image">
{% endif %} {% endif %}
</div> </div>
</a> </a>
<p class="nameExecutor"> <p class="nameExecutor">
<a href="{% url 'users:customer-profile-open-projects' project.customer.pk %}">{{ project.customer.get_full_name }} [{{ project.customer.username }}]</a> <a href="{% url 'users:customer-profile-open-projects' project.customer.pk %}">{{ project.customer.get_full_name }} [{{ project.customer.username }}]</a>
</p> </p>
<p class="navv2">На сайте {{ project.created|naturaltime }}</p> <p class="navv2">На сайте {{ project.created|naturaltime }}</p>
{% if not request.user.is_contractor %} {% if not request.user.is_contractor %}
<ul class="rettList restList3"> <ul class="rettList restList3">
<li> <li>
<a href="javascript:void(0)">Отзывы: <a href="javascript:void(0)">Отзывы:
@ -48,9 +49,9 @@
</li> </li>
</ul> </ul>
{% endif %} {% endif %}
</div> </div>
{% if request.user.is_contractor %} {% if request.user.is_contractor %}
<div class="col-lg-3 retts"> <div class="col-lg-3 retts">
<ul class="rettList restList2"> <ul class="rettList restList2">
<li>Рейтинг: <span> 0</span></li> <li>Рейтинг: <span> 0</span></li>
@ -66,24 +67,15 @@
</div> </div>
{% endif %} {% endif %}
<div class="col-lg-2 new-dashed"> <div class="col-lg-3 retts new-list">
{% specialization_widget contractor.pk %} <ul class="desListPro">
{# <div class="dashedCol4 dashedCol44 dashedColColor">#} <li>
{# <p class="specUser">#} {{ project.created }}
{# Специализации:#} </li>
{# </p>#} <li>
{# </div>#} {{ project.get_work_type_display }}
</div> </li>
</ul>
<div class="col-lg-3 retts new-list">
<ul class="desListPro">
<li>
{{ project.created }}
</li>
<li>
{{ project.get_work_type_display }}
</li>
</ul>
{% if project.cro %} {% if project.cro %}
<div class="sroUser sroExecutor sroPro"> <div class="sroUser sroExecutor sroPro">
@ -91,30 +83,30 @@
<p>Есть допуск СРО</p> <p>Есть допуск СРО</p>
</div> </div>
{% endif %} {% endif %}
</div> </div>
</div> </div>
<div class="infoProjectBlock info-new disTab"> <div class="infoProjectBlock info-new disTab">
<div class="triangle2"></div> <div class="triangle2"></div>
{% if project.realty %} {% if project.realty %}
<div class="col-lg-10 col-lg-offset-1"> <div class="col-lg-10 col-lg-offset-1">
<ul class="listProjectIn"> <ul class="listProjectIn">
<li><span>Местоположение:</span> {{ project.realty.location.name }}</li> <li><span>Местоположение:</span> {{ project.realty.location.name }}</li>
<li><span>Классификация здания:</span> {{ project.realty.building_classification.name }}</li> <li><span>Классификация здания:</span> {{ project.realty.building_classification.name }}</li>
<li><span>Вид строительства:</span> {{ project.realty.type_construction.name }}</li> <li><span>Вид строительства:</span> {{ project.realty.construction_type.name }}</li>
</ul> </ul>
</div> </div>
{% endif %} {% endif %}
<div class="col-lg-10 col-lg-offset-1"> <div class="col-lg-10 col-lg-offset-1">
<p class="textProIn"> <p class="textProIn">
{{ project.text }} {{ project.text }}
</p> </p>
</div> </div>
<div class="col-lg-10 col-lg-offset-1"> <div class="col-lg-10 col-lg-offset-1">
{% if request.user.is_contractor and not answer %} {% if request.user.is_contractor and not answer %}
<a href="#" onclick="$('.-project-answer-form').toggle('slow'); return false" class="new-answer"> <a href="#" onclick="$('.-project-answer-form').toggle('slow'); return false" class="new-answer">
Ответить на проект Ответить на проект
</a> </a>
@ -150,8 +142,22 @@
</a> </a>
</form> </form>
{% endif %} {% endif %}
</div> </div>
</div> </div>
@ -163,13 +169,13 @@
{% if request.user.is_contractor %}
{% if request.user.is_contractor %}
{% if answer %} {% if answer %}
<div class="candidateBlock disTab"> <div class="candidateBlock disTab">
<div class="candidate can-new"> <div class="candidate can-new">
@ -289,7 +295,7 @@
</span> </span>
<p class="textComm44"> <p class="textComm44">
{{ message.text }} {{ message.text|linebreaksbr }}
</p> </p>
</div> </div>
</div> </div>
@ -448,34 +454,49 @@
{% elif request.user.is_customer and project in request.user.projects.all %}
{% elif request.user.is_customer and project in request.user.projects.all %}
<div class="exBigBlock disTab"> <div class="exBigBlock disTab">
<div class="col-lg-12"> <div class="col-lg-12">
<p class="titleEx">Исполнители</p> <p class="titleEx">Исполнители</p>
</div> </div>
<div class="col-lg-12 exButton"> <div class="col-lg-12 exButton">
<div class="btn-group" role="group" aria-label="..."> <div class="btn-group" role="group">
<button type="button" class="btn btn-default"> <a href="#new-answers" data-toggle="tab" class="btn btn-default">
Новые <span>{{ project.answers.count|sub:project.candidates.count }}</span> Новые <span>{{ project|get_new_answers|length }}</span>
</button> </a>
<button type="button" class="btn btn-default"> <a href="#candidate-answers" data-toggle="tab" class="btn btn-default">
Кандидаты <span>{{ project.candidates.count }}</span> Кандидаты <span>{{ project|get_candidate_answers|length }}</span>
</button> </a>
<button type="button" class="btn btn-default"> <a href="#rejected-answers" data-toggle="tab" class="btn btn-default">
Отказал <span>{{ project.rejected_answers_count }}</span> Отказал <span>{{ project|get_rejected_answers|length }}</span>
</button> </a>
</div> </div>
</div> </div>
</div> </div>
{% if project.answers.exists %} {% if project.answers.exists %}
{% if project.candidates.count > 1 %} {% if project.candidates.count > 1 %}
<div class="col-lg-12 compareBlock"> <div class="col-lg-12 compareBlock">
@ -485,163 +506,425 @@
</div> </div>
{% endif %} {% endif %}
<div class="col-lg-12 exNew"> <div class="tab-content">
<p>Новые исполнители</p> <div id="new-answers" class="tab-pane fade in active">
</div> <div class="col-lg-12 exNew">
<p>Новые исполнители</p>
</div>
{% for answer in project.answers.all %} {% for answer in project|get_new_answers %}
<div class="candidateBlock disTab"> <div class="candidateBlock disTab">
<div class="candidate"> <div class="candidate">
<div class="col-lg-4"> <div class="col-lg-4">
<a href="#" class="aLinkExe"> <a href="#" class="aLinkExe">
<div class="imgExecutor"> <div class="imgExecutor">
{% if answer.author.avatar %} {% if answer.author.avatar %}
<img src="{{ answer.author.avatar.url }}" alt="execitor-image"> <img src="{{ answer.author.avatar.url }}" alt="execitor-image">
{% else %} {% else %}
<img src="{% static 'img/profile.jpg' %}" alt="execitor-image"> <img src="{% static 'img/profile.jpg' %}" alt="execitor-image">
{% endif %}
</div>
</a>
<p class="nameExecutor">
{% if answer.author|class_name == 'User' %}
<a href="#">{{ answer.author.get_full_name }} [{{ answer.author.username }}]</a>
{% elif answer.author|class_name == 'Team' %}
<a href="#">{{ answer.author.name }}</a>
{% endif %}
</p>
<p class="navv2">На сайте {{ answer.author.created }}</p>
{% if answer.author|class_name == 'User' %}
{% if answer.author.contractor_status == 'free' %}
<div class="statusUser">Свободен</div><!-- ............. -->
{% endif %}
{% endif %} {% endif %}
</div> </div>
</a>
<p class="nameExecutor"> <div class="col-lg-3 retts">
{% if answer.author|class_name == 'User' %} {% ratings_widget answer.author.pk 'restList2' %}
<a href="#">{{ answer.author.get_full_name }} [{{ answer.author.username }}]</a>
{% elif answer.author|class_name == 'Team' %}
<a href="#">{{ answer.author.name }}</a>
{% endif %}
</p>
<p class="navv2">На сайте {{ answer.author.created }}</p> {% if answer.author|class_name == 'User' and answer.author.cro %}
<div class="sroUser sroExecutor">
<div class="iconSRO"></div>
<p>Есть допуск СРО</p>
</div>
{% elif answer.author|class_name == 'Team' %}
<!-- TODO -->
{% if answer.author|class_name == 'User' %} <div class="sroUser sroExecutor">
{% if answer.author.contractor_status == 'free' %} <div class="iconSRO"></div>
<div class="statusUser">Свободен</div><!-- ............. --> <p>Есть допуск СРО</p>
{% endif %} </div>
{% endif %} {% endif %}
</div> </div>
<div class="col-lg-3 retts"> <div class="col-lg-2 listCens">
{% ratings_widget answer.author.pk 'restList2' %} <p>
Цена:
<span>{{ answer.budget|intcomma }}</span>
<i class="fa fa-rub"></i>
</p>
<p>
Срок: <span>{{ answer.term }} {{ answer.get_currency_display }} {{ answer.get_term_type_display|decap }}</span>
</p>
<p>Опубликован: {{ answer.created|date:'M d, Y' }}</p>
</div>
{% if answer.author|class_name == 'User' and answer.author.cro %} <div class="col-lg-3 retts">
<div class="sroUser sroExecutor"> {% if answer.author not in project|get_candidates %}
<div class="iconSRO"></div> <a href="{% url 'projects:add-candidate' answer_id=answer.pk project_id=project.pk %}" class="candLink candLink1">
<p>Есть допуск СРО</p> Кандидат
</a>
{% endif %}
<a href="{% url 'chat:chat-user' %}" class="candLink candLink2">
предложить проект
</a>
<form action="{% url 'projects:reject-project-answer' pk=answer.pk %}" method="POST" novalidate>
{% csrf_token %}
<input type="hidden" name="next" value="{{ request.path }}">
<a href="#" onclick="$(this).closest('form').submit(); return false" class="candLink candLink3">отказ</a>
</form>
</div> </div>
{% elif answer.author|class_name == 'Team' %}
<!-- TODO -->
<div class="sroUser sroExecutor"> <div class="gallMini disTab">
<div class="iconSRO"></div> {% for portf in answer.portfolios.all %}
<p>Есть допуск СРО</p> <div class="col-lg-3">
<div class="insetCol box-sizing disTab">
<div class="imgGal" style="background: url('{{ portf.photos.first.img.url }}') no-repeat center">
<div class="imgFigure"></div>
</div>
</div>
</div>
{% endfor %}
</div> </div>
{% endif %}
</div>
<div class="col-lg-2 listCens"> <div class="commBlock44 disTab">
<p> {% for message in answer.messages.all %}
Цена: <div class="comm44 disTab">
<span>{{ answer.budget|intcomma }}</span> <div class="col-lg-10 col-lg-offset-1">
<i class="fa fa-rub"></i> {% if message.is_sender_customer %}
</p> <p class="nameComm nameCommAct">
<p> {{ project.customer.get_full_name }}
Срок: <span>{{ answer.term }} {{ answer.get_currency_display }} {{ answer.get_term_type_display|decap }}</span> </p>
</p> {% else %}
<p>Опубликован: {{ answer.created|date:'M d, Y' }}</p> <p class="nameComm">
</div> {% if answer.author|class_name == 'User' %}
{{ answer.author.get_full_name }}
{% elif answer.author|class_name == 'Team' %}
{{ answer.author.name }}
{% endif %}
</p>
{% endif %}
<div class="col-lg-3 retts"> <span class="dateComm44">
<a href="{% url 'projects:add-candidate' answer_id=answer.pk project_id=project.pk %}" class="candLink candLink1"> {{ message.created }}
Кандидат </span>
</a>
<a href="{% url 'chat:chat-user' %}" class="candLink candLink2"> <p class="textComm44">
предложить проект {{ message.text|linebreaksbr }}
</a> </p>
</div>
</div>
{% endfor %}
<div class="comm44 disTab">
<!--
<div class="i col-lg-10 col-lg-offset-1">
<a href="#" onclick="return false" class="answerComm">
Ответить
</a>
</div>
-->
<form action="{% url 'projects:customer-reject-project-answer' pk=answer.pk %}" method="POST" novalidate> <div class="col-lg-10 col-lg-offset-1">
{% csrf_token %} <form action="{% url 'projects:create-answer-message' pk=answer.pk %}" method="POST" novalidate>
<input type="hidden" name="next" value="{{ request.path }}"> {% csrf_token %}
<a href="#" onclick="$(this).closest('form').submit(); return false" class="candLink candLink3">отказ</a> <input type="hidden" name="next" value="{% url 'projects:detail' pk=project.pk %}">
</form>
</div>
<div class="gallMini disTab"> <div><textarea name="text"></textarea></div>
{% for portf in answer.portfolios.all %} <div><button type="submit">Отправить</button></div>
<div class="col-lg-3"> </form>
<div class="insetCol box-sizing disTab">
<div class="imgGal" style="background: url('{{ portf.photos.first.img.url }}') no-repeat center">
<div class="imgFigure"></div>
</div> </div>
</div> </div>
</div> </div>
{% endfor %} </div>
</div> </div>
{% endfor %}
</div>
<div class="commBlock44 disTab">
{% for message in answer.messages.all %}
<div class="comm44 disTab">
<div class="col-lg-10 col-lg-offset-1">
{% if message.is_sender_customer %} <div id="candidate-answers" class="tab-pane fade">
<p class="nameComm nameCommAct"> <div class="col-lg-12 exNew">
{{ project.customer.get_full_name }} <p>Кандидаты</p>
</p> </div>
{% else %}
<p class="nameComm"> {% for answer in project|get_candidate_answers %}
{% if answer.author|class_name == 'User' %} <div class="candidateBlock disTab">
{{ answer.author.get_full_name }} <div class="candidate">
{% elif answer.author|class_name == 'Team' %} <div class="col-lg-4">
{{ answer.author.name }} <a href="#" class="aLinkExe">
{% endif %} <div class="imgExecutor">
</p> {% if answer.author.avatar %}
<img src="{{ answer.author.avatar.url }}" alt="execitor-image">
{% else %}
<img src="{% static 'img/profile.jpg' %}" alt="execitor-image">
{% endif %}
</div>
</a>
<p class="nameExecutor">
{% if answer.author|class_name == 'User' %}
<a href="#">{{ answer.author.get_full_name }} [{{ answer.author.username }}]</a>
{% elif answer.author|class_name == 'Team' %}
<a href="#">{{ answer.author.name }}</a>
{% endif %} {% endif %}
</p>
<span class="dateComm44"> <p class="navv2">На сайте {{ answer.author.created }}</p>
{{ message.created }}
</span>
<p class="textComm44"> {% if answer.author|class_name == 'User' %}
{{ message.text }} {% if answer.author.contractor_status == 'free' %}
</p> <div class="statusUser">Свободен</div><!-- ............. -->
</div> {% endif %}
{% endif %}
</div> </div>
{% endfor %}
<div class="comm44 disTab"> <div class="col-lg-3 retts">
{# <div class="i col-lg-10 col-lg-offset-1">#} {% ratings_widget answer.author.pk 'restList2' %}
{# <a href="#" onclick="return false" class="answerComm">#}
{# Ответить#}
{# </a>#}
{# </div>#}
<div class="col-lg-10 col-lg-offset-1"> {% if answer.author|class_name == 'User' and answer.author.cro %}
<form action="{% url 'projects:create-answer-message' pk=answer.pk %}" method="POST" novalidate> <div class="sroUser sroExecutor">
{% csrf_token %} <div class="iconSRO"></div>
<input type="hidden" name="next" value="{% url 'projects:detail' pk=project.pk %}"> <p>Есть допуск СРО</p>
</div>
{% elif answer.author|class_name == 'Team' %}
<!-- TODO -->
<div class="sroUser sroExecutor">
<div class="iconSRO"></div>
<p>Есть допуск СРО</p>
</div>
{% endif %}
</div>
<div class="col-lg-2 listCens">
<p>
Цена:
<span>{{ answer.budget|intcomma }}</span>
<i class="fa fa-rub"></i>
</p>
<p>
Срок: <span>{{ answer.term }} {{ answer.get_currency_display }} {{ answer.get_term_type_display|decap }}</span>
</p>
<p>Опубликован: {{ answer.created|date:'M d, Y' }}</p>
</div>
<div class="col-lg-3 retts">
<a href="{% url 'chat:chat-user' %}" class="candLink candLink2">
предложить проект
</a>
<div><textarea name="text"></textarea></div> <form action="{% url 'projects:reject-project-answer' pk=answer.pk %}" method="POST" novalidate>
<div><button type="submit">Отправить</button></div> {% csrf_token %}
<input type="hidden" name="next" value="{{ request.path }}">
<a href="#" onclick="$(this).closest('form').submit(); return false" class="candLink candLink3">отказ</a>
</form> </form>
</div> </div>
<div class="gallMini disTab">
{% for portf in answer.portfolios.all %}
<div class="col-lg-3">
<div class="insetCol box-sizing disTab">
<div class="imgGal" style="background: url('{{ portf.photos.first.img.url }}') no-repeat center">
<div class="imgFigure"></div>
</div>
</div>
</div>
{% endfor %}
</div>
<div class="commBlock44 disTab">
{% for message in answer.messages.all %}
<div class="comm44 disTab">
<div class="col-lg-10 col-lg-offset-1">
{% if message.is_sender_customer %}
<p class="nameComm nameCommAct">
{{ project.customer.get_full_name }}
</p>
{% else %}
<p class="nameComm">
{% if answer.author|class_name == 'User' %}
{{ answer.author.get_full_name }}
{% elif answer.author|class_name == 'Team' %}
{{ answer.author.name }}
{% endif %}
</p>
{% endif %}
<span class="dateComm44">
{{ message.created }}
</span>
<p class="textComm44">
{{ message.text|linebreaksbr }}
</p>
</div>
</div>
{% endfor %}
<div class="comm44 disTab">
<!--
<div class="i col-lg-10 col-lg-offset-1">
<a href="#" onclick="return false" class="answerComm">
Ответить
</a>
</div>
-->
<div class="col-lg-10 col-lg-offset-1">
<form action="{% url 'projects:create-answer-message' pk=answer.pk %}" method="POST" novalidate>
{% csrf_token %}
<input type="hidden" name="next" value="{% url 'projects:detail' pk=project.pk %}">
<div><textarea name="text"></textarea></div>
<div><button type="submit">Отправить</button></div>
</form>
</div>
</div>
</div>
</div> </div>
</div> </div>
</div> {% endfor %}
</div> </div>
{% endfor %}
{% endif %}
<div id="rejected-answers" class="tab-pane fade">
<div class="col-lg-12 exNew">
<p>Отказал</p>
</div>
{% for answer in project|get_rejected_answers %}
<div class="candidateBlock disTab">
<div class="candidate">
<div class="col-lg-4">
<a href="#" class="aLinkExe">
<div class="imgExecutor">
{% if answer.author.avatar %}
<img src="{{ answer.author.avatar.url }}" alt="execitor-image">
{% else %}
<img src="{% static 'img/profile.jpg' %}" alt="execitor-image">
{% endif %}
</div>
</a>
<p class="nameExecutor">
{% if answer.author|class_name == 'User' %}
<a href="#">{{ answer.author.get_full_name }} [{{ answer.author.username }}]</a>
{% elif answer.author|class_name == 'Team' %}
<a href="#">{{ answer.author.name }}</a>
{% endif %}
</p>
{% endif %} <p class="navv2">На сайте {{ answer.author.created }}</p>
{% if answer.author|class_name == 'User' %}
{% if answer.author.contractor_status == 'free' %}
<div class="statusUser">Свободен</div><!-- ............. -->
{% endif %}
{% endif %}
</div>
<div class="col-lg-3 retts">
{% ratings_widget answer.author.pk 'restList2' %}
{% if answer.author|class_name == 'User' and answer.author.cro %}
<div class="sroUser sroExecutor">
<div class="iconSRO"></div>
<p>Есть допуск СРО</p>
</div>
{% elif answer.author|class_name == 'Team' %}
<!-- TODO -->
<div class="sroUser sroExecutor">
<div class="iconSRO"></div>
<p>Есть допуск СРО</p>
</div>
{% endif %}
</div>
<div class="col-lg-2 listCens">
<p>
Цена:
<span>{{ answer.budget|intcomma }}</span>
<i class="fa fa-rub"></i>
</p>
<p>
Срок: <span>{{ answer.term }} {{ answer.get_currency_display }} {{ answer.get_term_type_display|decap }}</span>
</p>
<p>Опубликован: {{ answer.created|date:'M d, Y' }}</p>
</div>
<div class="gallMini disTab">
{% for portf in answer.portfolios.all %}
<div class="col-lg-3">
<div class="insetCol box-sizing disTab">
<div class="imgGal" style="background: url('{{ portf.photos.first.img.url }}') no-repeat center">
<div class="imgFigure"></div>
</div>
</div>
</div>
{% endfor %}
</div>
<div class="commBlock44 disTab">
{% for message in answer.messages.all %}
<div class="comm44 disTab">
<div class="col-lg-10 col-lg-offset-1">
{% if message.is_sender_customer %}
<p class="nameComm nameCommAct">
{{ project.customer.get_full_name }}
</p>
{% else %}
<p class="nameComm">
{% if answer.author|class_name == 'User' %}
{{ answer.author.get_full_name }}
{% elif answer.author|class_name == 'Team' %}
{{ answer.author.name }}
{% endif %}
</p>
{% endif %}
<span class="dateComm44">
{{ message.created }}
</span>
<p class="textComm44">
{{ message.text|linebreaksbr }}
</p>
</div>
</div>
{% endfor %}
</div>
</div>
</div>
{% endfor %}
</div>
</div>
{% endif %}
{% endif %}
{% include 'partials/footer.html' %} {% include 'partials/footer.html' %}
</div> </div>

@ -0,0 +1,26 @@
from django import template
from pprint import pprint, pformat
from archilance import util
register = template.Library()
@register.filter
def get_candidates(project):
return tuple(c.answer.author for c in project.candidates.all())
@register.filter
def get_new_answers(project):
return set(project.answers.filter(rejected=False)) - set(c.answer for c in project.candidates.filter(answer__rejected=False))
@register.filter
def get_candidate_answers(project):
return tuple(c.answer for c in project.candidates.filter(answer__rejected=False))
@register.filter
def get_rejected_answers(project):
return project.answers.filter(rejected=True)
# import code; code.interact(local=dict(globals(), **locals()))

@ -3,24 +3,23 @@ from django.views.generic import TemplateView
from .views import ( from .views import (
add_candidate, add_candidate,
CandidateDeleteView,
contractor_portfolio_create, contractor_portfolio_create,
ContractorAnswerArchiveView, ContractorAnswerArchiveView,
ContractorPortfolioTrashView, ContractorPortfolioTrashView,
ContractorPortfolioUpdateView, ContractorPortfolioUpdateView,
ContractorRejectProjectAnswerView,
CustomerProjectCreateView, CustomerProjectCreateView,
CustomerProjectDeleteView, CustomerProjectDeleteView,
CustomerProjectEditView, CustomerProjectEditView,
CustomerProjectRestoreView, CustomerProjectRestoreView,
CustomerProjectTrashView, CustomerProjectTrashView,
CustomerRejectProjectAnswerView,
OfferOrderView, OfferOrderView,
ProjectAnswerCreateMessageView, ProjectAnswerCreateMessageView,
ProjectComparisonView, ProjectComparisonView,
ProjectDetailWithAnswerView, ProjectDetailWithAnswerView,
ProjectFilterView, ProjectFilterView,
RejectProjectAnswerView,
sort_candidates, sort_candidates,
CandidateDeleteView,
) )
app_name = 'projects' app_name = 'projects'
@ -38,8 +37,7 @@ urlpatterns = [
urls.url(r'^(?P<pk>\d+)/delete/$', CustomerProjectDeleteView.as_view(), name='customer-project-delete'), urls.url(r'^(?P<pk>\d+)/delete/$', CustomerProjectDeleteView.as_view(), name='customer-project-delete'),
urls.url(r'^create-answer-message/(?P<pk>\d+)/$', ProjectAnswerCreateMessageView.as_view(), name='create-answer-message'), urls.url(r'^create-answer-message/(?P<pk>\d+)/$', ProjectAnswerCreateMessageView.as_view(), name='create-answer-message'),
urls.url(r'^contractor-reject-project-answer/(?P<pk>\d+)/$', ContractorRejectProjectAnswerView.as_view(), name='contractor-reject-project-answer'), urls.url(r'^reject-project-answer/(?P<pk>\d+)/$', RejectProjectAnswerView.as_view(), name='reject-project-answer'),
urls.url(r'^customer-reject-project-answer/(?P<pk>\d+)/$', CustomerRejectProjectAnswerView.as_view(), name='customer-reject-project-answer'),
urls.url(r'^portfolio/create/$', contractor_portfolio_create, name='contractor-portfolio-create'), urls.url(r'^portfolio/create/$', contractor_portfolio_create, name='contractor-portfolio-create'),
urls.url(r'^portfolio/(?P<pk>\d+)/edit/$', ContractorPortfolioUpdateView.as_view(), name='contractor-portfolio-edit'), urls.url(r'^portfolio/(?P<pk>\d+)/edit/$', ContractorPortfolioUpdateView.as_view(), name='contractor-portfolio-edit'),

@ -1,6 +1,7 @@
from django.conf import settings from django.conf import settings
from django.contrib import messages from django.contrib import messages
from django.contrib.auth.mixins import PermissionRequiredMixin, LoginRequiredMixin from django.contrib.auth.mixins import PermissionRequiredMixin, LoginRequiredMixin
from django.core.exceptions import PermissionDenied
from django.core.files.base import ContentFile from django.core.files.base import ContentFile
from django.core.paginator import Paginator, EmptyPage, PageNotAnInteger from django.core.paginator import Paginator, EmptyPage, PageNotAnInteger
from django.core.urlresolvers import reverse, reverse_lazy from django.core.urlresolvers import reverse, reverse_lazy
@ -178,43 +179,24 @@ class ProjectAnswerCreateMessageView(BaseMixin, View):
return redirect(redirect_to) return redirect(redirect_to)
class ContractorRejectProjectAnswerView(BaseMixin, View): class RejectProjectAnswerView(BaseMixin, View):
def dispatch(self, request, *args, **kwargs): def dispatch(self, request, *args, **kwargs):
if request.user.is_authenticated() and request.user.is_contractor(): if request.user.is_authenticated():
return super().dispatch(request, *args, **kwargs)
else:
return HttpResponseForbidden('403 Forbidden')
def post(self, request, *args, **kwargs):
answer = get_object_or_404(request.user.contractor_answers, pk=kwargs.get('pk'))
answer.delete()
messages.info(request, 'Вы успешно отказались от проекта')
redirect_to = request.POST.get('next')
return redirect(redirect_to)
class CustomerRejectProjectAnswerView(BaseMixin, View):
def dispatch(self, request, *args, **kwargs):
if request.user.is_authenticated() and request.user.is_customer():
return super().dispatch(request, *args, **kwargs) return super().dispatch(request, *args, **kwargs)
else: else:
return HttpResponseForbidden('403 Forbidden') raise PermissionDenied
def post(self, request, *args, **kwargs): def post(self, request, *args, **kwargs):
answer_id = kwargs.get('pk') if request.user.is_contractor():
answer = get_object_or_404(request.user.contractor_answers, pk=kwargs.get('pk'))
project = get_object_or_404(request.user.projects, answers__pk=answer_id) elif request.user.is_customer():
answer = get_object_or_404(project.answers, pk=answer_id) project = get_object_or_404(request.user.projects, answers__pk=kwargs.get('pk'))
answer = get_object_or_404(project.answers, pk=kwargs.get('pk'))
answer.delete() answer.rejected = True
answer.save()
project.rejected_answers_count = F('rejected_answers_count') + 1
project.save()
messages.info(request, 'Вы успешно отказали пользователю в проекте') messages.info(request, 'Успешный отказ от проекта')
redirect_to = request.POST.get('next') redirect_to = request.POST.get('next')
return redirect(redirect_to) return redirect(redirect_to)

Loading…
Cancel
Save