remotes/origin/PR-39
ArturBaybulatov 10 years ago
commit 31dc2ccdea
  1. 1
      archilance/settings/base.py
  2. 34
      archilance/urls.py
  3. 243
      chat/templates/chat_contractor.html
  4. 53
      chat/templates/chat_customer.html
  5. 3
      chat/views.py
  6. 1
      common/models.py
  7. 2
      projects/migrations/0006_merge.py
  8. 6
      templates/partials/footer.html
  9. 8
      templates/partials/header.html
  10. 25
      templates/password_reset/recovery_done.html
  11. 2
      templates/password_reset/recovery_email.txt
  12. 46
      templates/password_reset/recovery_form.html
  13. 91
      templates/password_reset/reset.html
  14. 33
      templates/password_reset/reset_sent.html
  15. 12
      templates/registration/login.html
  16. 14
      templates/registration/logout.html
  17. 28
      users/templates/contractor_filter.html
  18. 2
      users/templates/contractor_office.html
  19. 16
      users/templates/contractor_profile.html
  20. 9
      users/templates/partials/customer_profile_info_block.html
  21. 10
      users/templates/user_financial_info_edit.html
  22. 5
      users/templates/user_profile_edit.html
  23. 2
      users/urls.py
  24. 10
      users/views.py
  25. 31
      work_sell/forms.py
  26. 22
      work_sell/templates/worksell_detail.html
  27. 2
      work_sell/templates/worksell_edit.html
  28. 121
      work_sell/templates/worksells_list.html
  29. 3
      work_sell/urls.py
  30. 73
      work_sell/views.py

@ -224,6 +224,7 @@ AUTH_USER_MODEL = 'users.User'
ACCOUNT_ACTIVATION_DAYS = 7 ACCOUNT_ACTIVATION_DAYS = 7
REGISTRATION_AUTO_LOGIN = True REGISTRATION_AUTO_LOGIN = True
LOGIN_REDIRECT_URL = '/projects/' LOGIN_REDIRECT_URL = '/projects/'
LOGIN_URL = '/users/login/'
if DEBUG: if DEBUG:
EMAIL_BACKEND = 'django.core.mail.backends.dummy.EmailBackend' EMAIL_BACKEND = 'django.core.mail.backends.dummy.EmailBackend'

@ -7,25 +7,25 @@ from django.views.generic import TemplateView
from .views import HomeTemplateView, TestChatTemplateView from .views import HomeTemplateView, TestChatTemplateView
urlpatterns = [ urlpatterns = [
url(r'^$', HomeTemplateView.as_view()), url(r'^$', HomeTemplateView.as_view()),
url('', include('social.apps.django_app.urls', namespace='social')), url('', include('social.apps.django_app.urls', namespace='social')),
url(r'^chattest/$', TestChatTemplateView.as_view()), url(r'^chattest/$', TestChatTemplateView.as_view()),
url(r'^work_sell/', include('work_sell.urls')), url(r'^work_sell/', include('work_sell.urls')),
url(r'^test/$', TemplateView.as_view(template_name='test.html'), name='test'), url(r'^test/$', TemplateView.as_view(template_name='test.html'), name='test'),
url(r'^projects/', include('projects.urls')), url(r'^projects/', include('projects.urls')),
url(r'^reviews/', include('reviews.urls')), url(r'^reviews/', include('reviews.urls')),
url(r'^wallets/', include('wallets.urls')), url(r'^wallets/', include('wallets.urls')),
url(r'^chat/', include('chat.urls')), url(r'^chat/', include('chat.urls')),
url(r'^specializations/', include('specializations.urls')), url(r'^specializations/', include('specializations.urls')),
url(r'^users/', include('users.urls')), url(r'^users/', include('users.urls')),
url(r'^common/', include('common.urls')), url(r'^common/', include('common.urls')),
url(r'^users/', include('registration.backends.default.urls')), url(r'^password/', include('password_reset.urls')),
url(r'^users/', include('registration.backends.default.urls')),
url(r'^admin/', admin.site.urls), url(r'^admin/', admin.site.urls),
url(r'^api/', include('api.urls')), url(r'^api/', include('api.urls')),
] + static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT) ] + static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
if settings.DEBUG: if settings.DEBUG:
urlpatterns += staticfiles_urlpatterns() urlpatterns += staticfiles_urlpatterns()

@ -24,9 +24,9 @@
</li> </li>
{% if team_orders %} {% if team_orders %}
<li role="presentation"> <li role="presentation">
<a href="#tab3" data-toggle="tab">Исполнители</a> <a href="#tab3" data-toggle="tab">Исполнители</a>
</li> </li>
{% endif %} {% endif %}
</ul> </ul>
</div> </div>
@ -34,7 +34,7 @@
</div> </div>
<div class="tab-content"> <div class="tab-content">
<!-- Tab1 contacts block --> <!-- Tab1 contacts block -->
<div class="chatBlock disTab tab-pane fade in active" id="tab1"> <div class="chatBlock disTab tab-pane fade in active" id="tab1">
<div class="col-lg-3 wrMessages"> <div class="col-lg-3 wrMessages">
<div class="messageBlock box-sizing disTab"> <div class="messageBlock box-sizing disTab">
@ -47,9 +47,24 @@
{% endthumbnail %} {% endthumbnail %}
</div> </div>
<p class="nameMess"> <p class="nameMess">
<div><a href="#" style="color:black;">{{ contact.username }}</a></div> <div><a href="#" style="color:black;">{{ contact.username }}</a></div>
</p> </p>
<a href="javascript:void(0)" class="conMess">Контакты</a>
<div class="modal fade" id="userModal" tabindex="-1" role="dialog">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<button class="close" type="button" data-dismiss="modal">x</button>
<h4 class="modal-title" id="myModalLabel">Название модального
окна</h4>
</div>
<div class="modal-body">
<h3>Содержимое модального окна</h3>
</div>
</div>
</div>
</div>
<a href="#" data-target="#userModal" data-toggle="modal" class="conMess">Контакты</a>
<span>0</span> <span>0</span>
<a href="javascript:void(0)" class="deleteMess"> <a href="javascript:void(0)" class="deleteMess">
@ -70,7 +85,7 @@
<div class="bunChat"> <div class="bunChat">
<div class="setChat box-sizing"> <div class="setChat box-sizing">
<p>Прикрепить файл</p> <p>Прикрепить файл</p>
<span>Не более 10 файлов с общим объемом 500мб</span> <span>Не более 10 файлов с общим объемом 500мб</span>
</div> </div>
<a id="contact-chat-add-message" href="javascript:void(0)">отправить</a> <a id="contact-chat-add-message" href="javascript:void(0)">отправить</a>
</div> </div>
@ -85,16 +100,17 @@
</div> </div>
</div> </div>
</div> </div>
<!-- End block Tab1 --> <!-- End block Tab1 -->
<!-- Tab2 chat order block --> <!-- Tab2 chat order block -->
<div class="chatBlock disTab tab-pane fade" id="tab2"> <div class="chatBlock disTab tab-pane fade" id="tab2">
<div class="col-lg-3 wrMessages"> <div class="col-lg-3 wrMessages">
<div class="messageBlock box-sizing disTab"> <div class="messageBlock box-sizing disTab">
<p>Заказы</p> <p>Заказы</p>
{% for order in orders %} {% for order in orders %}
<div class="orderBlock box-sizing order-block" data-recipent-id="{{ order.project.customer.pk }}" data-id="{{ order.id }}"> <div class="orderBlock box-sizing order-block"
data-recipent-id="{{ order.project.customer.pk }}" data-id="{{ order.id }}">
<span class="dimovChat"></span> <span class="dimovChat"></span>
<p class="titleOB">{{ order }}</p> <p class="titleOB">{{ order }}</p>
<div class="hideOBB"> <div class="hideOBB">
@ -121,7 +137,7 @@
<div class="bunChat"> <div class="bunChat">
<div class="setChat box-sizing"> <div class="setChat box-sizing">
<p>Прикрепить файл</p> <p>Прикрепить файл</p>
<span>Не более 10 файлов с общим объемом 500мб</span> <span>Не более 10 файлов с общим объемом 500мб</span>
</div> </div>
<a href="javascript:void(0)" id="order-chat-add-message">отправить</a> <a href="javascript:void(0)" id="order-chat-add-message">отправить</a>
</div> </div>
@ -154,87 +170,89 @@
<p>Для заметок</p> <p>Для заметок</p>
<form id="add-form-order-note"> <form id="add-form-order-note">
<textarea id="chat2" name="text"></textarea> <textarea id="chat2" name="text"></textarea>
<input type="hidden" name="order" id="orderNote" value="" /> <input type="hidden" name="order" id="orderNote" value=""/>
<input type="hidden" name="sender" id="senderNote" value="{{ request.user.pk }}" /> <input type="hidden" name="sender" id="senderNote" value="{{ request.user.pk }}"/>
<input type="hidden" name="recipent" id="recipentNote" value="" /> <input type="hidden" name="recipent" id="recipentNote" value=""/>
<a href="#" id="add-note-button">сохранить</a> <a href="#" id="add-note-button">сохранить</a>
</form> </form>
</div> </div>
</div> </div>
</div> </div>
<!-- End block Tab2--> <!-- End block Tab2-->
{% if team_orders %} {% if team_orders %}
<!-- Tab3 groups block --> <!-- Tab3 groups block -->
<div class="chatBlock disTab tab-pane fade" id="tab3"> <div class="chatBlock disTab tab-pane fade" id="tab3">
<div class="col-lg-3 wrMessages"> <div class="col-lg-3 wrMessages">
<div class="messageBlock box-sizing disTab"> <div class="messageBlock box-sizing disTab">
<p>Заказы</p> <p>Заказы</p>
{% for torder in team_orders %} {% for torder in team_orders %}
<div class="team-order-block orderBlock box-sizing" data-team-id="{{ torder.team.pk }}" data-order-id="{{ torder.pk}}"> <div class="team-order-block orderBlock box-sizing"
<span class="dimovChat"></span> data-team-id="{{ torder.team.pk }}" data-order-id="{{ torder.pk }}">
<p class="titleOB"> <span class="dimovChat"></span>
{{ torder }} <p class="titleOB">
</p> {{ torder }}
<div class="hideOBB disTab"> </p>
<p class="pOB"> <div class="hideOBB disTab">
{# <span>Заказчик:</span> {{ torder.project.customer }}#} <p class="pOB">
<span>Исполнитель:</span> {{ torder.team.name }} {# <span>Заказчик:</span> {{ torder.project.customer }}#}
</p> <span>Исполнитель:</span> {{ torder.team.name }}
<ul class="listChat1"> </p>
{% for tuser in torder.team.users.all %} <ul class="listChat1">
<li>{{ tuser }}</li> {% for tuser in torder.team.users.all %}
{% endfor %} <li>{{ tuser }}</li>
</ul> {% endfor %}
</ul>
<p class="pOB">
<span>Чаты:</span> <p class="pOB">
{% for tuser in torder.team.users.all %} <span>Чаты:</span>
{% if request.user.pk != tuser.pk %} {% for tuser in torder.team.users.all %}
<span class="team-chat-user" data-id="{{ tuser.pk }}">{{ tuser.username }},</span> {% if request.user.pk != tuser.pk %}
{% endif %} <span class="team-chat-user"
{% endfor %} data-id="{{ tuser.pk }}">{{ tuser.username }},</span>
</p> {% endif %}
<a href="#" class="linkChat11"> {% endfor %}
<span class="glyphicon glyphicon-info-sign" aria-hidden="true"></span> </p>
Полное описание заказа <a href="#" class="linkChat11">
</a> <span class="glyphicon glyphicon-info-sign" aria-hidden="true"></span>
</div> Полное описание заказа
</a>
</div>
</div>
{% endfor %}
</div> </div>
{% endfor %}
</div> </div>
</div> <div class="col-lg-6 commChat">
<div class="col-lg-6 commChat"> <div id="message-chat-team-space"></div>
<div id="message-chat-team-space"></div> <form id="team-chat-form">
<form id="team-chat-form"> <input type="text" name="sender" id="senderId" value="{{ request.user.pk }}"/>
<input type="text" name="sender" id="senderId" value="{{ request.user.pk }}" /> <input type="text" name="recipent" id="recipentId" value=""/>
<input type="text" name="recipent" id="recipentId" value="" /> <input type="text" name="order" id="orderId" value=""/>
<input type="text" name="order" id="orderId" value="" /> <input type="text" name="team" id="teamId" value=""/>
<input type="text" name="team" id="teamId" value="" /> <input type="text" name="document-send" id="documentSendIds"/>
<input type="text" name="document-send" id="documentSendIds" /> <textarea id="chatText" class="chat-textarea box-sizing"></textarea>
<textarea id="chatText" class="chat-textarea box-sizing"></textarea> <div class="bunChat">
<div class="bunChat"> <div class="setChat box-sizing upload">
<div class="setChat box-sizing upload"> <input type="file" name="file" id="upload-document-team"/>
<input type="file" name="file" id="upload-document-team"/> <p>Прикрепить файл</p>
<p>Прикрепить файл</p> </div>
</div> <div id="progress" class="progress">
<div id="progress" class="progress"> <div class="progress-bar progress-bar-success"></div>
<div class="progress-bar progress-bar-success"></div> </div>
</div>
<div id="document-send"> <div id="document-send">
</div> </div>
<a href="javascript:void(0)" id="add-team-chat-message">отправить</a> <a href="javascript:void(0)" id="add-team-chat-message">отправить</a>
</div>
</form>
</div> </div>
</form> <div class="col-lg-3 wrstepschat">
</div>
<div class="col-lg-3 wrstepschat">
</div>
</div> </div>
</div> <!-- End block Tab3-->
<!-- End block Tab3--> {% endif %}
{% endif %}
</div> </div>
{% include 'partials/footer.html' %} {% include 'partials/footer.html' %}
</div> </div>
@ -256,7 +274,7 @@
var domain = '{{ request.META.HTTP_HOST }}'; var domain = '{{ request.META.HTTP_HOST }}';
var port = '{{ request.META.SERVER_PORT }}'; var port = '{{ request.META.SERVER_PORT }}';
domain = domain.replace(':' + port, ''); domain = domain.replace(':' + port, '');
var url = 'ws://' + domain +':8888/chat/' + userId + '/'; var url = 'ws://' + domain + ':8888/chat/' + userId + '/';
var sock = new WebSocket(url); var sock = new WebSocket(url);
var intervalId; var intervalId;
sock.onopen = function () { sock.onopen = function () {
@ -274,7 +292,7 @@
inbox = document.getElementById('message-chat-space'); inbox = document.getElementById('message-chat-space');
} else if (message.answer_type == 'order' || message.answer_type == 'add_message_order') { } else if (message.answer_type == 'order' || message.answer_type == 'add_message_order') {
inbox = document.getElementById('message-chat-order-space'); inbox = document.getElementById('message-chat-order-space');
} else if(message.answer_type == 'add_message_team'){ } else if (message.answer_type == 'add_message_team') {
inbox = document.getElementById('message-chat-team-space'); inbox = document.getElementById('message-chat-team-space');
} }
console.log(message.answer_type); console.log(message.answer_type);
@ -294,7 +312,7 @@
console.log(data); console.log(data);
}; };
this.add_team_message = function(messageData){ this.add_team_message = function (messageData) {
console.log(messageData); console.log(messageData);
sock.send(JSON.stringify(messageData)); sock.send(JSON.stringify(messageData));
@ -327,16 +345,16 @@
var form = document.getElementById('message_form'); var form = document.getElementById('message_form');
var csrftoken = getCookie('csrftoken'); var csrftoken = getCookie('csrftoken');
setTimeout(function(){ setTimeout(function () {
$(".user-block").first().trigger('click'); $(".user-block").first().trigger('click');
}, 10); }, 10);
setTimeout(function(){ setTimeout(function () {
$(".order-block").first().trigger('click'); $(".order-block").first().trigger('click');
}, 100); }, 100);
setTimeout(function(){ setTimeout(function () {
$(".team-order-block").first().trigger('click'); $(".team-order-block").first().trigger('click');
}, 1000); }, 1000);
@ -354,12 +372,13 @@
} }
}, },
dataType: 'json', dataType: 'json',
done: function (e, data) {; done: function (e, data) {
;
$.each(data.result.files, function (index, file) { $.each(data.result.files, function (index, file) {
var currentValue = $("#documentSendIds").val(); var currentValue = $("#documentSendIds").val();
currentValue += file.id + ';'; currentValue += file.id + ';';
$("#documentSendIds").val(currentValue); $("#documentSendIds").val(currentValue);
var htmlImg = '<p>'+ file.name+'</p>'; var htmlImg = '<p>' + file.name + '</p>';
var document_send = $(htmlImg).appendTo("#document-send"); var document_send = $(htmlImg).appendTo("#document-send");
}); });
}, },
@ -374,23 +393,23 @@
.parent().addClass($.support.fileInput ? undefined : 'disabled'); .parent().addClass($.support.fileInput ? undefined : 'disabled');
$("#order-stages").on('click',"#approve-stages",function(e){ $("#order-stages").on('click', "#approve-stages", function (e) {
e.preventDefault(); e.preventDefault();
$(".stage-block-approve").each(function(){ $(".stage-block-approve").each(function () {
var stageId = $(this).attr('data-id'); var stageId = $(this).attr('data-id');
$.ajax({ $.ajax({
url: '/api/stages/' + stageId + '/', url: '/api/stages/' + stageId + '/',
type: 'PATCH', type: 'PATCH',
beforeSend: function(xhr){ beforeSend: function (xhr) {
xhr.setRequestHeader("X-CSRFToken", getCookie('csrftoken')) xhr.setRequestHeader("X-CSRFToken", getCookie('csrftoken'))
}, },
data: "status=in_process", data: "status=in_process",
dataType:'json', dataType: 'json',
success: function(json){ success: function (json) {
console.log(json); console.log(json);
}, },
error: function(e){ error: function (e) {
console.log('error'); console.log('error');
console.log(e); console.log(e);
} }
@ -399,13 +418,13 @@
}); });
}); });
$(".team-chat-user").on('click',function(e){ $(".team-chat-user").on('click', function (e) {
e.stopPropagation(); e.stopPropagation();
var recipentId = $(this).attr('data-id'); var recipentId = $(this).attr('data-id');
$("#team-chat-form #recipentId").val(recipentId); $("#team-chat-form #recipentId").val(recipentId);
}); });
$(".team-order-block").on('click', function(){ $(".team-order-block").on('click', function () {
$('.team-order-block').each(function () { $('.team-order-block').each(function () {
$(this).removeClass('orAct'); $(this).removeClass('orAct');
@ -423,7 +442,7 @@
$.ajax({ $.ajax({
url: '/api/message', url: '/api/message',
type: 'GET', type: 'GET',
data: {csrfmiddlewaretoken: csrftoken, 'team': teamId,'order': orderId}, data: {csrfmiddlewaretoken: csrftoken, 'team': teamId, 'order': orderId},
dataType: 'json', dataType: 'json',
success: function (json) { success: function (json) {
$.each(json.results, function (i, v) { $.each(json.results, function (i, v) {
@ -489,7 +508,7 @@
console.log(json.results); console.log(json.results);
var noteHtmlInbox = ''; var noteHtmlInbox = '';
$.each(json.results, function (i, v) { $.each(json.results, function (i, v) {
noteHtmlInbox += '<li>'+ v.text +'<li>'; noteHtmlInbox += '<li>' + v.text + '<li>';
}); });
$(".notes-block").html(noteHtmlInbox); $(".notes-block").html(noteHtmlInbox);
@ -508,15 +527,15 @@
if (json.results.length > 0) { if (json.results.length > 0) {
$.each(json.results, function (i, v) { $.each(json.results, function (i, v) {
if(v.is_paid){ if (v.is_paid) {
stagesReservedHtml += '<li class="reserved">Сумма за этап '+ i +'.Зарезервирована.</li>'; stagesReservedHtml += '<li class="reserved">Сумма за этап ' + i + '.Зарезервирована.</li>';
}else{ } else {
stagesReservedHtml += '<li class="unreserved">Сумма за этап '+ i +'.Не зарезервирована.</li>'; stagesReservedHtml += '<li class="unreserved">Сумма за этап ' + i + '.Не зарезервирована.</li>';
} }
htmlInbox += '<div data-id="' + v.id + '" class="numberStepp box-sizing stage-block-approve"><div class="insetNumStepp">' + htmlInbox += '<div data-id="' + v.id + '" class="numberStepp box-sizing stage-block-approve"><div class="insetNumStepp">' +
'<p class="titleNumStepp"><span>Этап ' + v.pos + '</span>' + v.name + '</p>' + '<p class="titleNumStepp"><span>Этап ' + v.pos + '</span>' + v.name + '</p>' +
'<p class="textNumStepp">Результаты этапа:' + v.result + '</p><div>' + '<p class="textNumStepp">Результаты этапа:' + v.result + '</p><div>' +
'<p>'+ v.status+'</p><span>' + v.cost + '<i class="fa fa-rub"></i></span></div></div></div>'; '<p>' + v.status + '</p><span>' + v.cost + '<i class="fa fa-rub"></i></span></div></div></div>';
}); });
htmlInbox += '<div class="textAreaBlock2 FFD box-sizing disTab"><a id="approve-stages" href="#">согласовать</a></div>'; htmlInbox += '<div class="textAreaBlock2 FFD box-sizing disTab"><a id="approve-stages" href="#">согласовать</a></div>';
@ -529,21 +548,21 @@
}); });
$('#add-note-button').on('click', function(){ $('#add-note-button').on('click', function () {
$.ajax({ $.ajax({
url: '/api/note/', url: '/api/note/',
type: 'POST', type: 'POST',
beforeSend: function (xhr) { beforeSend: function (xhr) {
xhr.setRequestHeader("X-CSRFToken", getCookie('csrftoken')) xhr.setRequestHeader("X-CSRFToken", getCookie('csrftoken'))
}, },
data:$("#add-form-order-note").serialize(), data: $("#add-form-order-note").serialize(),
dataType: 'json', dataType: 'json',
success: function (json) { success: function (json) {
console.log(json); console.log(json);
$("#add-form-order-note #chat2").val(""); $("#add-form-order-note #chat2").val("");
}, },
error: function(e){ error: function (e) {
console.log('error'); console.log('error');
console.log(e); console.log(e);
} }
@ -586,7 +605,7 @@
//Добавить сообщение для исполнителей в группе //Добавить сообщение для исполнителей в группе
$("#add-team-chat-message").on('click', function(){ $("#add-team-chat-message").on('click', function () {
var chatMessage = $("#team-chat-form #chatText").val(); var chatMessage = $("#team-chat-form #chatText").val();
var recipentId = $("#team-chat-form #recipentId").val(); var recipentId = $("#team-chat-form #recipentId").val();
var senderId = $("#team-chat-form #senderId").val(); var senderId = $("#team-chat-form #senderId").val();

@ -32,14 +32,21 @@
{% for contact in contacts_users %} {% for contact in contacts_users %}
<div class="message messd user-block" data-id="{{ contact.pk }}"> <div class="message messd user-block" data-id="{{ contact.pk }}">
<div class="imgMess"> <div class="imgMess">
{% thumbnail contact.avatar "60x60" crop="center" as im %} {% if contact.avatar %}
<img src="{{ im.url }}" alt="mess-image"> {% thumbnail contact.avatar "60x60" crop="center" as im %}
{% endthumbnail %} <img src="{{ im.url }}" alt="mess-image">
{% endthumbnail %}
{% else %}
<img src="{% static 'img/profile.jpg' %}" alt="mess-image">
{% endif %}
</div> </div>
<p class="nameMess"> <p class="nameMess">
<a href="#">{{ contact.username }} {{ contact.username }}</a> <div><a href="#">{{ contact.username }}</a></div>
</p> </p>
<a href="javascript:void(0)" class="conMess">Контакты</a>
<a href="#" data-target="#userModal" data-toggle="modal"
class="conMess">Контакты</a>
<span>0</span> <span>0</span>
<a href="javascript:void(0)" class="deleteMess"> <a href="javascript:void(0)" class="deleteMess">
Удалить контакт Удалить контакт
@ -49,6 +56,20 @@
</div> </div>
</div> </div>
<div class="modal fade" id="userModal" tabindex="-1" role="dialog">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<button class="close" type="button" data-dismiss="modal">x</button>
<h4 class="modal-title" id="myModalLabel">Название модального
окна</h4>
</div>
<div class="modal-body">
<h3>Содержимое модального окна</h3>
</div>
</div>
</div>
</div>
<div class="col-lg-6 commChat" id="contact-chat"> <div class="col-lg-6 commChat" id="contact-chat">
<div id="message-chat-space"> <div id="message-chat-space">
</div> </div>
@ -209,7 +230,7 @@
</button> </button>
<h4 class="modal-title">Оставить отзыв</h4> <h4 class="modal-title">Оставить отзыв</h4>
</div> </div>
<form id="review-adds-form" method="POST">{% csrf_token %} <form id="review-adds-form" method="POST">{% csrf_token %}
<div class="modal-body"> <div class="modal-body">
<div style="height: 250px;"> <div style="height: 250px;">
@ -225,10 +246,12 @@
</div> </div>
<div class="textAreaBlock2 text-nn box-sizing disTab"> <div class="textAreaBlock2 text-nn box-sizing disTab">
<textarea cols="40" name="text" rows="10"></textarea> <textarea cols="40" name="text" rows="10"></textarea>
<input type="hidden" name="from_customer" value="{{ request.user.pk }}" /> <input type="hidden" name="from_customer"
<input type="hidden" name="target_contractor" id="targetContractorId" /> value="{{ request.user.pk }}"/>
<input type="hidden" name="project" id="projectReviewId" /> <input type="hidden" name="target_contractor"
id="targetContractorId"/>
<input type="hidden" name="project" id="projectReviewId"/>
</div> </div>
</div> </div>
</div> </div>
@ -236,7 +259,9 @@
<div class="modal-footer"> <div class="modal-footer">
<button type="button" class="btn btn-default" data-dismiss="modal">Закрыть <button type="button" class="btn btn-default" data-dismiss="modal">Закрыть
</button> </button>
<button type="submit" id="order-review-add" class="btn btn-primary">Оставить отзыв</button> <button type="submit" id="order-review-add" class="btn btn-primary">Оставить
отзыв
</button>
</div> </div>
</form> </form>
@ -494,8 +519,8 @@
$("#chat").val(""); $("#chat").val("");
}); });
$('#order-review-add').on('click', function(){ $('#order-review-add').on('click', function () {
alert('add review'); alert('add review');
}); });
$('#order-chat-add-message').on('click', function () { $('#order-chat-add-message').on('click', function () {
@ -526,7 +551,7 @@
var domain = '{{ request.META.HTTP_HOST }}'; var domain = '{{ request.META.HTTP_HOST }}';
var port = '{{ request.META.SERVER_PORT }}'; var port = '{{ request.META.SERVER_PORT }}';
domain = domain.replace(':' + port, ''); domain = domain.replace(':' + port, '');
var url = 'ws://' + domain +':8888/chat/' + userId + '/'; var url = 'ws://' + domain + ':8888/chat/' + userId + '/';
var sock = new WebSocket(url); var sock = new WebSocket(url);
var intervalId; var intervalId;
sock.onopen = function () { sock.onopen = function () {

@ -2,6 +2,7 @@ from django.shortcuts import render
from django.views.generic import View from django.views.generic import View
from django.db.models import Q from django.db.models import Q
from django.forms import formset_factory from django.forms import formset_factory
from django.contrib.auth.mixins import LoginRequiredMixin
from .models import Message from .models import Message
from .forms import ArticleForm from .forms import ArticleForm
@ -9,7 +10,7 @@ from reviews.forms import Review
from users.models import User from users.models import User
class ChatUserView(View): class ChatUserView(LoginRequiredMixin, View):
template_name = '' template_name = ''
def get(self, request, *args, **kwargs): def get(self, request, *args, **kwargs):

@ -43,6 +43,7 @@ class Settings(models.Model):
document_send_time_remove = models.IntegerField(default=14) document_send_time_remove = models.IntegerField(default=14)
recalculation_spec_time = models.TimeField() recalculation_spec_time = models.TimeField()
recalculation_rating_time = models.TimeField() recalculation_rating_time = models.TimeField()
# worksell_count = models.PositiveIntegerField(default=20)
def __str__(self): def __str__(self):
return 'Настройки сайта' return 'Настройки сайта'

@ -1,5 +1,5 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
# Generated by Django 1.9.7 on 2016-08-15 08:24 # Generated by Django 1.9.7 on 2016-08-15 10:48
from __future__ import unicode_literals from __future__ import unicode_literals
from django.db import migrations from django.db import migrations

@ -24,15 +24,15 @@
</li> </li>
<li> <li>
<a href="">Регистрация</a> <a href="{% url 'registration_register' %}">Регистрация</a>
</li> </li>
<li> <li>
<a href="">Востановить доступ</a> <a href="{% url 'password_reset_recover' %}">Востановить доступ</a>
</li> </li>
<li> <li>
<a href="">Опубликовать проект</a> <a href="{% url 'projects:customer-project-create' %}">Опубликовать проект</a>
</li> </li>
</ul> </ul>
</div> </div>

@ -47,7 +47,7 @@
<span></span> <span></span>
</li> </li>
<li class="icon_tm3"> <li class="icon_tm3">
<a href="#">Работы на продажу</a> <a href="{% url 'work_sell:list' %}">Работы на продажу</a>
<span></span> <span></span>
</li> </li>
</ul> </ul>
@ -108,9 +108,15 @@
<li class="icon_mm5"> <li class="icon_mm5">
<a href="#">Настройки<span></span></a> <a href="#">Настройки<span></span></a>
</li> </li>
<li class="icon_mm6"> <li class="icon_mm6">
<a href="#">FAQ<span></span></a> <a href="#">FAQ<span></span></a>
</li> </li>
<li class="icon_mm6">
<a href="{% url 'auth_logout' %}">Выйти<span></span></a>
</li>
</ul> </ul>
</div> </div>
</div> </div>

@ -3,18 +3,21 @@
{% block title %}{% trans "New password set" %}{% endblock %} {% block title %}{% trans "New password set" %}{% endblock %}
{% block content %} {% block content %}
{% include 'partials/header.html' %}
<div class="container mainScore">
<div class="row">
<div class="col-lg-12">
<p class="titleScore">Успех</p>
</div>
<div class="container container_1200"> <div class="col-lg-12">
<hr> {% trans "Your password has successfully been reset. You can use it right now on the login page." %}
</div> </div>
<!-- block_registr --> {% include 'partials/footer.html' %}
<div class="container container_1200"> </div>
</div>
<div class="block_registr" style="height: auto;">
<div class="text-center registr">Успех</div>
{% trans "Your password has successfully been reset. You can use it right now on the login page." %}
</div>
</div>
<!-- block_registr end -->
{% endblock %} {% endblock %}

@ -4,6 +4,6 @@
{% trans "You can set your new password by following this link:" %} {% trans "You can set your new password by following this link:" %}
http{% if secure %}s{% endif %}://{{ site.domain }} http{% if secure %}s{% endif %}://{{ site.domain }}{% url "password_reset_reset" token %}
{% trans "If you don't want to reset your password, simply ignore this email and it will stay unchanged." %} {% trans "If you don't want to reset your password, simply ignore this email and it will stay unchanged." %}

@ -5,25 +5,37 @@
{% block content %} {% block content %}
{% include 'partials/header.html' %} {% include 'partials/header.html' %}
<div class="container mainScore">
<div class="row">
<div class="col-lg-12"> <div class="col-lg-12">
<p class="titleScore">Восстановление пароля</p> <p class="titleScore">Восстановление пароля</p>
</div> </div>
<div class="form-regestration">
<form method="post" action="{{ url }}"> <div class="form-regestration" style="padding-top:10px;">
{% csrf_token %} <form method="post" action="{{ url }}">
{% csrf_token %}
<div class="col-lg-12 select-reg">
<input type="email" name="{{ form.username_or_email.name }}" class="box-sizing pass-reg" id="inputEmail"
placeholder="Электронная почта">
<p>{{ form.username_or_email.errors.as_text }}</p>
</div>
<div class="col-lg-12 select-reg"> <div class="col-lg-12 select-reg">
<button type="submit" class="reg-sub"> <input type="email" name="{{ form.username_or_email.name }}" class="box-sizing pass-reg"
Восстановить id="inputEmail"
</button> placeholder="Электронная почта">
<p>{{ form.username_or_email.errors.as_text }}</p>
</div>
<div class="col-lg-12 select-reg">
<button type="submit" class="reg-sub">
Восстановить
</button>
</div>
</form>
<div class="col-lg-12 select-reg">
<p></p>
</div>
</div>
{% include 'partials/footer.html' %}
</div> </div>
</form>
</div> </div>
{% endblock %} {% endblock %}

@ -1,46 +1,55 @@
{% extends "password_reset/base.html" %}{% load i18n %} {% extends "password_reset/base.html" %}{% load i18n %}
{% block content %} {% block content %}
<div class="container container_1200"> {% include 'partials/header.html' %}
<hr> <div class="container mainScore">
</div> <div class="row">
<div class="col-lg-12">
<!-- block_registr --> <p class="titleScore">Сброс пароля</p>
<div class="container container_1200"> </div>
<div class="block_registr" style="height: auto;">
<div class="text-center registr">Сброс пароля</div> {% if invalid %}{% url "password_reset_recover" as recovery_url %}
<div class="col-lg-12">
{% if invalid %}{% url "password_reset_recover" as recovery_url %} {% blocktrans %}Sorry, this password reset link is invalid. You can still
{% blocktrans %}Sorry, this password reset link is invalid. You can still <a href="{{ recovery_url }}">request a new one</a>.{% endblocktrans %}
<a href="{{ recovery_url }}">request a new one</a>.{% endblocktrans %} </div>
{% else %} {% else %}
{% blocktrans %}Hi, <strong>{{ username }}</strong>. Please choose your new password.{% endblocktrans %}
<form method="post" action="{% url "password_reset_reset" token %}"> <div class="form-regestration" style="padding-top:10px;">
{% csrf_token %} {% blocktrans %}Hi, <strong>{{ username }}</strong>. Please choose your new password.
{% endblocktrans %}
<div class="form-group"> <form method="post" action="{% url "password_reset_reset" token %}">
<input type="password" name="{{ form.password1.name }}" class="col-xs-10 form-control" id="id_password1" {% csrf_token %}
placeholder="Новый пароль">
<p>{{ form.password1.errors.as_text }}</p> <div class="col-lg-12 select-reg">
</div> <input type="password" name="{{ form.password1.name }}" class="box-sizing pass-reg"
<div class="form-group"> id="id_password1"
<input type="password" name="{{ form.password2.name }}" class="col-xs-10 form-control" id="id_password2" placeholder="Новый пароль">
placeholder="Подтверждение"> <p>{{ form.password1.errors.as_text }}</p>
<p>{{ form.password2.errors.as_text }}</p> </div>
</div>
<div class="col-lg-12 select-reg">
<div> <input type="password" name="{{ form.password2.name }}" class="box-sizing pass-reg"
<button type="submit" class="btn registr_button"> id="id_password2"
Изменить пароль placeholder="Подтверждение">
</button> <p>{{ form.password2.errors.as_text }}</p>
</div> </div>
</form>
{% endif %} <div class="col-lg-12 select-reg">
<button type="submit" class="reg-sub">
Изменить пароль
</button>
</div>
</form>
</div>
{% endif %}
{% include 'partials/footer.html' %}
</div>
</div> </div>
</div>
<!-- block_registr end -->
{% endblock %} {% endblock %}

@ -3,26 +3,21 @@
{% block title %}{% trans "Password recovery sent" %}{% endblock %} {% block title %}{% trans "Password recovery sent" %}{% endblock %}
{#{% block content %}#}
{# <p></p>#}
{#{% endblock %}#}
{% block content %} {% block content %}
{% include 'partials/header.html' %}
<div class="container mainScore">
<div class="row">
<div class="col-lg-12">
<p class="titleScore">Письмо отправлено</p>
</div>
<div class="block_registr" style="height: 300px;">
{% blocktrans with ago=timestamp|timesince %}An email was sent to <strong>{{ email }}</strong>
{{ ago }} ago. Use the link in it to set a new password.{% endblocktrans %}
</div>
<div class="container container_1200"> {% include 'partials/footer.html' %}
<hr> </div>
</div> </div>
<!-- block_registr -->
<div class="container container_1200">
<div class="block_registr" style="height: 300px;">
<div class="text-center registr">Письмо отправлено</div>
{# <div class="alert alert-success">#}
{% blocktrans with ago=timestamp|timesince %}An email was sent to <strong>{{ email }}</strong> {{ ago }} ago. Use the link in it to set a new password.{% endblocktrans %}
</div>
{# </div>#}
</div>
<!-- block_registr end -->
{% endblock %} {% endblock %}

@ -11,12 +11,20 @@
{{ form.errors }} {{ form.errors }}
<form method="post">{% csrf_token %} <form method="post">{% csrf_token %}
<div class="col-lg-12 select-reg"> <div class="col-lg-12 select-reg">
<input type="text" name="{{ form.username.name }}" class="box-sizing email-reg" <input type="text" name="{{ form.username.name }}" value="{{ form.username.value }}" class="box-sizing email-reg"
placeholder="Электронная почта"> placeholder="Электронная почта">
</div> </div>
<div class="col-lg-12 select-reg"> <div class="col-lg-12 select-reg">
<input type="password" name="{{ form.password.name }}" class="box-sizing pass-reg" placeholder="Пароль"> <input type="password" name="{{ form.password.name }}" value="{{ form.password.value }}"class="box-sizing pass-reg" placeholder="Пароль">
</div> </div>
<div class="col-lg-12 select-reg">
<div class="check-reg">
<label><input type="checkbox" name="check-reg"><span></span></label>
<p>Запомнить</p>
<p><a href="{% url 'password_reset_recover' %}">Забыли пароль ?</a></p>
</div>
</div>
<div class="col-lg-12 select-reg"> <div class="col-lg-12 select-reg">
<button class="reg-sub">Вход</button> <button class="reg-sub">Вход</button>
</div> </div>

@ -1,7 +1,15 @@
{% extends 'partials/base.html' %} {% extends 'partials/base.html' %}
{% block content %} {% block content %}
<div class="col-lg-12"> {% include 'partials/header.html' %}
<p class="titleScore">Выход</p> <div class="container mainScore">
</div> <div class="row">
<div class="col-lg-12">
<p class="titleScore">Вы вышли</p>
</div>
{% include 'partials/footer.html' %}
</div>
</div>
{% endblock %} {% endblock %}

@ -1,6 +1,8 @@
{% extends 'partials/base.html' %} {% extends 'partials/base.html' %}
{% load common_tags %} {% load common_tags %}
{% load specializtions_tags %}
{% load thumbnail %}
{% block content %} {% block content %}
{% include 'partials/header.html' %} {% include 'partials/header.html' %}
@ -213,14 +215,6 @@
<span>Интерьеры</span> <span>Интерьеры</span>
<span>2-й</span> <span>2-й</span>
</div> </div>
<div class="insetSpec">
<span>Визуализация/3D</span>
<span>45-й</span>
</div>
<div class="insetSpec">
<span>Экстерьеры</span>
<span>10-й</span>
</div>
<div class="showSpec"> <div class="showSpec">
<div class="insetSpec"> <div class="insetSpec">
<span>Архитектура</span> <span>Архитектура</span>
@ -313,11 +307,21 @@
{% with contractor=obj %} {% with contractor=obj %}
<div class="executorBlock clearfix"> <div class="executorBlock clearfix">
<div class="col-lg-4"> <div class="col-lg-4">
<a href="#" class="aLinkExe"><div class="imgExecutor"> <a href="{% url 'users:contractor-profile' pk=obj.pk %}" class="aLinkExe">
<img src="img/profile.jpg" alt="execitor-image"> <div class="imgExecutor">
</div></a>
{% if contractor.avatar %}
{% thumbnail contractor.avatar "126x125" crop="center" as im %}
<img src="{{ im.url }}" alt="profile-image">
{% endthumbnail %}
{% else %}
<img src="{% static 'img/profile.jpg' %}" alt="profile-image">
{% endif %}
</div>
</a>
<p class="nameExecutor"> <p class="nameExecutor">
<a href="#">{{ contractor.get_full_name }} [{{ contractor.username }}]</a> <a href="{% url 'users:contractor-profile' pk=obj.pk %}">{{ contractor.get_full_name }} [{{ contractor.username }}]</a>
</p> </p>
<p class="navv2">На сайте 8 лет и 3 месяца</p> <p class="navv2">На сайте 8 лет и 3 месяца</p>
<div class="statusUser">Свободен</div> <div class="statusUser">Свободен</div>

@ -16,7 +16,7 @@
<div class="profileTabs"> <div class="profileTabs">
<ul class="nav nav-tabs nav-justified"> <ul class="nav nav-tabs nav-justified">
<li role="presentation"> <li role="presentation">
<a href="#">Поиск исполнителей</a> <a href="{% url 'users:contractor-filter' %}">Поиск исполнителей</a>
</li> </li>
<li role="presentation" class="active"> <li role="presentation" class="active">

@ -71,7 +71,7 @@
<div class="statusUser">Свободен</div> <div class="statusUser">Свободен</div>
{% endif %} {% endif %}
<a href="javascript:void(0)" class="showCon">показать контакты</a> <a href="#" data-toggle="modal" data-target="#contact-contactor-modal" class="showCon">показать контакты</a>
</div> </div>
<div class="col-lg-4"> <div class="col-lg-4">
{% specialization_widget contractor.pk %} {% specialization_widget contractor.pk %}
@ -89,6 +89,20 @@
</div> </div>
</div> </div>
<div id="contact-contactor-modal" class="modal fade">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-hidden="true">×
</button>
<h4 class="modal-title">Контакты владельца </h4>
</div>
<div class="modal-body">
<h2>Здесь находятся контакты владельца</h2>
</div>
</div>
</div>
</div>
<div class="col-lg-9"> <div class="col-lg-9">
<div class="profileTabs2"> <div class="profileTabs2">
<ul class="nav nav-tabs nav-justified"> <ul class="nav nav-tabs nav-justified">

@ -27,9 +27,12 @@
</div> </div>
<div class="col-lg-4"> <div class="col-lg-4">
<a href="javascript:void(0)" class="new-prop new-prop1">показать контакты</a> {% if request.user.pk != customer.pk %}
<a href="javascript:void(0)" class="new-prop new-prop2">написать сообщение</a> <a href="javascript:void(0)" class="new-prop new-prop1">показать контакты</a>
<a href="{% url 'users:user-profile-edit' pk=pk %}" class="new-red">редактировать профиль</a> <a href="{% url 'chat:chat-user' %}?user_id={{ pk }}" class="new-prop new-prop2">написать сообщение</a>
{% else %}
<a href="{% url 'users:user-profile-edit' pk=pk %}" class="new-red">редактировать профиль</a>
{% endif %}
</div> </div>
</div> </div>

@ -1,6 +1,6 @@
{% extends 'partials/base.html' %} {% extends 'partials/base.html' %}
{% load thumbnail %}
{% block content %} {% block content %}
{% include 'partials/header.html' %} {% include 'partials/header.html' %}
@ -20,7 +20,13 @@
<div class="col-lg-3 divCol3"> <div class="col-lg-3 divCol3">
<div class="avatar"> <div class="avatar">
<div class="avatarInset"> <div class="avatarInset">
<img src="{{ form.avatar.value.url }}" alt="profile-image"> {% if form.avatar.value %}
{% thumbnail form.avatar.value "235x224" crop="center" as im %}
<img src="{{ im.url }}" alt="profile-image">
{% endthumbnail %}
{% endif %}
</div> </div>
</div> </div>
<div class="menuUser upload-img disTab"> <div class="menuUser upload-img disTab">

@ -23,7 +23,10 @@
<div class="avatar"> <div class="avatar">
<div class="avatarInset"> <div class="avatarInset">
{% if form.avatar.value %} {% if form.avatar.value %}
<img src="{{ form.avatar.value.url }}" alt="profile-image"> {% thumbnail form.avatar.value "235x224" crop="center" as im %}
<img src="{{ im.url }}" alt="profile-image">
{% endthumbnail %}
{% endif %} {% endif %}
</div> </div>
</div> </div>

@ -23,7 +23,7 @@ from .views import (
app_name = 'users' app_name = 'users'
urlpatterns = [ urlpatterns = [
urls.url(r'^password/', include('password_reset.urls')),
urls.url(r'^(?P<pk>\d+)/edit/$', UserProfileEditView.as_view(), name='user-profile-edit'), urls.url(r'^(?P<pk>\d+)/edit/$', UserProfileEditView.as_view(), name='user-profile-edit'),
urls.url(r'^(?P<pk>\d+)/financial-info/edit/$', UserFinancialInfoEditView.as_view(), name='user-financial-info-edit'), urls.url(r'^(?P<pk>\d+)/financial-info/edit/$', UserFinancialInfoEditView.as_view(), name='user-financial-info-edit'),

@ -204,8 +204,9 @@ class ContractorFilterView(BaseMixin, View):
if get_contractors: if get_contractors:
contractors = User.contractor_objects.filter(cro=cro) # contractors = User.contractor_objects.filter(cro=cro)
contractors = User.contractor_objects
if specialization: if specialization:
contractors = contractors.filter( contractors = contractors.filter(
contractor_specializations__lft__gte=specialization.lft, contractor_specializations__lft__gte=specialization.lft,
@ -230,8 +231,9 @@ class ContractorFilterView(BaseMixin, View):
if get_teams: if get_teams:
teams = Team.objects.filter(Q(contractors__cro=cro) | Q(owner__cro=cro)) # teams = Team.objects.filter(Q(contractors__cro=cro) | Q(owner__cro=cro))
teams = Team.objects
if specialization: if specialization:
teams = teams.filter( teams = teams.filter(
( (

@ -1,7 +1,9 @@
import itertools
from django import forms from django import forms
from common.models import Location from common.models import Location
from .models import WorkSell from .models import WorkSell
from specializations.models import Specialization
class ContractorWorkSellTrashForm(forms.Form): class ContractorWorkSellTrashForm(forms.Form):
@ -41,6 +43,33 @@ class WorkSellForm(forms.ModelForm):
def __init__(self, *args, **kwargs): def __init__(self, *args, **kwargs):
# self.request = kwargs.pop('request') # self.request = kwargs.pop('request')
super().__init__(*args, **kwargs) super().__init__(*args, **kwargs)
self.fields['specialization'].queryset = Specialization.objects.root_nodes()[0].get_descendants()
self.fields['location'].queryset = Location.objects.root_nodes()[0].get_descendants() self.fields['location'].queryset = Location.objects.root_nodes()[0].get_descendants()
# self.fields['location'].queryset = Location.objects # Migrate with this enabled # self.fields['location'].queryset = Location.objects # Migrate with this enabled
class WorkSellFilterForm(forms.ModelForm):
keywords = forms.CharField(required=False, max_length=255)
class Meta:
model = WorkSell
fields = (
'location',
'building_classification',
'construction_type',
'specialization',
)
widgets = {
'building_classification': forms.Select(attrs={'class': 'selectpicker'}),
'construction_type': forms.Select(attrs={'class': 'selectpicker'}),
}
def __init__(self, *args, **kwargs):
self.request = kwargs.pop('request')
super().__init__(*args, **kwargs)
self.fields['specialization'].required = False
self.fields['specialization'].queryset = Specialization.objects.root_nodes()[0].get_descendants()

@ -25,37 +25,27 @@
<div class="col-lg-3"> <div class="col-lg-3">
<p class="cenaReady">{{ object.budget }} <i class="fa fa-rub"></i></p> <p class="cenaReady">{{ object.budget }} <i class="fa fa-rub"></i></p>
</div> </div>
{% if request.user.is_authenticated %}
<div class="col-lg-3"> <div class="col-lg-3">
<a href="{% url 'users:contractor-profile' object.contractor.pk %}" class="linkReady LR1"> <a href="{% url 'users:contractor-profile' object.contractor.pk %}" class="linkReady LR1">
купить купить
</a> </a>
</div> </div>
<div class="col-lg-3"> <div class="col-lg-3">
<a href="{% url 'chat:chat-user' %}" class="linkReady LR2"> <a href="{% url 'chat:chat-user' %}?user_id={{ object.contractor.pk }}" class="linkReady LR2">
Написать сообщение Написать сообщение
</a> </a>
</div> </div>
{% endif %}
<div class="col-lg-3"> <div class="col-lg-3">
<a href="#" data-toggle="modal" data-target="#contact-contactor-modal" class="linkReady LR3"> <a href="{% url 'users:contractor-profile' object.contractor.pk %}" class="linkReady LR3">
посмотреть контакты посмотреть контакты
</a> </a>
</div> </div>
</div> </div>
<div id="contact-contactor-modal" class="modal fade">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-hidden="true">×
</button>
<h4 class="modal-title">Контакты владельца </h4>
</div>
<div class="modal-body">
<h2>Здесь находятся контакты владельца</h2>
</div>
</div>
</div>
</div>
<div class="desReadyBlock"> <div class="desReadyBlock">
<div class="col-lg-10 col-lg-offset-1"> <div class="col-lg-10 col-lg-offset-1">

@ -84,7 +84,7 @@
</div> </div>
<div class="polsF1 polsF2 disTab"> <div class="polsF1 polsF2 disTab">
{% form.ins %}
</div> </div>
<div class="searchF1 polsF1 polsFF links-filter"> <div class="searchF1 polsF1 polsFF links-filter">

@ -13,56 +13,57 @@
</div> </div>
<form action="{{ request.path }}" method="GET" novalidate> <form action="{% url 'work_sell:list' %}" method="GET" novalidate>
<div class="col-lg-12"> <div class="col-lg-12">
<div class="filter clearfix"> <div class="filter clearfix">
<div class="triangle1"></div> <div class="triangle1"></div>
<div class="titleF1 disTab"> <div class="titleF1 disTab">
<div class="col-lg-3">Специализации:</div> <div class="col-lg-3">Специализации</div>
<div class="col-lg-3"></div> <div class="col-lg-9"></div>
<div class="col-lg-3"></div>
<div class="col-lg-3"></div>
</div> </div>
<div class="polsF1 disTab"> <div class="polsF1 disTab">
<div class="col-lg-3"> <div class="col-lg-3">
<input type='hidden' class="-spec-select -spec-select-level-1" style="width: 100%"> <input type="hidden" class="-spec-select -spec-select-level-1" style="width: 100%">
</div> </div>
<div class="col-lg-3"> <div class="col-lg-3">
<input type='hidden' class="-spec-select -spec-select-level-2" style="width: 100%"> <input type="hidden" class="-spec-select -spec-select-level-2" style="width: 100%">
</div> </div>
<div class="col-lg-3"> <div class="col-lg-3">
<input type='hidden' class="-spec-select -spec-select-level-3" style="width: 100%"> <input type="hidden" class="-spec-select -spec-select-level-3" style="width: 100%">
</div> </div>
<div class="col-lg-3"> <div class="col-lg-3">
<input type='hidden' class="-spec-select -spec-select-level-4" style="width: 100%"> <input type="hidden" class="-spec-select -spec-select-level-4" style="width: 100%">
</div> </div>
</div> <input type="hidden" id="chosenSpecId" name="{{ form.specialization.html_name }}" value="{{ form.specialization.value }}">
<div class="titleF1 titleF2 disTab">
<div class="col-lg-4">Тип работ:</div>
<div class="col-lg-8"></div>
</div> </div>
<div class="searchF1 polsF1 polsFF">
<div class="col-lg-4">
<input type="text" placeholder="От" name="from_budget" class="box-sizing otInp"> <div class="searchF1">
<input type="text" placeholder="До" name="to_budget" class="box-sizing otInp"> <div class="col-lg-6">
<select class="selectpicker2 valul"> <input
<option>&#36;</option> type="text"
<option>&#36;</option> name="keywords"
<option>&#36;</option> onkeydown="event.keyCode === 13 && $(this).closest('form').submit()"
</select> value="{{ form.keywords.value }}"
class="searchInp box-sizing"
placeholder="Ключевые слова">
</div> </div>
<div class="col-lg-3"> <div class="col-lg-3">
<a href="#" class="findReal" onclick="$(this).closest('form').submit(); return false">
найти проект
</a>
</div> </div>
<div class="col-lg-3"> <div class="col-lg-3">
<button type="submit" class="findReal">Поиск</button> <a href="{% url 'work_sell:list' %}" class="clearSearch">
</div>
<div class="col-lg-2">
<a href="javascript:void(0)" class="clearSearch">
Очистить фильтр Очистить фильтр
</a> </a>
</div> </div>
</div> </div>
<div class="resSearchF1"> <div class="resSearchF1">
<div class="col-lg-3"> <div class="col-lg-3">
<p class="titleResF1">Расширенный поиск</p> <p class="titleResF1">Расширенный поиск</p>
@ -74,47 +75,69 @@
<div class="borderS1"></div> <div class="borderS1"></div>
</div> </div>
</div> </div>
<div class="slideRes disTab activeSlide"> <div class="slideRes disTab activeSlide">
<div class="titleF1 disTab"> <div class="titleF1 disTab">
<div class="col-lg-3">Классификация</div> <div class="col-lg-3">Классификация здания</div>
<div class="col-lg-3">Вид строительства:</div> <div class="col-lg-3">Вид строительства</div>
<div class="col-lg-3">Местоположение:</div>
<div class="col-lg-3"></div> <div class="col-lg-3"></div>
</div> </div>
<div class="polsF1 polsF2 disTab">
<div class="polsF1 disTab">
<div class="col-lg-3"> <div class="col-lg-3">
<select class="selectpicker" name="building_classification"> {{ form.building_classification }}
{% for bc in building_classifications %}
<option>{{ bc }}</option>
{% endfor %}
</select>
</div> </div>
<div class="col-lg-3"> <div class="col-lg-3">
<select class="selectpicker"> {{ form.construction_type }}
{% for ct in construction_types %}
<option>{{ ct }}</option>
{% endfor %}
</select>
</div> </div>
</div>
</div>
<div class="slideRes disTab activeSlide">
<div class="titleF1 disTab">
<div class="col-lg-3">Местоположение</div>
</div>
<div class="polsF1 disTab">
<div class="col-lg-3"> <div class="col-lg-3">
<select class="selectpicker"> <input type="hidden" class="-location-select -location-select-country" style="width: 100%">
<option>Mustard</option>
</select>
</div> </div>
<div class="col-lg-3">
<input type="hidden" class="-location-select -location-select-region" style="width: 100%">
</div>
<div class="col-lg-3"> <div class="col-lg-3">
<select class="selectpicker"> <input type="hidden" class="-location-select -location-select-city" style="width: 100%">
<option>Mustard</option>
</select>
</div> </div>
<input type="hidden" id="chosenLocationId" name="{{ realty_form.location.html_name }}" value="{{ realty_form.location.value }}">
</div> </div>
</div> </div>
</div> </div>
</div> </div>
</form>
</form>
<div class="galleryWork disTab"> <div class="galleryWork disTab">
{% for work in object_list %} {% for work in work_sells %}
<div class="col-lg-3"> <div class="col-lg-3">
<div class="insetCol box-sizing disTab"> <div class="insetCol box-sizing disTab">
<a href="{% url 'work_sell:detail' work.pk %}"> <a href="{% url 'work_sell:detail' work.pk %}">

@ -11,13 +11,14 @@ from .views import (
BasicCreateView, BasicCreateView,
PictureCreateView, PictureCreateView,
ContractorWorkSellTrashView, ContractorWorkSellTrashView,
WorkSellFilterView,
) )
app_name = 'work_sell' app_name = 'work_sell'
urlpatterns = [ urlpatterns = [
urls.url(r'^$', WorkSellsView.as_view(), name='list'), urls.url(r'^$', WorkSellFilterView.as_view(), name='list'),
# urls.url(r'^create/$', WorkSellCreateView.as_view(), name='create'), # urls.url(r'^create/$', WorkSellCreateView.as_view(), name='create'),
urls.url(r'^upload/$', UploadView.as_view(), name='upload'), urls.url(r'^upload/$', UploadView.as_view(), name='upload'),
urls.url(r'^(?P<pk>\d+)/edit/$',WorkSellUpdateView.as_view(), name='edit'), urls.url(r'^(?P<pk>\d+)/edit/$',WorkSellUpdateView.as_view(), name='edit'),

@ -1,12 +1,16 @@
import json import json
import re
import pydash as _; import pydash as _;
_.map = _.map_; _.map = _.map_;
_.filter = _.filter_ _.filter = _.filter_
from pprint import pprint, pformat from pprint import pprint, pformat
from django.shortcuts import render, redirect from django.shortcuts import render, redirect
from django.conf import settings
from django.contrib import messages from django.contrib import messages
from django.db.models import Q
from django.core.urlresolvers import reverse from django.core.urlresolvers import reverse
from django.core.paginator import Paginator, EmptyPage, PageNotAnInteger
from django.http import JsonResponse, HttpResponse from django.http import JsonResponse, HttpResponse
from django.core.files.base import ContentFile from django.core.files.base import ContentFile
from django.views.generic import ListView, DetailView, CreateView, View, \ from django.views.generic import ListView, DetailView, CreateView, View, \
@ -14,10 +18,10 @@ from django.views.generic import ListView, DetailView, CreateView, View, \
from projects.models import BuildingClassfication, ConstructionType from projects.models import BuildingClassfication, ConstructionType
from .models import WorkSell, Picture, WorkSellPhoto from .models import WorkSell, Picture, WorkSellPhoto
from .forms import WorkSellForm, ContractorWorkSellTrashForm from .forms import WorkSellForm, WorkSellFilterForm, ContractorWorkSellTrashForm
from .serialize import serialize from .serialize import serialize
from .response import JSONResponse, response_mimetype from .response import JSONResponse, response_mimetype
from archilance.mixins import BaseMixin
class PictureCreateView(CreateView): class PictureCreateView(CreateView):
model = Picture model = Picture
@ -63,6 +67,69 @@ class WorkSellsView(ListView):
return context return context
class WorkSellFilterView(BaseMixin,View):
template_name = 'worksells_list.html'
form_class = WorkSellFilterForm
def get(self, request, *args, **kwargs):
form = self.form_class(request.GET, request=request)
context = self.get_context_data(**_.merge({}, request.GET,kwargs))
work_sells = WorkSell.objects
if form.is_valid():
keywords = form.cleaned_data.get('keywords')
specialization = form.cleaned_data.get('specialization')
building_classification = form.cleaned_data.get('building_classification')
construction_type = form.cleaned_data.get('construction_type')
location = form.cleaned_data.get('location')
if keywords:
keywords = tuple(filter(None, re.split(r'\s|,|;', keywords)))
for k in keywords:
work_sells = work_sells.filter(Q(name__icontains=k) | Q(text__icontains=k))
if specialization:
work_sells = work_sells.filter(
specialization__lft__gte=specialization.lft,
specialization__rght__lte=specialization.rght,
)
if building_classification:
work_sells = work_sells.filter(building_classification=building_classification)
if construction_type:
work_sells = work_sells.filter(construction_type=construction_type)
if location:
work_sells = work_sells.filter(
location__lft__gte=location.lft,
location__rght__lte=location.rght,
)
paginator = Paginator(work_sells.all(), settings.PAGE_SIZE)
page = request.GET.get('page')
try:
work_sells = paginator.page(page)
except PageNotAnInteger:
work_sells = paginator.page(1)
except EmptyPage:
work_sells = paginator.page(paginator.num_pages)
context.update({
'form': form,
'work_sells': work_sells,
'is_paginated': True,
'page_obj': work_sells,
})
return render(request, self.template_name, context)
class WorkSellDetail(DetailView): class WorkSellDetail(DetailView):
model = WorkSell model = WorkSell
template_name = 'worksell_detail.html' template_name = 'worksell_detail.html'
@ -78,7 +145,9 @@ def work_sell_create(request):
form = WorkSellForm(data=request.POST) form = WorkSellForm(data=request.POST)
if form.is_valid(): if form.is_valid():
instance = form.save(commit=False) instance = form.save(commit=False)
# import code; code.interact(local=dict(globals(), **locals()))
instance.save() instance.save()
form.save_m2m()
images_ids = request.POST.get('images-ids').split(';')[:-1] images_ids = request.POST.get('images-ids').split(';')[:-1]
for pk in images_ids: for pk in images_ids:
picture = Picture.objects.get(pk=pk) picture = Picture.objects.get(pk=pk)

Loading…
Cancel
Save