#ARC-27 Add serializers

remotes/origin/setup
Mukhtar 10 years ago
parent ad4cfd8b32
commit b96c34584c
  1. 2
      api/urls.py
  2. 11
      api/views.py
  3. 2
      archilance/settings/base.py
  4. 1
      archilance/urls.py
  5. 27
      chat/templates/chat_contractor.html
  6. 318
      chat/templates/chat_customer.html
  7. 2
      chat/testapp.py
  8. 1
      chat/views.py
  9. 18
      reviews/filters.py
  10. 21
      reviews/forms.py
  11. 31
      reviews/migrations/0003_auto_20160811_1113.py
  12. 30
      reviews/migrations/0004_auto_20160811_1507.py
  13. 38
      reviews/models.py
  14. 24
      reviews/serializers.py
  15. 21
      reviews/templates/review_create.html
  16. 41
      reviews/templates/reviews_list.html
  17. 11
      reviews/urls.py
  18. 20
      reviews/views.py
  19. 20
      users/templates/contractor_profile.html
  20. 1
      wallets/__init__.py
  21. 3
      wallets/apps.py
  22. 4
      wallets/signals.py

@ -10,6 +10,7 @@ from .views import (
StageViewSet, StageViewSet,
NoteViewSet, NoteViewSet,
DocumentViewSet, DocumentViewSet,
ReviewViewSet,
) )
@ -18,6 +19,7 @@ router = routers.DefaultRouter()
router.register(r'locations', LocationViewSet) router.register(r'locations', LocationViewSet)
router.register(r'projects', ProjectViewSet) router.register(r'projects', ProjectViewSet)
router.register(r'stages', StageViewSet) router.register(r'stages', StageViewSet)
router.register(r'reviews', ReviewViewSet)
router.register(r'documents', DocumentViewSet) router.register(r'documents', DocumentViewSet)
router.register(r'realties', RealtyViewSet) router.register(r'realties', RealtyViewSet)
router.register(r'specializations', SpecializationViewSet) router.register(r'specializations', SpecializationViewSet)

@ -22,6 +22,10 @@ from chat.models import Message, Notes, Documents
from chat.serializers import MessageSerializer, NoteSerializer, DocumentsSerializer from chat.serializers import MessageSerializer, NoteSerializer, DocumentsSerializer
from chat.filters import MessageFilterSet, NoteFilterSet, DocumentsFilterSet from chat.filters import MessageFilterSet, NoteFilterSet, DocumentsFilterSet
from reviews.models import Review
from reviews.serializers import ReviewSerializer
from reviews.filters import ReviewFilterSet
class StageViewSet(ModelViewSet): class StageViewSet(ModelViewSet):
queryset = Stage.objects.all() queryset = Stage.objects.all()
@ -30,6 +34,13 @@ class StageViewSet(ModelViewSet):
permission_classes = (permissions.IsAuthenticatedOrReadOnly,) permission_classes = (permissions.IsAuthenticatedOrReadOnly,)
class ReviewViewSet(ModelViewSet):
queryset = Review.objects.all()
serializer_class = ReviewSerializer
filter_class = ReviewFilterSet
permission_classes = (permissions.IsAuthenticatedOrReadOnly,)
class DocumentViewSet(ModelViewSet): class DocumentViewSet(ModelViewSet):
queryset = Documents.objects.all() queryset = Documents.objects.all()
serializer_class = DocumentsSerializer serializer_class = DocumentsSerializer

@ -111,7 +111,7 @@ WSGI_APPLICATION = 'archilance.wsgi.application'
DATABASES = { DATABASES = {
'default': { 'default': {
'ENGINE': 'django.db.backends.postgresql_psycopg2', 'ENGINE': 'django.db.backends.postgresql_psycopg2',
'NAME': 'archilance', 'NAME': 'archilance2',
'USER': 'postgres', 'USER': 'postgres',
'PASSWORD': 'postgres', 'PASSWORD': 'postgres',
'HOST': 'localhost', 'HOST': 'localhost',

@ -15,6 +15,7 @@ urlpatterns = [
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'^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')),

@ -157,7 +157,7 @@
<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="javascript:void()" id="add-note-button">сохранить</a> <a href="#" id="add-note-button">сохранить</a>
</form> </form>
</div> </div>
</div> </div>
@ -195,7 +195,7 @@
{% endif %} {% endif %}
{% endfor %} {% endfor %}
</p> </p>
<a href="javascript:void(0)" class="linkChat11"> <a href="#" class="linkChat11">
<span class="glyphicon glyphicon-info-sign" aria-hidden="true"></span> <span class="glyphicon glyphicon-info-sign" aria-hidden="true"></span>
Полное описание заказа Полное описание заказа
</a> </a>
@ -371,9 +371,28 @@
.parent().addClass($.support.fileInput ? undefined : 'disabled'); .parent().addClass($.support.fileInput ? undefined : 'disabled');
$("#approve-stages").on('click', function(){ $("#order-stages").on('click',"#approve-stages",function(e){
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({
url: '/api/stages/' + stageId + '/',
type: 'PATCH',
beforeSend: function(xhr){
xhr.setRequestHeader("X-CSRFToken", getCookie('csrftoken'))
},
data: "status=in_process",
dataType:'json',
success: function(json){
console.log(json);
},
error: function(e){
console.log('error');
console.log(e);
}
});
}); });
}); });
@ -496,7 +515,7 @@
'<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="javascript:void()">согласовать</a></div>'; htmlInbox += '<div class="textAreaBlock2 FFD box-sizing disTab"><a id="approve-stages" href="#">согласовать</a></div>';
} }
$("#order-stages").html(htmlInbox); $("#order-stages").html(htmlInbox);

@ -24,7 +24,7 @@
</div> </div>
</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">
@ -79,9 +79,9 @@
</div> </div>
</div> </div>
</div> </div>
<!-- End block Tab1(contacts block)--> <!-- End block Tab1(contacts block)-->
<!-- 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">
@ -136,79 +136,51 @@
</p> </p>
</div> </div>
{# <div class="stepssBlock box-sizing disTab">#}
{# <p class="textStepss">#}
{# Какое кол-во этапов подразумевает работа? <input type="text" id="countStage" size="3"/>#}
{# </p>#}
{# <div id="formsetStage" class="numberStepp box-sizing" style="display: none;">#}
{# <div class="insetNumStepp" id="stage1">#}
{# <p class="titleNumStepp">#}
{# <span>Этап </span>#}
{# </p>#}
{# <div class="textAreaBlock2 box-sizing disTab">#}
{# <form class="new-stages-form">#}
{# <label>Название</label>#}
{# <input type="text" name="name" />#}
{# <label>Результат</label>#}
{# <input type="text" name="result" />#}
{# <label>Стоимость</label>#}
{# <input type="text" name="cost" />#}
{# <input type="hidden" name="order" class="orderStagesInput"/>#}
{# </form>#}
{# </div>#}
{# </div>#}
{##}
{# </div>#}
{##}
{# </div>#}
{# <div class="textAreaBlock2 FFD box-sizing disTab">#}
{# <a href="javascript:void()">согласовать</a>#}
{# </div>#}
<div id="order-stages"></div> <div id="order-stages"></div>
<div class="stepssBlock box-sizing disTab"> <div class="stepssBlock box-sizing disTab">
<p class="titleStepss">2 / Резервирование</p> <p class="titleStepss">2 / Резервирование</p>
<p class="textStepss"> <p class="textStepss">
Резервирование заказчиком суммы оплаты по заказ. Деньги перечисляются и хранятся на сайте. Резервирование заказчиком суммы оплаты по заказ. Деньги перечисляются и хранятся на
</p> сайте.
</p>
<div class="textAreaBlock2 FFD box-sizing disTab"> <div class="textAreaBlock2 FFD box-sizing disTab">
<a href="#" data-toggle="modal" data-target="#reserve-stage-modal">Зарезирвировать</a> <a href="#" data-toggle="modal" data-target="#reserve-stage-modal">Зарезирвировать</a>
</div> </div>
</div> </div>
<!-- Зарезервировать средства (модальное окно)--> <!-- Зарезервировать средства (модальное окно)-->
<div id="reserve-stage-modal" class="modal fade"> <div id="reserve-stage-modal" class="modal fade">
<div class="modal-dialog" style="width:900px;"> <div class="modal-dialog" style="width:900px;">
<div class="modal-content"> <div class="modal-content">
<div class="modal-header"> <div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-hidden="true">×</button> <button type="button" class="close" data-dismiss="modal" aria-hidden="true">×
<h4 class="modal-title">Зарезервировать средства</h4> </button>
</div> <h4 class="modal-title">Зарезервировать средства</h4>
</div>
<div class="modal-body"> <div class="modal-body">
<div class="textAreaBlock2 text-nn box-sizing disTab"> <div class="textAreaBlock2 text-nn box-sizing disTab">
</div> </div>
<div class="searchF1 polsF1 polsFF links-filter"> <div class="searchF1 polsF1 polsFF links-filter">
<input class="btn-submit-link" type="submit" value="Сохранить"> <input class="btn-submit-link" type="submit" value="Сохранить">
</div>
</div>
<div class="modal-footer"></div>
</div> </div>
</div> </div>
<div class="modal-footer"></div>
</div> </div>
<!-- Конец блока --> </div>
</div>
<!-- Конец блока -->
<div class="stepssBlock box-sizing disTab"> <div class="stepssBlock box-sizing disTab">
<p class="titleStepss">3 / Выполнение работы</p> <p class="titleStepss">3 / Выполнение работы</p>
<p class="textStepss"> <p class="textStepss">
Процесс выполнения задания в заказе до получения заказчиком итогового результата работы. Процесс выполнения задания в заказе до получения заказчиком итогового результата работы.
</p> </p>
</div> </div>
<div class="textAreaBlock2 box-sizing disTab"> <div class="textAreaBlock2 box-sizing disTab">
@ -216,13 +188,71 @@
<textarea id="chat2"></textarea> <textarea id="chat2"></textarea>
<a href="javascript:void()">сохранить</a> <a href="javascript:void()">сохранить</a>
</div> </div>
<div class="linkChatB box-sizing disTab">
<a href="javascript:void(0)">предложить проект</a>
<div class="closeChat closeChat1">
<a href="#" data-toggle="modal" data-target="#review-add">
Закрыть проект<br>и оставить отзыв
</a>
</div>
<!-- Review add -->
<div id="review-add" class="modal fade" role="dialog">
<div class="modal-dialog" role="document" style="width:900px;">
<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>
<form id="review-adds-form" method="POST">{% csrf_token %}
<div class="modal-body">
<div style="height: 250px;">
<div class="text-nn box-sizing disTab">
<input type="radio" value="positive"
name="type">Положительный
<input type="radio" value="negative"
name="type">Отрицательный
<input type="radio" value="neutral"
name="type">Нейтральный
</div>
<div class="textAreaBlock2 text-nn box-sizing disTab">
<textarea cols="40" name="text" rows="10"></textarea>
<input type="hidden" name="from_customer" value="{{ request.user.pk }}" />
<input type="hidden" name="target_contractor" id="targetContractorId" />
<input type="hidden" name="project" id="projectReviewId" />
</div>
</div>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-default" data-dismiss="modal">Закрыть
</button>
<button type="submit" id="order-review-add" class="btn btn-primary">Оставить отзыв</button>
</div>
</form>
</div>
</div>
</div> </div>
<!-- -->
</div> </div>
</div> </div>
<!-- End block (chat order block) --> <!-- End block (chat order block) -->
</div> </div>
{% include 'partials/footer.html' %} {% include 'partials/footer.html' %}
</div> </div>
</div> </div>
@ -238,46 +268,46 @@
var form = document.getElementById('message_form'); var form = document.getElementById('message_form');
var csrftoken = getCookie('csrftoken'); var csrftoken = getCookie('csrftoken');
function getStages(orderId){ function getStages(orderId) {
$.ajax({ $.ajax({
url: '/api/stages/', url: '/api/stages/',
type: 'GET', type: 'GET',
data: {csrfmiddlewaretoken: csrftoken, 'order': orderId}, data: {csrfmiddlewaretoken: csrftoken, 'order': orderId},
dataType: 'json', dataType: 'json',
success: function (json) { success: function (json) {
var stageCount = json.results.length; var stageCount = json.results.length;
if (stageCount == 0){ if (stageCount == 0) {
stageCountVal = 1; stageCountVal = 1;
}else{ } else {
stageCountVal = stageCount; stageCountVal = stageCount;
} }
var htmlInbox = ""; var htmlInbox = "";
var htmlInboxStage = '<p class="textStepss">Какое кол-во этапов подразумевает работа? ' + var htmlInboxStage = '<p class="textStepss">Какое кол-во этапов подразумевает работа? ' +
'<input type="text" id="countStage" value="'+ stageCountVal +'"size="3"/></p>'; '<input type="text" id="countStage" value="' + stageCountVal + '"size="3"/></p>';
if (stageCount == 0){ if (stageCount == 0) {
htmlInboxStage += '<div class="numberStepp box-sizing" id="stage1">' + htmlInboxStage += '<div class="numberStepp box-sizing" id="stage1">' +
'<p>Этап <span class="stage-span-id">1</span></p><form class="new-stages-form" id="stage-form">' + '<p>Этап <span class="stage-span-id">1</span></p><form class="new-stages-form" id="stage-form">' +
'<label for="">Название</label><input class="form-control" name="name" type="text" />' + '<label for="">Название</label><input class="form-control" name="name" type="text" />' +
'<label for="">Цена</label><input class="form-control" name="cost" type="text" />' + '<label for="">Цена</label><input class="form-control" name="cost" type="text" />' +
'<input class="form-control" name="order" type="text" value="'+ orderId +'" class="orderStagesInput"/> />' + '<input class="form-control" name="order" type="text" value="' + orderId + '" class="orderStagesInput"/> />' +
'<label for="">Срок</label><input class="form-control" name="term" type="text" />' + '<label for="">Срок</label><input class="form-control" name="term" type="text" />' +
'<label for="">Результат</label><input class="form-control" name="result" type="text" />' + '<label for="">Результат</label><input class="form-control" name="result" type="text" />' +
'</form></div>'; '</form></div>';
} }
var statusNotAgreed = true; var statusNotAgreed = true;
$.each(json.results, function (i, v) { $.each(json.results, function (i, v) {
if (v.status == "not_agreed") { if (v.status == "not_agreed") {
htmlInbox += '<div class="numberStepp box-sizing">' + htmlInbox += '<div class="numberStepp box-sizing">' +
'<p>Этап</p><form class="update-stages-form" data-order-id="'+ v.order +'" id="stage-form-'+ v.pos +'">' + '<p>Этап</p><form class="update-stages-form" data-stage-id="' + v.id + '" id="stage-form-' + v.pos + '">' +
'<label for="">Название</label><input class="form-control" type="text" name="name" value="'+ v.name +'" />' + '<label for="">Название</label><input class="form-control" type="text" name="name" value="' + v.name + '" />' +
'<label for="">Цена</label><input class="form-control" type="text" name="cost" value="'+ v.cost +'" />' + '<label for="">Цена</label><input class="form-control" type="text" name="cost" value="' + v.cost + '" />' +
'<input class="form-control" type="hidden" name="order" value="'+ v.order +'" />' + '<input class="form-control" type="hidden" name="order" value="' + v.order + '" />' +
'<label for="">Срок</label><input class="form-control" type="text" name="term" value="'+ v.term +'" />' + '<label for="">Срок</label><input class="form-control" type="text" name="term" value="' + v.term + '" />' +
'<label for="">Результат</label><input class="form-control" type="text" name="result" value="'+ v.result +'" />' + '<label for="">Результат</label><input class="form-control" type="text" name="result" value="' + v.result + '" />' +
'</form></div>'; '</form></div>';
} else { } else {
statusNotAgreed = false; statusNotAgreed = false;
@ -299,55 +329,55 @@
$("#order-stages").html(htmlInbox); $("#order-stages").html(htmlInbox);
} }
}); });
} }
setTimeout(function(){
$(".user-block").first().trigger('click'); setTimeout(function () {
$(".user-block").first().trigger('click');
}, 10); }, 10);
setTimeout(function(){ setTimeout(function () {
$(".order-block").first().trigger('click'); $(".order-block").first().trigger('click');
}, 100); }, 100);
$("#order-stages").on('click', "#addStagesForm", function(e){ $("#order-stages").on('click', "#addStagesForm", function (e) {
e.preventDefault(); e.preventDefault();
$(".new-stages-form").each(function(i,v){ $(".new-stages-form").each(function (i, v) {
console.log($(this).serialize()); console.log($(this).serialize());
$.ajax({ $.ajax({
url: '/api/stages/', url: '/api/stages/',
type: 'POST', type: 'POST',
beforeSend: function (xhr) { beforeSend: function (xhr) {
xhr.setRequestHeader("X-CSRFToken", getCookie('csrftoken')) xhr.setRequestHeader("X-CSRFToken", getCookie('csrftoken'))
}, },
data:$(this).serialize(), data: $(this).serialize(),
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);
} }
}); });
}); });
$(".update-stages-form").each(function(i,v){ $(".update-stages-form").each(function (i, v) {
var currentStageId = parseInt($(this).attr('data-order-id')); var currentStageId = parseInt($(this).attr('data-stage-id'));
alert(currentStageId);
$.ajax({ $.ajax({
url: '/api/stages/' + currentStageId + '/', url: '/api/stages/' + currentStageId + '/',
type: 'PUT', type: 'PUT',
beforeSend: function(xhr){ beforeSend: function (xhr) {
xhr.setRequestHeader("X-CSRFToken", getCookie('csrftoken')) xhr.setRequestHeader("X-CSRFToken", getCookie('csrftoken'))
}, },
data: $(this).serialize(), data: $(this).serialize(),
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);
} }
@ -355,8 +385,6 @@
}); });
var currentOrderId = $(this).attr('data-order-id'); var currentOrderId = $(this).attr('data-order-id');
currentOrderId = parseInt(currentOrderId); currentOrderId = parseInt(currentOrderId);
getStages(currentOrderId); getStages(currentOrderId);
@ -364,7 +392,7 @@
}); });
$('#order-stages-tab').on('change', '#countStage', function(){ $('#order-stages-tab').on('change', '#countStage', function () {
var countStage = parseInt($(this).val()); var countStage = parseInt($(this).val());
var updateFormStages = $(".update-stages-form"); var updateFormStages = $(".update-stages-form");
var limitCount = countStage + 1; var limitCount = countStage + 1;
@ -376,7 +404,7 @@
$('.order-block').on('click', function () { $('.order-block').on('click', function () {
$("#chat-order-add").css("display", "block"); $("#chat-order-add").css("display", "block");
$("#formsetStage").css("display","block"); $("#formsetStage").css("display", "block");
$('.order-block').each(function () { $('.order-block').each(function () {
$(this).removeClass('orAct'); $(this).removeClass('orAct');
@ -386,6 +414,8 @@
var orderId = $(this).attr('data-id'); var orderId = $(this).attr('data-id');
var recipentId = $(this).attr('data-recipent-id'); var recipentId = $(this).attr('data-recipent-id');
$("#chat-order-add #orderId").val(orderId); $("#chat-order-add #orderId").val(orderId);
$("#projectReviewId").val(orderId);
$("#targetContractorId").val(recipentId);
$("#chat-order-add #recipentId").val(recipentId); $("#chat-order-add #recipentId").val(recipentId);
$(".orderStagesInput").val(orderId); $(".orderStagesInput").val(orderId);
var inbox = document.getElementById('message-chat-order-space'); var inbox = document.getElementById('message-chat-order-space');
@ -411,70 +441,7 @@
}); });
} }
}); });
getStages(orderId); getStages(orderId);
{# $.ajax({#}
{# url: '/api/stages/',#}
{# type: 'GET',#}
{# data: {csrfmiddlewaretoken: csrftoken, 'order': orderId},#}
{# dataType: 'json',#}
{# success: function (json) {#}
{# var stageCount = json.results.length;#}
{# if (stageCount == 0){#}
{# stageCountVal = 1;#}
{# }else{#}
{# stageCountVal = stageCount;#}
{# }#}
{##}
{# var htmlInbox = "";#}
{##}
{# var htmlInboxStage = '<p class="textStepss">Какое кол-во этапов подразумевает работа? ' +#}
{# '<input type="text" id="countStage" value="'+ stageCountVal +'"size="3"/></p>';#}
{##}
{# if (stageCount == 0){#}
{# htmlInboxStage += '<div class="numberStepp box-sizing" id="stage1">' +#}
{# '<p>Этап <span class="stage-span-id">1</span></p><form class="new-stages-form" id="stage-form">' +#}
{# '<label for="">Название</label><input class="form-control" name="name" type="text" />' +#}
{# '<label for="">Цена</label><input class="form-control" name="cost" type="text" />' +#}
{# '<input class="form-control" name="order" type="hidden" value="'+ orderId +'" class="orderStagesInput"/> />' +#}
{# '<label for="">Срок</label><input class="form-control" name="term" type="text" />' +#}
{# '<label for="">Результат</label><input class="form-control" name="result" type="text" />' +#}
{# '</form></div>';#}
{# }#}
{# var statusNotAgreed = true;#}
{# $.each(json.results, function (i, v) {#}
{# if (v.status == "not_agreed") {#}
{# htmlInbox += '<div class="numberStepp box-sizing">' +#}
{# '<p>Этап</p><form class="update-stages-form" id="stage-form-'+ v.pos +'">' +#}
{# '<label for="">Название</label><input class="form-control" type="text" value="'+ v.name +'" />' +#}
{# '<label for="">Цена</label><input class="form-control" type="text" value="'+ v.cost +'" />' +#}
{# '<input class="form-control" type="hidden" value="'+ v.order +'" />' +#}
{# '<label for="">Срок</label><input class="form-control" type="text" value="'+ v.term +'" />' +#}
{# '<label for="">Результат</label><input class="form-control" type="text" value="'+ v.result +'" />' +#}
{# '</form></div>';#}
{# } else {#}
{# statusNotAgreed = false;#}
{# htmlInboxStage = "";#}
{# htmlInbox += '<div class="numberStepp box-sizing"><div class="insetNumStepp">' +#}
{# '<p class="titleNumStepp"><span>Этап ' + v.pos + '</span>' + v.name + '</p>' +#}
{# '<p class="textNumStepp">Результаты этапа:' + v.result + '</p><div>' +#}
{# '<p>до 16.03.2015</p><span>' + v.cost + '<i class="fa fa-rub"></i></span></div></div></div>';#}
{##}
{# }#}
{# });#}
{##}
{# if (statusNotAgreed) {#}
{# htmlInbox += '<div class="box-sizing disTab" style="text-align:center;"><div class="checkbox"><input type="checkbox" style="opacity:1">Перейти в режим безопасной сделки' +#}
{# '</div></div><div class="textAreaBlock2 box-sizing disTab">' +#}
{# '<a href="javascript:void()" data-order-id="'+ orderId +'" id="addStagesForm">отправить на согласование</a> </div>';#}
{# }#}
{# htmlInbox = htmlInboxStage + htmlInbox;#}
{# $("#order-stages").html(htmlInbox);#}
{# }#}
{# });#}
}); });
// Вытащить сообщения для конактов // Вытащить сообщения для конактов
@ -527,6 +494,10 @@
$("#chat").val(""); $("#chat").val("");
}); });
$('#order-review-add').on('click', function(){
alert('add review');
});
$('#order-chat-add-message').on('click', function () { $('#order-chat-add-message').on('click', function () {
var chatMessage = $("#chat-order-add #chat").val(); var chatMessage = $("#chat-order-add #chat").val();
var recipentId = $("#chat-order-add #recipentId").val(); var recipentId = $("#chat-order-add #recipentId").val();
@ -550,9 +521,6 @@
}); });
var userId = '{{ request.user.pk }}'; var userId = '{{ request.user.pk }}';
var SocketHandler = function () { var SocketHandler = function () {
var url = 'ws://127.0.0.1:8888/chat/' + userId + '/'; var url = 'ws://127.0.0.1:8888/chat/' + userId + '/';

@ -92,7 +92,7 @@ if __name__ == '__main__':
ioloop = IOLoop.instance() ioloop = IOLoop.instance()
application.db = momoko.Pool( application.db = momoko.Pool(
dsn='dbname=archilance user=postgres password=postgres host=localhost', dsn='dbname=archilance2 user=postgres password=postgres host=localhost',
size=1, size=1,
ioloop=ioloop, ioloop=ioloop,
) )

@ -5,6 +5,7 @@ from django.forms import formset_factory
from .models import Message from .models import Message
from .forms import ArticleForm from .forms import ArticleForm
from reviews.forms import Review
from users.models import User from users.models import User

@ -0,0 +1,18 @@
from rest_framework_filters import FilterSet, RelatedFilter, AllLookupsFilter
from .models import Review
class ReviewFilterSet(FilterSet):
text = AllLookupsFilter()
type = AllLookupsFilter()
created = AllLookupsFilter()
from_customer = RelatedFilter('users.filters.UserFilterSet')
from_contractor = RelatedFilter('users.filters.UserFilterSet')
target_customer = RelatedFilter('users.filters.UserFilterSet')
target_contractor = RelatedFilter('users.filters.UserFilterSet')
class Meta:
model = Review

@ -0,0 +1,21 @@
from django import forms
from .models import Review
class ReviewForm(forms.ModelForm):
class Meta:
model = Review
fields = (
'type',
'text',
'project',
'from_customer',
'target_contractor',
'target_team',
'from_contractor',
'target_customer',
'from_team',
)

@ -0,0 +1,31 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.9.7 on 2016-08-11 08:13
from __future__ import unicode_literals
from django.db import migrations, models
import django.db.models.deletion
class Migration(migrations.Migration):
dependencies = [
('users', '0007_auto_20160808_1557'),
('reviews', '0002_remove_review_is_secured'),
]
operations = [
migrations.AddField(
model_name='review',
name='from_team',
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='team_reviews', to='users.Team'),
),
migrations.AddField(
model_name='review',
name='target_team',
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='reviews_by_team', to='users.Team'),
),
migrations.AlterUniqueTogether(
name='review',
unique_together=set([('from_customer', 'target_contractor', 'project'), ('from_contractor', 'target_customer', 'project'), ('from_team', 'target_customer', 'project'), ('from_customer', 'target_team', 'project')]),
),
]

@ -0,0 +1,30 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.9.7 on 2016-08-11 12:07
from __future__ import unicode_literals
from django.db import migrations, models
import django.utils.timezone
class Migration(migrations.Migration):
dependencies = [
('reviews', '0003_auto_20160811_1113'),
]
operations = [
migrations.RemoveField(
model_name='review',
name='stars',
),
migrations.AddField(
model_name='review',
name='created',
field=models.DateTimeField(default=django.utils.timezone.now),
),
migrations.AddField(
model_name='review',
name='type',
field=models.CharField(choices=[('positive', 'Положительный'), ('negative', 'Отрицательный'), ('neutral', 'Нейтральный')], default='neutral', max_length=30),
),
]

@ -1,23 +1,55 @@
from django.db import models from django.db import models
from django.core.validators import MaxValueValidator, MinValueValidator from django.core.urlresolvers import reverse
from django.utils import timezone
TYPE_REVIEWS = (
('positive', 'Положительный'),
('negative', 'Отрицательный'),
('neutral', 'Нейтральный'),
)
class Review(models.Model): class Review(models.Model):
project = models.ForeignKey('projects.Project', related_name='reviews') project = models.ForeignKey('projects.Project', related_name='reviews')
stars = models.IntegerField(validators=[MinValueValidator(1), MaxValueValidator(5)]) type = models.CharField(max_length=30, choices=TYPE_REVIEWS, default='neutral')
text = models.TextField() text = models.TextField()
created = models.DateTimeField(default=timezone.now)
target_customer = models.ForeignKey('users.User', related_name='reviews_by_contractor', null=True, blank=True) target_customer = models.ForeignKey('users.User', related_name='reviews_by_contractor', null=True, blank=True)
target_contractor = models.ForeignKey('users.User', related_name='reviews_by_customer', null=True, blank=True) target_contractor = models.ForeignKey('users.User', related_name='reviews_by_customer', null=True, blank=True)
target_team = models.ForeignKey('users.Team', related_name='reviews_by_team', null=True, blank=True)
from_customer = models.ForeignKey('users.User', related_name='contractor_reviews', null=True, blank=True) from_customer = models.ForeignKey('users.User', related_name='contractor_reviews', null=True, blank=True)
from_contractor = models.ForeignKey('users.User', related_name='customer_reviews', null=True, blank=True) from_contractor = models.ForeignKey('users.User', related_name='customer_reviews', null=True, blank=True)
from_team = models.ForeignKey('users.Team', related_name='team_reviews', null=True, blank=True)
def __str__(self): def __str__(self):
return str(self.pk) return str(self.pk)
def get_absolute_url(self):
return reverse('reviews:detail', kwargs={'pk': self.pk})
def get_sender(self):
if not self.from_team is None:
return self.from_team.name
elif not self.from_customer is None:
return self.from_customer.username
else:
return self.from_contractor.username
def get_recipient(self):
if not self.target_team is None:
return self.target_team.name
elif not self.target_customer is None:
return self.target_customer.username
else:
return self.target_contractor.username
class Meta: class Meta:
verbose_name = 'Отзыв' verbose_name = 'Отзыв'
verbose_name_plural = 'Отзывы' verbose_name_plural = 'Отзывы'
unique_together = ( unique_together = (
('from_customer', 'target_contractor', 'project'), ('from_customer', 'target_contractor', 'project'),
('from_customer', 'target_team', 'project'),
('from_contractor', 'target_customer', 'project'), ('from_contractor', 'target_customer', 'project'),
('from_team', 'target_customer', 'project'),
) )

@ -0,0 +1,24 @@
from rest_framework.serializers import ModelSerializer
from .models import Review
from users.serializers import UserSerializer, TeamSerializer
class ReviewSerializer(ModelSerializer):
class Meta:
model = Review
fields = (
'text',
'type',
'created',
'project',
'from_customer',
'from_contractor',
'from_team',
'target_customer',
'target_contractor',
'target_team',
)

@ -0,0 +1,21 @@
<h1>Добавление отзыва</h1>
<form method="post">{% csrf_token %}
{{ form.errors }}
<p>
<div class="mail-block type-work-inset">
{% for id, name in form.type.field.choices %}
<input type="radio" value="{{ id }}" {% if form.type.value|int == id %}checked{% endif %}
name="{{ form.type.html_name }}">{{ name }}
{% endfor %}
</div>
</p>
<p>
{{ form.text }}
<input type="text" name="{{ form.project.html_name }}" value="" />
</p>
<input type="submit" value="Добавить"/>
</form>

@ -0,0 +1,41 @@
{% extends 'partials/base.html' %}
{% load staticfiles %}
{% load thumbnail %}
{% 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="galleryWork disTab">
{% for review in object_list %}
<div class="new-comm-44">
<div class="col-lg-12">
<p class="nameComm">
<a href="#">{{ review.get_sender }}</a>
</p>
{% if review.project.deal_type == 'secure_deal' %}
<span class="dateComm44">
Безопасная сделка
</span>
{% endif %}
<div class="stars box-sizing">
<a href="#">положительный отзыв</a>
</div>
<p class="textComm44">
{{ review.text }}
</p>
</div>
</div>
{% endfor %}
</div>
{% include 'partials/footer.html' %}
</div>
</div>
{% endblock %}

@ -0,0 +1,11 @@
from django.conf import urls
from .views import ReviewsView, ReviewCreateView
app_name = 'reviews'
urlpatterns = [
urls.url(r'^$', ReviewsView.as_view(), name='list'),
urls.url(r'^create/$', ReviewCreateView.as_view(), name='create'),
]

@ -1,3 +1,21 @@
from django.shortcuts import render from django.shortcuts import render
from django.contrib.auth.mixins import LoginRequiredMixin, PermissionRequiredMixin
from django.views.generic import ListView, CreateView, DeleteView
from .models import Review
from .forms import ReviewForm
# Create your views here.
class ReviewsView(LoginRequiredMixin, ListView):
login_url = '/users/login/'
model = Review
template_name = 'reviews_list.html'
class ReviewCreateView(CreateView):
model = Review
form_class = ReviewForm
template_name = 'review_create.html'
class ReviewDeleteView(DeleteView):
model = Review

@ -402,28 +402,28 @@
</div> </div>
<div id="tab14" class="tab-pane fade"> <div id="tab14" class="tab-pane fade">
<div class="new-comm-44">
{% for review in contractor.contractor_reviews.all %}
<div class="new-comm-44">
<div class="col-lg-12"> <div class="col-lg-12">
<p class="nameComm"> <p class="nameComm">
<a href="#">Иванов Петр Иванович</a> <a href="#">{{ review.get_sender }}</a>
</p> </p>
{% if review.project.deal_type == 'secure_deal' %}
<span class="dateComm44"> <span class="dateComm44">
Безопасная сделка Безопасная сделка
</span> </span>
{% endif %}
<div class="stars box-sizing"> <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>
<a href="#">положительный отзыв</a> <a href="#">положительный отзыв</a>
</div> </div>
<p class="textComm44"> <p class="textComm44">
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Aenean euismod bibendum {{ review.text }}
</p> </p>
</div> </div>
</div> </div>
{% endfor %}
</div> </div>
</div> </div>

@ -0,0 +1 @@
default_app_config = 'wallets.apps.WalletsConfig'

@ -3,3 +3,6 @@ from django.apps import AppConfig
class WalletsConfig(AppConfig): class WalletsConfig(AppConfig):
name = 'wallets' name = 'wallets'
def ready(self):
import wallets.signals

@ -3,7 +3,7 @@ from django.dispatch import receiver
from django.core.mail import send_mail, EmailMultiAlternatives from django.core.mail import send_mail, EmailMultiAlternatives
from django.template.loader import get_template, render_to_string from django.template.loader import get_template, render_to_string
from .models import WithDraw from .models import WithDraw, InvoiceHistory
@receiver(post_save, sender=WithDraw) @receiver(post_save, sender=WithDraw)
@ -18,3 +18,5 @@ def send_for_accountant(sender, instance, created, **kwargs):
html_content = get_template('send_for_accountant.html').render(ctx_dict) html_content = get_template('send_for_accountant.html').render(ctx_dict)
msg = EmailMultiAlternatives(subject, text_content, from_email, [to]) msg = EmailMultiAlternatives(subject, text_content, from_email, [to])
msg.send() msg.send()

Loading…
Cancel
Save