From bfcecd3031414e626aae6a3be68b9dc10ed0ca23 Mon Sep 17 00:00:00 2001 From: Mukhtar Date: Thu, 25 Aug 2016 19:11:22 +0300 Subject: [PATCH] #ARC-18 add complete work --- api/urls.py | 2 + api/views.py | 15 +++- assets/js/chat.js | 7 +- chat/chat.py | 4 +- chat/templates/chat_contractor.html | 128 +++++++++++++++++++--------- chat/templates/chat_customer.html | 113 ++++++++++++++---------- projects/serializers.py | 33 ++++--- 7 files changed, 196 insertions(+), 106 deletions(-) diff --git a/api/urls.py b/api/urls.py index 9b19b2c..6fc2a21 100755 --- a/api/urls.py +++ b/api/urls.py @@ -17,6 +17,7 @@ from .views import ( StageViewSet, TeamViewSet, UserViewSet, + OrderViewSet, ) @@ -32,6 +33,7 @@ router.register(r'note', NoteViewSet) router.register(r'portfolio-photos', PortfolioPhotoViewSet) router.register(r'portfolios', PortfolioViewSet) router.register(r'projects', ProjectViewSet) +router.register(r'orders', OrderViewSet) router.register(r'realties', RealtyViewSet) router.register(r'reviews', ReviewViewSet) router.register(r'specializations', SpecializationViewSet) diff --git a/api/views.py b/api/views.py index 5c9909c..8e4c5fd 100755 --- a/api/views.py +++ b/api/views.py @@ -2,9 +2,12 @@ from django.db.models import Q from rest_framework.viewsets import ModelViewSet from rest_framework import permissions -from projects.models import Project, Realty, Stage, Portfolio, PortfolioPhoto, Answer, AnswerFile -from projects.serializers import ProjectSerializer, RealtySerializer, StageSerializer, PortfolioSerializer, PortfolioPhotoSerializer, AnswerSerializer, AnswerFileSerializer -from projects.filters import ProjectFilterSet, RealtyFilterSet, StageFilterSet, PortfolioFilterSet, PortfolioPhotoFilterSet +from projects.models import Project, Realty, Stage, Portfolio, PortfolioPhoto, Answer, AnswerFile, Order +from projects.serializers import (ProjectSerializer, RealtySerializer, StageSerializer, + PortfolioSerializer, PortfolioPhotoSerializer, AnswerSerializer, + OrderSerializer, AnswerFileSerializer,) +from projects.filters import (ProjectFilterSet, RealtyFilterSet, StageFilterSet, PortfolioFilterSet, + OrderFilterSet, PortfolioPhotoFilterSet,) from specializations.models import Specialization from specializations.serializers import SpecializationSerializer @@ -108,6 +111,12 @@ class RealtyViewSet(ModelViewSet): filter_class = RealtyFilterSet +class OrderViewSet(ModelViewSet): + queryset = Order.objects.all() + serializer_class = OrderSerializer + filter_class = OrderFilterSet + + class SpecializationViewSet(ModelViewSet): try: # TODO: dirty queryset = Specialization.objects.root_nodes()[0].get_descendants() diff --git a/assets/js/chat.js b/assets/js/chat.js index d8e0883..647b0aa 100644 --- a/assets/js/chat.js +++ b/assets/js/chat.js @@ -1,6 +1,6 @@ var SocketHandler = function () { domain = domain.replace(':' + port, ''); - var url = 'ws://' + domain + '/chat/' + userId + '/'; + var url = 'ws://' + domain + ':8888/chat/' + userId + '/'; var sock = new WebSocket(url); var intervalId; sock.onopen = function () { @@ -20,6 +20,11 @@ var SocketHandler = function () { } else if (message.answer_type == 'add_message_team') { inbox = document.getElementById('message-chat-team-space'); } else if (message.answer_type == 'approve_stages') { + var resOrderId = message.order_id; + $.jGrowl(message.msg,{life: 2000}); + setTimeout(function () { + $("#orderBlock" + resOrderId).trigger('click'); + }, 2000); console.log('approve stages'); } if (inbox) { diff --git a/chat/chat.py b/chat/chat.py index 84897e0..53fc19c 100644 --- a/chat/chat.py +++ b/chat/chat.py @@ -43,14 +43,14 @@ class ChatHandler(websocket.WebSocketHandler): @gen.coroutine def approve_stages(self, data): - print(data) sender_id = data['data']['sender_id'] recipent_id = data['data']['recipent_id'] order_id = data['data'].get('order_id') + message = data['data'].get('msg', 'Этапы обновлены') answer_type = data['format_type'] waiters = tuple(w for c, w in self.waiters if c == recipent_id or c == sender_id) for waiter in waiters: - waiter.write_message({'msg': 'Этапы обновлены', 'answer_type': answer_type}) + waiter.write_message({'msg': message, 'order_id': order_id, 'answer_type': answer_type}) @gen.coroutine def add_message(self, message_data): diff --git a/chat/templates/chat_contractor.html b/chat/templates/chat_contractor.html index 2d62b6f..e288b81 100644 --- a/chat/templates/chat_contractor.html +++ b/chat/templates/chat_contractor.html @@ -108,7 +108,7 @@

Заказы

{% for order in orders %}
+ id="orderBlock{{ order.id }}" data-recipent-id="{{ order.project.customer.pk }}" data-id="{{ order.id }}">

{{ order }}

@@ -147,16 +147,17 @@

1 / Согласование условий

- Обсуджение задания и условий выполнения работы. Подтверждение заказа исполнителем. + Обсуджение задания и условий выполнения работы. + Подтверждение заказа исполнителем.

-
+ @@ -293,6 +294,7 @@ var url = '/work_sell/basic/'; + //Загрузка документов $('#upload-document-team').fileupload({ url: url, crossDomain: false, @@ -325,12 +327,11 @@ }).prop('disabled', !$.support.fileInput) .parent().addClass($.support.fileInput ? undefined : 'disabled'); - + // Согласование этапов $("#order-stages").on('click', "#approve-stages", function (e) { e.preventDefault(); $(".stage-block-approve").each(function () { var stageId = $(this).attr('data-id'); - $.ajax({ url: '/api/stages/' + stageId + '/', type: 'PATCH', @@ -341,6 +342,7 @@ dataType: 'json', success: function (json) { console.log(json); + }, error: function (e) { console.log('error'); @@ -349,6 +351,18 @@ }); }); + var orderId = $(this).attr('data-order-id'); + + socket.send_stages_approve({ + "format_type": "approve_stages", + "data": { + "sender_id": $(this).attr('data-sender-id'), + "recipent_id": $(this).attr('data-recipent-id'), + "order_id": orderId, + "msg": "Исполнитель согласовал этапы для заказа " + orderId, + } + }); + }); $(".team-chat-user").on('click', function (e) { @@ -449,57 +463,80 @@ }); $.ajax({ - url: '/api/stages/', - type: 'GET', - data: {csrfmiddlewaretoken: csrftoken, 'order': orderId}, - dataType: 'json', - success: function (json) { - console.log(json.results); - var htmlInbox = ""; - var stagesReservedHtml = ""; - var stagesPaidProcess = []; - if (json.results.length > 0) { - - $.each(json.results, function (i, v) { + url:'/api/orders/' + orderId + '/', + type: 'GET', + data:{csrfmiddlewaretoken: csrftoken}, + dataType: 'json', + + }).then(function(data){ + var htmlInbox = ""; + var stagesReservedHtml = ""; + var stagesPaidProcess = []; + var stagesInWork = []; + var stagesResults = data.stages; + var statusNotAgreed = false; + if (stagesResults.length > 0) { + $.each(stagesResults, function (i, v) { + if(v.status == "not_agreed"){ + statusNotAgreed = true; + } + if(!data.secure){ + if(v.status == "in_process"){ + stagesInWork.push(v); - if ((v.status == "in_process") && (v.is_paid)){ - stagesPaidProcess.push(v); } - if (v.is_paid) { - stagesReservedHtml += '
  • Сумма за этап ' + v.pos + '.Зарезервирована.
  • '; - } else { - stagesReservedHtml += '
  • Сумма за этап ' + v.pos + '.Не зарезервирована.
  • '; - } - htmlInbox += '
    ' + + } else if ((v.status == "in_process") && (v.is_paid)){ + stagesPaidProcess.push(v); + stagesInWork.push(v); + } + + if (v.is_paid) { + stagesReservedHtml += '
  • Сумма за этап ' + v.pos + '.Зарезервирована.
  • '; + } else { + stagesReservedHtml += '
  • Сумма за этап ' + v.pos + '.Не зарезервирована.
  • '; + } + + htmlInbox += '
    ' + '

    Этап ' + v.pos + '' + v.name + '

    ' + '

    Результаты этапа:' + v.result + '

    ' + '

    ' + v.term + '

    ' + v.cost + '
    '; - }); - htmlInbox += ''; + }); + if (statusNotAgreed) { + htmlInbox += ''; } - $("#order-stages").html(htmlInbox); - $(".stages-paid").html(stagesReservedHtml); + } + + $("#order-stages").html(htmlInbox); + $(".stages-paid").html(stagesReservedHtml); - if (stagesPaidProcess.length > 0){ + if (stagesInWork.length > 0){ $("#completeWork").show(); - var stage = stagesPaidProcess[0]; + var stage = stagesInWork[0]; var stageWork = '

    В работе '+ stage.name +'

    ' + '

    Результат этапа : '+ stage.result +'

    ' + - '

    Срок сдачи 25.08.2016 ' + stage.cost + 'р.

    ' + - 'Завершить этап' + - 'Обратитьсяв арбитраж'; + '

    Срок сдачи '+ stage.term +' ' + stage.cost + 'р.

    '; + + if(!stage.close_contractor){ + stageWork += 'Завершить этап'; + }else{ + stageWork += '

    Этап ожидает завершения статуса от заказчика

    '; + } + stageWork += 'Обратитьсяв арбитраж'; $("#stagesWork").html(stageWork); - }else{ + }else{ $("#completeWork").hide(); - } - } }); + }); + //Добавить заметку. $('#add-note-button').on('click', function (e) { e.preventDefault(); $.ajax({ @@ -525,6 +562,7 @@ $('#tab2').on('click','.closeStage', function(e){ e.preventDefault(); var stageId = $(this).attr('data-stage-id'); + var _this = $(this); $.ajax({ url: '/api/stages/' + stageId + '/', type: 'PATCH', @@ -534,7 +572,17 @@ data: "close_contractor=True", dataType: 'json', success: function (json) { - alert(json); + + socket.send_stages_approve({ + "format_type": "approve_stages", + "data": { + "sender_id": _this.attr('data-sender-id'), + "recipent_id": _this.attr('data-recipent-id'), + "order_id": _this.attr('data-order-id'), + "msg": "Исполнитель завершил этап " + json.name, + } + }); + console.log(json); }, error: function (e) { diff --git a/chat/templates/chat_customer.html b/chat/templates/chat_customer.html index d9068f3..460d3c5 100644 --- a/chat/templates/chat_customer.html +++ b/chat/templates/chat_customer.html @@ -288,23 +288,22 @@ //Получить заказы function getStages(orderId, senderId, recipentId, secureOrder) { - $.ajax({ - url: '/api/stages/', - type: 'GET', - data: {csrfmiddlewaretoken: csrftoken, 'order': orderId}, - dataType: 'json', - success: function (json) { - var stageCount = json.results.length; + url:'/api/orders/' + orderId + '/', + type: 'GET', + data:{csrfmiddlewaretoken: csrftoken}, + dataType: 'json', + + }).then(function(data){ + var stagesResults = data.stages; + var stageCount = stagesResults.length; if (stageCount == 0) { $("#reserveSpace").hide(); stageCountVal = 1; } else { stageCountVal = stageCount; } - var htmlInbox = ""; - var htmlInboxStage = '

    Какое кол-во этапов подразумевает работа? ' + '

    '; @@ -320,13 +319,19 @@ '
    '; } var statusNotAgreed = true; + var stagesInWork = []; var stagesPaidProcess = []; - $.each(json.results, function (i, v) { - - if ((v.status == "in_process") && (v.is_paid)){ + $.each(stagesResults, function (i, v) { + if(!data.secure){ + if(v.status == "in_process") { + stagesInWork.push(v); + } + }else if ((v.status == "in_process") && (v.is_paid)){ + stagesInWork.push(v); stagesPaidProcess.push(v); } + if (v.status == "not_agreed") { htmlInbox += '
    ' + '

    Этап

    ' + @@ -349,8 +354,8 @@ }); if (statusNotAgreed) { - if(secureOrder) { - var orderSecureCheckbox = 'checked="checked"'; + if(!data.secure) { + var orderSecureCheckbox = ''; htmlInbox += '
    ' + '
    ' + 'Перейти в режим безопасной сделки
    '; @@ -360,28 +365,26 @@ 'отправить на согласование
    '; - }else if(json.results.length>0){ + }else if((stagesResults.length>0) && (data.secure)){ $("#reserveSpace").show(); } htmlInbox = htmlInboxStage + htmlInbox; $("#order-stages").html(htmlInbox); + $("#completeWork").hide(); - - if (stagesPaidProcess.length > 0){ + if(stagesInWork.length > 0){ $("#completeWork").show(); - var stage = stagesPaidProcess[0]; + var stage = stagesInWork[0]; var stageWork = '

    В работе '+ stage.name +'

    ' + '

    Результат этапа : '+ stage.result +'

    ' + '

    Срок сдачи 25.08.2016 ' + stage.cost + 'р.

    '; if (stage.close_contractor){ - stageWork += 'Закрыть этап '+ stage.pos +''; + stageWork += 'Закрыть этап '+ stage.pos +''; } $("#stagesWork").html(stageWork); - }else{ - $("#completeWork").hide(); } - } }); } @@ -389,6 +392,7 @@ $('#tab2').on('click','.closeStage', function(e){ e.preventDefault(); var stageId = $(this).attr('data-stage-id'); + var _this = $(this); $.ajax({ url: '/api/stages/' + stageId + '/', type: 'PATCH', @@ -398,6 +402,15 @@ data: {close_customer: true, status: 'completed'}, dataType: 'json', success: function (json) { + socket.send_stages_approve({ + "format_type": "approve_stages", + "data": { + "sender_id": _this.attr('data-sender-id'), + "recipent_id": _this.attr('data-recipent-id'), + "order_id": _this.attr('data-order-id'), + "msg": "Заказчик закрыл этап " + json.name, + } + }); console.log(json); }, error: function (e) { @@ -462,11 +475,14 @@ "sender_id": userId, "recipent_id": currentRecipentId, "order_id": currentOrderId, + "msg": "Этапы для заказа "+ currentOrderId +"изменены", } }); - setTimeout(function () { - getStages(currentOrderId,userId,currentRecipentId,secureOrder); - }, 1000); + +{# setTimeout(function () {#} +{# getStages(currentOrderId,userId,currentRecipentId,secureOrder);#} +{##} +{# }, 1000);#} }); @@ -474,33 +490,38 @@ $('#order-stages-tab').on('change', '#countStage', function () { var countStage = parseInt($(this).val()); var currentCountStage = $(".numberStepp").length; - - if (countStage > currentCountStage){ - for(var jj=currentCountStage; jjЭтап '+ pos +'

    ' + + if ((countStage<1) || isNaN(countStage)) { + countStage = 1; + $('#order-stages-tab #countStage').val(currentCountStage); + }else { + if (countStage > currentCountStage) { + for (var jj = currentCountStage; jj < countStage; jj++) { + var pos = jj + 1; + var lastFormStage = $(".numberStepp").last(); + var orderId = lastFormStage.find('.orderStagesInput').val(); + var addFormTemplate = '
    ' + + '

    Этап ' + pos + '

    ' + '' + '' + '' + '' + '' + - '' - '
    '; - lastFormStage.after(addFormTemplate); - } - - }else if (countStage < currentCountStage) { - var ii = currentCountStage; - $($(".numberStepp").get().reverse()).each(function(){ - var currenFormName = ($(this).find('form').attr('class')); - if(ii>countStage) { - $(this).remove(); + '' + '
    '; + lastFormStage.after(addFormTemplate); } - ii--; - }); + + } else if (countStage < currentCountStage) { + var ii = currentCountStage; + $($(".numberStepp").get().reverse()).each(function () { + var currenFormName = ($(this).find('form').attr('class')); + if (ii > countStage) { + $(this).remove(); + } + ii--; + }); + + } } }); diff --git a/projects/serializers.py b/projects/serializers.py index 0d8fa2e..0020da1 100755 --- a/projects/serializers.py +++ b/projects/serializers.py @@ -47,20 +47,6 @@ class RealtySerializer(ModelSerializer): ) -class OrderSerializer(ModelSerializer): - class Meta: - model = Order - - fields = ( - 'id', - 'contractor', - 'team', - 'created', - 'project', - 'secure', - 'status', - ) - class StageSerializer(ModelSerializer): # order = OrderSerializer() @@ -97,6 +83,25 @@ class StageSerializer(ModelSerializer): # return inst +class OrderSerializer(ModelSerializer): + stages = StageSerializer(many=True) + + class Meta: + model = Order + + fields = ( + 'id', + 'contractor', + 'team', + 'created', + 'project', + 'secure', + 'status', + 'stages', + ) + + + class ProjectSerializer(ModelSerializer): customer = UserSerializer() specialization = SpecializationSerializer()