remotes/origin/PR-39
ArturBaybulatov 10 years ago
parent 1f8713db24
commit 55f13883ba
  1. 24
      projects/migrations/0014_auto_20160823_1912.py
  2. 4
      projects/models.py
  3. 709
      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),
),
]

@ -78,7 +78,7 @@ class Project(models.Model, HitCountMixin):
('trashed', 'В корзине'), ('trashed', 'В корзине'),
('deleted', 'Удален'), ('deleted', 'Удален'),
) )
budget = models.DecimalField(max_digits=10, decimal_places=0) budget = models.DecimalField(max_digits=10, decimal_places=0)
budget_by_agreement = models.BooleanField(default=False) budget_by_agreement = models.BooleanField(default=False)
created = models.DateTimeField(default=timezone.now) created = models.DateTimeField(default=timezone.now)
@ -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,55 +67,46 @@
</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">
<div class="iconSRO"></div> <div class="iconSRO"></div>
<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,28 @@
</a> </a>
</form> </form>
{% endif %} {% endif %}
</div> </div>
</div> </div>
@ -164,12 +176,6 @@
{% 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,164 +506,426 @@
</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>
{% for answer in project.answers.all %} </div>
<div class="candidateBlock disTab">
<div class="candidate"> {% for answer in project|get_new_answers %}
<div class="col-lg-4"> <div class="candidateBlock disTab">
<a href="#" class="aLinkExe"> <div class="candidate">
<div class="imgExecutor"> <div class="col-lg-4">
{% if answer.author.avatar %} <a href="#" class="aLinkExe">
<img src="{{ answer.author.avatar.url }}" alt="execitor-image"> <div class="imgExecutor">
{% else %} {% if answer.author.avatar %}
<img src="{% static 'img/profile.jpg' %}" alt="execitor-image"> <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>
<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>
<div class="col-lg-3 retts">
<p class="nameExecutor"> {% ratings_widget answer.author.pk 'restList2' %}
{% if answer.author|class_name == 'User' %}
<a href="#">{{ answer.author.get_full_name }} [{{ answer.author.username }}]</a> {% if answer.author|class_name == 'User' and answer.author.cro %}
{% elif answer.author|class_name == 'Team' %} <div class="sroUser sroExecutor">
<a href="#">{{ answer.author.name }}</a> <div class="iconSRO"></div>
{% endif %} <p>Есть допуск СРО</p>
</p> </div>
{% elif answer.author|class_name == 'Team' %}
<p class="navv2">На сайте {{ answer.author.created }}</p> <!-- 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 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> </div>
{% elif answer.author|class_name == 'Team' %}
<!-- TODO -->
<div class="sroUser sroExecutor"> <div class="col-lg-2 listCens">
<div class="iconSRO"></div> <p>
<p>Есть допуск СРО</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>
{% endif %}
</div> <div class="col-lg-3 retts">
{% if answer.author not in project|get_candidates %}
<div class="col-lg-2 listCens"> <a href="{% url 'projects:add-candidate' answer_id=answer.pk project_id=project.pk %}" class="candLink candLink1">
<p> Кандидат
Цена: </a>
<span>{{ answer.budget|intcomma }}</span> {% endif %}
<i class="fa fa-rub"></i>
</p> <a href="{% url 'chat:chat-user' %}" class="candLink candLink2">
<p> предложить проект
Срок: <span>{{ answer.term }} {{ answer.get_currency_display }} {{ answer.get_term_type_display|decap }}</span> </a>
</p>
<p>Опубликован: {{ answer.created|date:'M d, Y' }}</p> <form action="{% url 'projects:reject-project-answer' pk=answer.pk %}" method="POST" novalidate>
</div> {% csrf_token %}
<input type="hidden" name="next" value="{{ request.path }}">
<div class="col-lg-3 retts"> <a href="#" onclick="$(this).closest('form').submit(); return false" class="candLink candLink3">отказ</a>
<a href="{% url 'projects:add-candidate' answer_id=answer.pk project_id=project.pk %}" class="candLink candLink1"> </form>
Кандидат </div>
</a>
<div class="gallMini disTab">
<a href="{% url 'chat:chat-user' %}" class="candLink candLink2"> {% for portf in answer.portfolios.all %}
предложить проект <div class="col-lg-3">
</a> <div class="insetCol box-sizing disTab">
<div class="imgGal" style="background: url('{{ portf.photos.first.img.url }}') no-repeat center">
<form action="{% url 'projects:customer-reject-project-answer' pk=answer.pk %}" method="POST" novalidate> <div class="imgFigure"></div>
{% csrf_token %} </div>
<input type="hidden" name="next" value="{{ request.path }}"> </div>
<a href="#" onclick="$(this).closest('form').submit(); return false" class="candLink candLink3">отказ</a> </div>
</form> {% endfor %}
</div> </div>
<div class="gallMini disTab"> <div class="commBlock44 disTab">
{% for portf in answer.portfolios.all %} {% for message in answer.messages.all %}
<div class="col-lg-3"> <div class="comm44 disTab">
<div class="insetCol box-sizing disTab"> <div class="col-lg-10 col-lg-offset-1">
<div class="imgGal" style="background: url('{{ portf.photos.first.img.url }}') no-repeat center"> {% if message.is_sender_customer %}
<div class="imgFigure"></div> <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>
{% endfor %} </div>
</div> </div>
{% endfor %}
<div class="commBlock44 disTab"> </div>
{% 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 }} <div id="candidate-answers" class="tab-pane fade">
</p> <div class="col-lg-12 exNew">
{% else %} <p>Кандидаты</p>
<p class="nameComm"> </div>
{% if answer.author|class_name == 'User' %}
{{ answer.author.get_full_name }} {% for answer in project|get_candidate_answers %}
{% elif answer.author|class_name == 'Team' %} <div class="candidateBlock disTab">
{{ answer.author.name }} <div class="candidate">
{% endif %} <div class="col-lg-4">
</p> <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 %} {% 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 %}
</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 -->
<span class="dateComm44"> <div class="sroUser sroExecutor">
{{ message.created }} <div class="iconSRO"></div>
</span> <p>Есть допуск СРО</p>
</div>
<p class="textComm44"> {% endif %}
{{ message.text }}
</p>
</div>
</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"> <div class="col-lg-2 listCens">
<form action="{% url 'projects:create-answer-message' pk=answer.pk %}" method="POST" novalidate> <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>
<form action="{% url 'projects:reject-project-answer' pk=answer.pk %}" method="POST" novalidate>
{% csrf_token %} {% csrf_token %}
<input type="hidden" name="next" value="{% url 'projects:detail' pk=project.pk %}"> <input type="hidden" name="next" value="{{ request.path }}">
<a href="#" onclick="$(this).closest('form').submit(); return false" class="candLink candLink3">отказ</a>
<div><textarea name="text"></textarea></div>
<div><button type="submit">Отправить</button></div>
</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>
{% endfor %}
</div>
<div id="rejected-answers" class="tab-pane fade">
<div class="col-lg-12 exNew">
<p>Отказал</p>
</div> </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>
<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>
{% endfor %} </div>
{% endif %} {% endif %}
{% endif %} {% endif %}
{% include 'partials/footer.html' %} {% include 'partials/footer.html' %}
</div> </div>
</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