remotes/origin/setup
ArturBaybulatov 10 years ago
parent 29b1d99301
commit 0d6cb8f796
  1. 2
      README.md
  2. 7
      archilance/util.py
  3. 14
      assets/index.js
  4. 35
      chat/migrations/0003_documents.py
  5. 41
      chat/migrations/0004_auto_20160804_1806.py
  6. 10
      chat/models.py
  7. 8
      common/templatetags/common_tags.py
  8. 24
      projects/migrations/0013_auto_20160804_1403.py
  9. 21
      projects/migrations/0014_auto_20160804_1754.py
  10. 8
      projects/models.py
  11. 41
      projects/templates/customer_project_edit_test.html
  12. 433
      projects/templates/project_detail.html
  13. 31
      projects/views.py
  14. 20
      users/migrations/0004_team_avatar.py
  15. 1
      users/models.py
  16. 6
      users/templates/partials/customer_profile_info_block.html

@ -23,6 +23,7 @@ python manage.py shell_plus --use-pythonrc
```
----------------------------------------
Generate data via:
```
@ -45,6 +46,7 @@ Data generation order:
12. Reviews
or here is right commands in one str:
```
python manage.py generate_superuser &&
python manage.py generate_specializations &&

@ -82,3 +82,10 @@ def lorem(sentences=5):
), ' ')
return _.join(_.times(lambda i_: _.capitalize(_.join(_.sample(words, _.random(5, 30)), ' ')), sentences), '. ')
def decap(s):
if not isinstance(s, str):
raise TypeError('String expected')
return s[0].lower() + s[1:] if len(s) > 0 else s

@ -271,24 +271,24 @@ function loadRealtyDetails(realtyId) {
var $fileUploadContainer = $('#fileUploadContainer')
$('#fileUploadAddBtn').on('click', function($evt) {
$fileUploadContainer.find('.file-upload-widget').last().children('.file-upload-input').click()
$fileUploadContainer.find('.file-upload-widget').last().find('.file-upload-input').click()
})
$fileUploadContainer.on('change', '.file-upload-input', function($evt) {
var $fileInput = $(this)
var $fileUploadWidget = $fileInput.parent('.file-upload-widget')
var $fileUploadWidget = $fileInput.closest('.file-upload-widget')
var filePath = $fileInput.val().replace(/\\/g, '/')
var fileName = path.basename(filePath)
//var fileExt = path.extname(filePath)
var fileSize = $fileInput.get(0).files && humanFileSize($fileInput.get(0).files[0].size)
if (fileName) {
$fileUploadWidget.children('.file-upload-label').text(fileName + ' ' + fileSize)
$fileUploadWidget.find('.file-upload-label').text(fileName + ' ' + fileSize)
var $newFileUploadWidget = $fileUploadWidget.clone()
$newFileUploadWidget.children('.file-upload-label').text('')
$newFileUploadWidget.find('.file-upload-label').text('')
$fileUploadContainer.children('ul').first().append($newFileUploadWidget)
$fileUploadContainer.find('ul').first().append($newFileUploadWidget)
$fileUploadWidget.css('display', 'block')
}
@ -296,12 +296,12 @@ $fileUploadContainer.on('change', '.file-upload-input', function($evt) {
$fileUploadContainer.on('click', '.file-upload-remove-btn', function($evt) {
var $btn = $(this)
$btn.parent('.file-upload-widget').remove()
$btn.closest('.file-upload-widget').remove()
})
$fileUploadContainer.on('click', '.existing-file-remove-btn', function($evt) {
var $btn = $(this)
$btn.parent('.existing-file-widget').remove()
$btn.closest('.existing-file-widget').remove()
})

@ -0,0 +1,35 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.9.7 on 2016-08-04 11:03
from __future__ import unicode_literals
from django.conf import settings
from django.db import migrations, models
import django.db.models.deletion
class Migration(migrations.Migration):
dependencies = [
('projects', '0013_auto_20160804_1403'),
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
('users', '0003_auto_20160726_1931'),
('chat', '0002_message_team'),
]
operations = [
migrations.CreateModel(
name='Documents',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('file', models.FileField(upload_to='chat/documents/')),
('order', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='order_documents', to='projects.Order')),
('recipent', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='recipent_documents', to=settings.AUTH_USER_MODEL)),
('sender', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='sender_documents', to=settings.AUTH_USER_MODEL)),
('team', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='team_documents', to='users.Team')),
],
options={
'verbose_name_plural': 'Входящие Документы',
'verbose_name': 'Входящие Документы',
},
),
]

@ -0,0 +1,41 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.9.7 on 2016-08-04 15:06
from __future__ import unicode_literals
from django.db import migrations, models
import django.db.models.deletion
class Migration(migrations.Migration):
dependencies = [
('chat', '0003_documents'),
]
operations = [
migrations.AlterField(
model_name='documents',
name='order',
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='documents', to='projects.Order'),
),
migrations.AlterField(
model_name='documents',
name='team',
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='documents', to='users.Team'),
),
migrations.AlterField(
model_name='message',
name='order',
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='messages', to='projects.Order'),
),
migrations.AlterField(
model_name='message',
name='team',
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='messages', to='users.Team'),
),
migrations.AlterField(
model_name='notes',
name='order',
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='notes', to='projects.Order'),
),
]

@ -8,11 +8,11 @@ from users.models import User, Team
class Message(models.Model):
text = models.TextField()
created = models.DateTimeField(default=timezone.now)
order = models.ForeignKey(Order, related_name='order_messages',null=True, blank=True)
order = models.ForeignKey(Order, related_name='messages',null=True, blank=True)
sender = models.ForeignKey(User, related_name='sender_messages')
recipent = models.ForeignKey(User, related_name='recipent_messages')
private_type = models.BooleanField(default=False)
team = models.ForeignKey(Team, related_name='team_messages', null=True, blank=True)
team = models.ForeignKey(Team, related_name='messages', null=True, blank=True)
def __str__(self):
return self.text
@ -27,7 +27,7 @@ class Notes(models.Model):
created = models.DateTimeField(default=timezone.now)
sender = models.ForeignKey(User, related_name='sender_notes')
recipent = models.ForeignKey(User, related_name='recipent_notes')
order = models.ForeignKey(Order, related_name='order_notes', null=True, blank=True)
order = models.ForeignKey(Order, related_name='notes', null=True, blank=True)
def __str__(self):
return self.text
@ -39,8 +39,8 @@ class Notes(models.Model):
class Documents(models.Model):
file = models.FileField(upload_to='chat/documents/')
order = models.ForeignKey(Order, related_name='order_documents',null=True, blank=True)
team = models.ForeignKey(Team, related_name='team_documents',null=True, blank=True)
order = models.ForeignKey(Order, related_name='documents', null=True, blank=True)
team = models.ForeignKey(Team, related_name='documents', null=True, blank=True)
sender = models.ForeignKey(User, related_name='sender_documents')
recipent = models.ForeignKey(User, related_name='recipent_documents')

@ -57,4 +57,12 @@ def lorem(*args, **kwargs):
return util.lorem(*args, **kwargs)
@register.filter
def decap(val):
if isinstance(val, str):
return util.decap(val)
return val
# import code; code.interact(local=dict(globals(), **locals()))

@ -0,0 +1,24 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.9.7 on 2016-08-04 11:03
from __future__ import unicode_literals
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('projects', '0012_merge'),
]
operations = [
migrations.RenameModel(
old_name='AnswerFiles',
new_name='AnswerFile',
),
migrations.AlterField(
model_name='answer',
name='portfolios',
field=models.ManyToManyField(blank=True, related_name='portfolios_answers', to='projects.Portfolio'),
),
]

@ -0,0 +1,21 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.9.7 on 2016-08-04 14:54
from __future__ import unicode_literals
from django.db import migrations, models
import django.db.models.deletion
class Migration(migrations.Migration):
dependencies = [
('projects', '0013_auto_20160804_1403'),
]
operations = [
migrations.AlterField(
model_name='order',
name='team',
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='orders', to='users.Team'),
),
]

@ -141,7 +141,7 @@ class Answer(models.Model):
ordering = ('-created',)
class AnswerFiles(models.Model):
class AnswerFile(models.Model):
answer = models.ForeignKey(Answer, related_name='files', blank=True, null=True)
name = models.CharField(max_length=255)
file = models.FileField(upload_to='projects/answer_files')
@ -156,15 +156,15 @@ class AnswerFiles(models.Model):
class Order(models.Model):
contractor = models.ForeignKey(User, null=True, blank=True, related_name='orders')
team = models.ForeignKey(Team, null=True, blank=True, related_name='team_orders')
team = models.ForeignKey(Team, null=True, blank=True, related_name='orders')
created = models.DateTimeField(default=timezone.now)
project = models.OneToOneField(Project, related_name='order')
secure = models.BooleanField(default=False)
status = models.BooleanField(default=False)
def __str__(self):
return self.project.name
class Meta:
verbose_name = 'Заказ'
verbose_name_plural = 'Заказы'

@ -1,41 +0,0 @@
{% load staticfiles %}
{% load common_tags %}
<!doctype html>
<html>
<head>
<meta charset='utf-8'>
<meta http-equiv='X-UA-Compatible' content='IE=edge, chrome=1'>
<meta name='viewport' content='width=device-width, initial-scale=1'>
<!--<meta name='viewport' content='initial-scale=1.0, user-scalable=no, maximum-scale=1'>-->
<title>Archilance</title>
<link rel='stylesheet' href='{% static "css/bootstrap.css" %}'>
<link rel='stylesheet' href='{% static "css/dev-colors.css" %}'> <!-- Dev-time only, temporary!!! -->
</head>
<body>
{% if messages %}
{% for message in messages %}
<div class="c" style='padding: 10px; margin-bottom: 6px'>{{ message | safe }}</div>
{% endfor %}
{% endif %}
<h1>"pk": {{ pk }}</h1>
<form action="{% url 'projects:customer-project-edit' pk=pk %}" method="POST">
{% csrf_token %}
{{ form.as_p }}
<input type="hidden" name="next" value="{% url 'projects:detail' pk=pk %}">
<button type="submit">Сохранить</button>
{% if back %}<a href='{{ back }}'>Назад</a>{% endif %}
</form>
<script src='{% static "js/jquery-2.2.3.min.js" %}'></script>
<script src='{% static "js/bootstrap.min.js" %}'></script>
</body>
</html>

@ -78,6 +78,7 @@
</div>
</div>
</div>
<div class="col-lg-3 retts new-list">
<ul class="desListPro">
<li>
@ -163,16 +164,161 @@
{% if request.user.is_contractor and True %}
<form action="{% url 'projects:detail' pk=project.pk %}" method="POST" novalidate>
{% if request.user.is_contractor and request.user.contractor_answers.exists %}
{% with answer=request.user.contractor_answers.first %}
<div class="b 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">
<a href="#">{{ answer.author.get_full_name }} [{{ answer.author.username }}]</a>
</p>
<p class="navv2">На сайте {{ answer.contractor.created }}</p>
<div class="statusUser">Свободен</div>
</div>
<div class="col-lg-3 retts">
<ul class="rettList restList2">
<li>Рейтинг: <span> 0</span></li>
<li>Безопасные сделки: <span> 0</span></li>
<li>
<a href="javascript:void(0)">Отзывы:
<span> + 0</span>
<small> 0</small>
<mark> - 0</mark>
</a>
</li>
</ul>
<div class="sroUser sroExecutor">
<div class="iconSRO"></div>
<p>Есть допуск СРО</p>
</div>
</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_term_type_display|decap }}</span>
</p>
<p>Опубликован: {{ answer.created }}</p>
</div>
<div class="col-lg-3 retts">
<a href="{% url 'projects:add-candidate' answer_id=answer.pk project_id=project.pk %}" class="candLink candLink1">
Кандидат
</a>
<a href="{% url 'projects:offer-order' answer_id=answer.pk project_id=project.pk %}" class="candLink candLink2">
предложить проект
</a>
<a href="javascript:void(0)" class="candLink candLink3">
отказ
</a>
</div>
<div class="gallMini disTab">
<div class="col-lg-3">
<div class="insetCol box-sizing disTab">
<div class="imgGal">
<div class="imgFigure"></div>
</div>
</div>
</div>
<div class="col-lg-3">
<div class="insetCol box-sizing disTab">
<div class="imgGal">
<div class="imgFigure"></div>
</div>
</div>
</div>
<div class="col-lg-3">
<div class="insetCol box-sizing disTab">
<div class="imgGal">
<div class="imgFigure"></div>
</div>
</div>
</div>
<div class="col-lg-3">
<div class="insetCol box-sizing disTab">
<div class="imgGal">
<div class="imgFigure"></div>
</div>
</div>
</div>
</div>
<div class="commBlock44 disTab">
<div class="comm44 disTab">
<div class="col-lg-10 col-lg-offset-1">
<p class="nameComm">
Иванов Петр Иванович
</p>
<span class="dateComm44">
13.01.2016 / 21:05
</span>
<div class="stars box-sizing">
<span class="glyphicon glyphicon-star starAct" aria-hidden="true"></span>
<span class="glyphicon glyphicon-star starAct" aria-hidden="true"></span>
<span class="glyphicon glyphicon-star starAct" aria-hidden="true"></span>
<span class="glyphicon glyphicon-star" aria-hidden="true"></span>
<span class="glyphicon glyphicon-star" aria-hidden="true"></span>
</div>
<p class="textComm44">
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Aenean euismod bibendum laoreet. Proin gravida dolor sit amet lacus accumsan et viverra justo commodo. Proin sodales pulvinar tempor. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Nam fermentum, nulla luctus pharetra vulputate, felis tellus mollis orci, sed rhoncus sapien nunc eget odio.
</p>
</div>
</div>
<div class="comm44 disTab">
<div class="col-lg-10 col-lg-offset-1">
<p class="nameComm nameCommAct">
Иванов Петр Иванович
</p>
<span class="dateComm44">
13.01.2016 / 21:05
</span>
<p class="textComm44">
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Aenean euismod bibendum laoreet. Proin gravida dolor sit amet lacus accumsan et viverra justo commodo. Proin sodales pulvinar tempor. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Nam fermentum, nulla luctus pharetra vulputate, felis tellus mollis orci, sed rhoncus sapien nunc eget odio.
</p>
<a href="javascript:void(0)" class="answerComm">
Ответить
</a>
</div>
</div>
</div>
</div>
</div>
{% endwith %}
{% elif request.user.is_contractor %}
<form action="{% url 'projects:detail' pk=project.pk %}" method="POST" enctype="multipart/form-data" novalidate>
{% csrf_token %}
<input type="hidden" name="next" value="{% url 'projects:detail' pk=project.pk %}">
<div class="a polsF1 disTab">
<div class="polsF1 disTab">
<div class="col-lg-3">
<div class="textAreaBlock2 text-nn box-sizing disTab">
<p>Стоимость</p>
<input type="text" class="box-sizing" name="{{ form.budget.html_name }}">
<p>Стоимость <span style="color: red">{{ form.budget.errors.as_text }}</span></p>
<input type="text" class="box-sizing" name="{{ form.budget.html_name }}" value="{{ form.budget.value }}">
</div>
</div>
@ -184,8 +330,8 @@
<div class="col-lg-3">
<div class="textAreaBlock2 text-nn box-sizing disTab">
<p>Срок</p>
<input type="text" class="box-sizing" name="{{ form.term.html_name }}">
<p>Срок <span style="color: red">{{ form.term.errors.as_text }}</span></p>
<input type="text" class="box-sizing" name="{{ form.term.html_name }}" value="{{ form.term.value }}">
</div>
</div>
@ -196,41 +342,61 @@
</div>
</div>
<div class="a polsF1 disTab searchF1">
<div class="polsF1 disTab searchF1">
<div class="col-lg-9">
<div class="textAreaBlock2 text-nn box-sizing disTab">
<p>Текст</p>
<textarea name="{{ form.text.html_name }}" id="text-new"></textarea>
<p>Текст <span style="color: red">{{ form.text.errors.as_text }}</span></p>
<textarea name="{{ form.text.html_name }}" id="text-new">{{ form.text.value }}</textarea>
</div>
</div>
<div class="col-lg-3"></div>
</div>
<div class="a polsF1 disTab searchF1">
<div class="polsF1 disTab searchF1">
<div class="col-lg-9">
<p>Портфолио</p>
<p>Портфолио <span style="color: red">{{ form.portfolios.errors.as_text }}</span></p>
<ul>
{% for p in request.user.portfolios.all %}
<li><input type="checkbox" name="{{ form.portfolios.html_name }}" value="{{ p.pk }}"> {{ p.name }}</li>
{% endfor %}
{% for p in request.user.portfolios.all %}
<li>
<input
type="checkbox"
name="{{ form.portfolios.html_name }}"
value="{{ p.pk }}"
{% if p.pk|str in form.portfolios.value %}checked{% endif %}>
{{ p.name }}
</li>
{% endfor %}
</ul>
</div>
</div>
<div class="a polsF1 disTab searchF1">
<div class="polsF1 disTab searchF1">
<div class="col-lg-9">
<button>Добавить файл</button> Не более 10 файлов общим объемом до 500 Мб
<div id="fileUploadContainer">
<div>
<button type="button" id="fileUploadAddBtn">Добавить файл</button> Не более 10 файлов общим объемом до 500 Мб
</div>
<ul class="list-new-new">
<li class="file-upload-widget" style="display: none">
<input type="file" name="new_files" class="file-upload-input" style="position: absolute; top: -1000px; left: -1000px">
<span class="file-upload-label"></span>
<a href="#" onclick="return false" class="file-upload-remove-btn">&times;</a>
</li>
</ul>
</div>
</div>
</div>
<div class="a polsF1 disTab searchF1">
<div class="polsF1 disTab searchF1">
<div class="col-lg-9">
{{ form.secure_deal_only }} Работаю только по безопасной сделке
</div>
</div>
<div class="a polsF1 disTab searchF1">
<div class="polsF1 disTab searchF1">
<div class="col-lg-3">
<button type="submit">Опубликовать ответ</button>
</div>
@ -243,235 +409,6 @@
{% elif request.user.is_contractor and False %}
{# {% with answer=tmp_answer %}#}
{# <div class="candidateBlock disTab">#}
{# <div class="candidate">#}
{# <div class="col-lg-4">#}
{# <a href="#" class="aLinkExe">#}
{# <div class="imgExecutor">#}
{# <img src="{% static 'img/profile.jpg' %}" alt="execitor-image">#}
{# </div>#}
{# </a>#}
{# <p class="nameExecutor">#}
{# <a href="#"> {{ answer.contractor.get_full_name }} []</a>#}
{# </p>#}
{# <p class="navv2">На сайте {{ answer.contractor.created }}</p>#}
{# <div class="statusUser">Свободен</div>#}
{# </div>#}
{# <div class="col-lg-3 retts">#}
{# <ul class="rettList restList2">#}
{# <li>Рейтинг: <span> 0</span></li>#}
{# <li>Безопасные сделки: <span> 0</span></li>#}
{# <li>#}
{# <a href="javascript:void(0)">Отзывы:#}
{# <span> + 0</span>#}
{# <small> 0</small>#}
{# <mark> - 0</mark>#}
{# </a>#}
{# </li>#}
{# </ul>#}
{# <div class="sroUser sroExecutor">#}
{# <div class="iconSRO"></div>#}
{# <p>Есть допуск СРО</p>#}
{# </div>#}
{# </div>#}
{# <div class="col-lg-2 listCens">#}
{# <p>Цена:#}
{# <span> {{ answer.cost|intcomma }}</span>#}
{# <i class="fa fa-rub"></i>#}
{# </p>#}
{# <p>#}
{# Срок: <span>{{ answer.term }} {{ answer.term_type }}</span>#}
{# </p>#}
{# <p>Опубликован: {{ answer.created }}</p>#}
{# </div>#}
{# <div class="col-lg-3 retts">#}
{# <a href="{% url 'projects:add-candidate' answer_id=answer.pk project_id=project.pk %}" class="candLink candLink1">#}
{# Кандидат#}
{# </a>#}
{# <a href="{% url 'projects:offer-order' answer_id=answer.pk project_id=project.pk %}" class="candLink candLink2">#}
{# предложить проект#}
{# </a>#}
{# <a href="javascript:void(0)" class="candLink candLink3">#}
{# отказ#}
{# </a>#}
{# </div>#}
{# <div class="gallMini disTab">#}
{# <div class="col-lg-3">#}
{# <div class="insetCol box-sizing disTab">#}
{# <div class="imgGal">#}
{# <div class="imgFigure"></div>#}
{# </div>#}
{# </div>#}
{# </div>#}
{# </div>#}
{# <div class="commBlock44 disTab">#}
{# <div class="comm44 disTab">#}
{# <div class="col-lg-10 col-lg-offset-1">#}
{# <p class="nameComm">#}
{# Иванов Петр Иванович#}
{# </p>#}
{# <span class="dateComm44">#}
{# 13.01.2016 / 21:05#}
{# </span>#}
{# <div class="stars box-sizing">#}
{# <span class="glyphicon glyphicon-star starAct" aria-hidden="true"></span>#}
{# <span class="glyphicon glyphicon-star starAct" aria-hidden="true"></span>#}
{# <span class="glyphicon glyphicon-star starAct" aria-hidden="true"></span>#}
{# <span class="glyphicon glyphicon-star" aria-hidden="true"></span>#}
{# <span class="glyphicon glyphicon-star" aria-hidden="true"></span>#}
{# </div>#}
{# <p class="textComm44">Lorem ipsum dolor sit amet</p>#}
{# </div>#}
{# </div>#}
{# </div>#}
{# </div>#}
{# </div>#}
{# {% endwith %}#}
<div class="b candidateBlock disTab">
<div class="candidate">
<div class="col-lg-4">
<a href="#" class="aLinkExe">
<div class="imgExecutor">
<img src="{% static 'img/profile.jpg' %}" alt="execitor-image">
</div>
</a>
<p class="nameExecutor">
<a href="#">Иванов Петр Иванович [ivanov_petr]</a>
</p>
<p class="navv2">На сайте 8 лет и 3 месяца</p>
<div class="statusUser">Свободен</div>
</div>
<div class="col-lg-3 retts">
<ul class="rettList restList2">
<li>Рейтинг: <span> 1245</span></li>
<li>Безопасные сделки: <span> 5</span></li>
<li>
<a href="javascript:void(0)">Отзывы:
<span> + 385</span>
<small> 0</small>
<mark> - 0</mark>
</a>
</li>
</ul>
<div class="sroUser sroExecutor">
<div class="iconSRO"></div>
<p>Есть допуск СРО</p>
</div>
</div>
<div class="col-lg-2 listCens">
<p>Цена:
<span> 35 000</span>
<i class="fa fa-rub"></i>
</p>
<p>
Срок: <span>3 недели</span>
</p>
<p>Опубликован: 22.04.2016</p>
</div>
<div class="col-lg-3 retts">
<a href="javascript:void(0)" class="candLink candLink1">
Кандидат
</a>
<a href="javascript:void(0)" class="candLink candLink2">
предложить проект
</a>
<a href="javascript:void(0)" class="candLink candLink3">
отказ
</a>
</div>
<div class="gallMini disTab">
<div class="col-lg-3">
<div class="insetCol box-sizing disTab">
<div class="imgGal">
<div class="imgFigure"></div>
</div>
</div>
</div>
<div class="col-lg-3">
<div class="insetCol box-sizing disTab">
<div class="imgGal">
<div class="imgFigure"></div>
</div>
</div>
</div>
<div class="col-lg-3">
<div class="insetCol box-sizing disTab">
<div class="imgGal">
<div class="imgFigure"></div>
</div>
</div>
</div>
<div class="col-lg-3">
<div class="insetCol box-sizing disTab">
<div class="imgGal">
<div class="imgFigure"></div>
</div>
</div>
</div>
</div>
<div class="commBlock44 disTab">
<div class="comm44 disTab">
<div class="col-lg-10 col-lg-offset-1">
<p class="nameComm">
Иванов Петр Иванович
</p>
<span class="dateComm44">
13.01.2016 / 21:05
</span>
<div class="stars box-sizing">
<span class="glyphicon glyphicon-star starAct" aria-hidden="true"></span>
<span class="glyphicon glyphicon-star starAct" aria-hidden="true"></span>
<span class="glyphicon glyphicon-star starAct" aria-hidden="true"></span>
<span class="glyphicon glyphicon-star" aria-hidden="true"></span>
<span class="glyphicon glyphicon-star" aria-hidden="true"></span>
</div>
<p class="textComm44">
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Aenean euismod bibendum laoreet. Proin gravida dolor sit amet lacus accumsan et viverra justo commodo. Proin sodales pulvinar tempor. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Nam fermentum, nulla luctus pharetra vulputate, felis tellus mollis orci, sed rhoncus sapien nunc eget odio.
</p>
</div>
</div>
<div class="comm44 disTab">
<div class="col-lg-10 col-lg-offset-1">
<p class="nameComm nameCommAct">
Иванов Петр Иванович
</p>
<span class="dateComm44">
13.01.2016 / 21:05
</span>
<p class="textComm44">
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Aenean euismod bibendum laoreet. Proin gravida dolor sit amet lacus accumsan et viverra justo commodo. Proin sodales pulvinar tempor. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Nam fermentum, nulla luctus pharetra vulputate, felis tellus mollis orci, sed rhoncus sapien nunc eget odio.
</p>
<a href="javascript:void(0)" class="answerComm">
Ответить
</a>
</div>
</div>
</div>
</div>
</div>
{% elif request.user.is_customer %}

@ -14,7 +14,7 @@ import pydash as _; _.map = _.map_; _.filter = _.filter_
import re
from .mixins import LastAccessMixin
from .models import Project, ProjectFile, Portfolio, Candidate, Answer, Realty, Order
from .models import Project, ProjectFile, Portfolio, Candidate, Answer, AnswerFile, Realty, Order
from archilance.mixins import BaseMixin
from users.models import User
@ -42,10 +42,6 @@ class ProjectDetailWithContractorAnswerView(BaseMixin, View):
project = get_object_or_404(Project, pk=kwargs.get('pk'))
context.update({'project': project})
# context.update({'tmp_answer': Answer.objects.order_by('?').first()})
# import code; code.interact(local=dict(globals(), **locals()))
if request.user.is_authenticated() and request.user.is_contractor():
form = self.form_class(request=request)
context.update({'form': form})
@ -61,11 +57,17 @@ class ProjectDetailWithContractorAnswerView(BaseMixin, View):
context.update({'project': project})
if form.is_valid():
print('###############################################')
pprint(form.cleaned_data)
print('###############################################')
answer = form.save(commit=False)
answer.project = project
answer.author = request.user
answer.save()
form.save_m2m()
messages.info(request, 'Форма ОК')
for file in request.FILES.getlist('new_files'):
if len(file.name) <= 255:
AnswerFile.objects.create(file=file, name=file.name, answer=answer)
messages.info(request, 'Отклик успешно размещён')
redirect_to = request.POST.get('next')
return redirect(redirect_to)
else:
@ -199,7 +201,7 @@ class CustomerProjectCreateView(BaseMixin, View):
template_name = 'customer_project_create.html'
def dispatch(self, request, *args, **kwargs):
if request.user.is_authenticated() and request.user.is_customer() and request.user.pk == int(kwargs.get('pk')):
if request.user.is_authenticated() and request.user.is_customer():
return super().dispatch(request, *args, **kwargs)
else:
return HttpResponseForbidden('403 Forbidden')
@ -214,7 +216,7 @@ class CustomerProjectCreateView(BaseMixin, View):
return render(request, self.template_name, context)
def post(self, request, *args, **kwargs):
form = self.form_class(request.POST, request.FILES, request=request)
form = self.form_class(request.POST, request=request) # Passing `request.FILES` seems unnecessary here. Files are added manually below
form.is_valid()
realty = form.cleaned_data.get('realty')
@ -233,8 +235,7 @@ class CustomerProjectCreateView(BaseMixin, View):
Order.objects.create(project=project)
for file in request.FILES.getlist('new_files'):
proj_file = ProjectFile.objects.create(file=file, project=project)
proj_file.save()
ProjectFile.objects.create(file=file, project=project)
if realty:
realty_form.save()
@ -310,7 +311,7 @@ class CustomerProjectEditView(BaseMixin, View):
if form.is_valid() and realty_form.is_valid():
project = form.save(commit=False)
project.customer = request.user
project.files = form.cleaned_data.get('files') # TODO: Somehow get rid of this explicit assignment
project.files = form.cleaned_data.get('files') # TODO: Should we somehow get rid of this explicit assignment?
project.save()
form.save_m2m()
@ -366,7 +367,7 @@ class CustomerProjectTrashView(View):
project = form.cleaned_data.get('pk')
project.state = 'trashed'
project.save()
messages.info(req, 'Проект перемещён в корзину')
else:
messages.info(req, 'Произошла ошибка: <pre>{msg}</pre>'.format(msg=pformat(form.errors)))

@ -0,0 +1,20 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.9.7 on 2016-08-04 16:00
from __future__ import unicode_literals
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('users', '0003_auto_20160726_1931'),
]
operations = [
migrations.AddField(
model_name='team',
name='avatar',
field=models.ImageField(blank=True, upload_to='teams/avatars/'),
),
]

@ -185,6 +185,7 @@ class User(AbstractBaseUser, PermissionsMixin):
class Team(models.Model):
answers = GenericRelation('projects.Answer')
avatar = models.ImageField(upload_to='teams/avatars/', blank=True)
created = models.DateTimeField(default=timezone.now)
name = models.CharField(max_length=255)
owner = models.OneToOneField(User, related_name='team', blank=True, null=True)

@ -5,7 +5,11 @@
<div class="col-lg-3 divCol3">
<div class="avatar new-mar">
<div class="avatarInset">
<img src="{{ customer.avatar.url }}" alt="profile-image">
{% if customer.avatar %}
<img src="{{ customer.avatar.url }}" alt="profile-image">
{% else %}
<img src="{% static 'img/profile.jpg' %}" alt="profile-image">
{% endif %}
</div>
</div>
</div>

Loading…
Cancel
Save