diff --git a/assets/js/chat.js b/assets/js/chat.js index e47ffb5..06fef1f 100644 --- a/assets/js/chat.js +++ b/assets/js/chat.js @@ -184,7 +184,6 @@ function dialog (message, yesCallback, notCallback) { $("a[href='#tab1']").trigger('click'); } - // Информация о заказе $(".messageBlock").on('click','.full-order-info', function (e) { e.preventDefault(); @@ -322,6 +321,7 @@ function dialog (message, yesCallback, notCallback) { // Вытащить сообщения для конактов $('.user-block').on('click', function () { + var newCount = parseInt($("#count-tab-contact").text()); var contactId = $(this).attr('data-id'); location.hash = '#user' + contactId; $("#contact-chat-form #recipentContactId").val(contactId); @@ -336,6 +336,9 @@ function dialog (message, yesCallback, notCallback) { var sumSenderRecipent = parseInt(userId) + parseInt(contactId); $("#message-chat-space").removeClass().addClass("contact-space" + sumSenderRecipent); + var currNewCount = parseInt($(".contact-count-" + sumSenderRecipent).text()); + var resCount = newCount - currNewCount; + $("#count-tab-contact").text(newCount - currNewCount); $(".contact-count-" + sumSenderRecipent).text(0); var docList = document.getElementById('documentSpace'); inbox.innerHTML = ''; @@ -758,6 +761,7 @@ function dialog (message, yesCallback, notCallback) { var related = $(e.relatedTarget); var relatedType = related.attr('data-review-type'); $('input[name="type"]').filter('[value="'+ relatedType+'"]').prop("checked", true); + $("#text-new").val(""); }); // Добавление отзыва @@ -776,15 +780,19 @@ function dialog (message, yesCallback, notCallback) { success: function (json) { console.log(json); $("#review-add").modal('hide'); - //socket.send_stages_approve({ - // "format_type": "approve_stages", - // "data": { - // "sender_id": userId, - // "recipent_id": '', - // "order_id": '', - // "msg": "Отзыв добавлен", - // } - //}); + $("#leaveReview").hide(); + var currOrder = json.project; + var currRecipent = json.target_user; + + socket.send_stages_approve({ + "format_type": "approve_stages", + "data": { + "sender_id": userId, + "recipent_id": currRecipent, + "order_id": currOrder, + "msg": "Отзыв добавлен", + } + }); }, error: function (e) { console.log('error'); @@ -792,6 +800,99 @@ function dialog (message, yesCallback, notCallback) { } }); }); + + // Нажимаем на кнопку архивные сообщения + $("#trashed-button").on('click',function(e){ + e.preventDefault(); + var state = $(this).attr('data-show'); + var trashedOrderHtml = ""; + + if (state == 'true') { + $(this).attr('data-show','false'); + $(this).text("Скрыть архивные заказы"); + + $("#archive-space").show(); + $("#show-archive-label").show(); + + //$.ajax({ + // url: '/api/orders/', + // type: 'GET', + // dataType: 'json', + // success: function (json) { + // console.log(json.results); + // $.each(json.results, function (i, v) { + // + // var temp = '
' + + // '

' + v.project.name + '

' + + // 'Исполнитель:'+ v.contractor_name +'

' + + // '' + + // 'Полное описание заказа
'; + // + // trashedOrderHtml += temp; + // }); + // $("#trashed-orders").html(trashedOrderHtml); + // + // }, + // error: function (e, jqxhr) { + // console.log(e); + // } + //}); + + }else { + $(this).attr('data-show','true'); + $(this).text("Показать архивные заказы"); + $("#archive-space").hide(); + $("#show-archive-label").hide(); + } + + + }); + + // Нажимаем на заказ в архмвных заказах + $(".messageBlock").on('click','.trashedOrderBlock',function(){ + $("#chat-order-add").css("display", "none"); + $('.order-block, .trashedOrderBlock').each(function () { + $(this).removeClass('orAct'); + }); + $(this).addClass('orAct'); + var inbox = document.getElementById('message-chat-order-space'); + var docList = document.getElementById('documentOrderSpace'); + inbox.innerHTML = ''; + docList.innerHTML = ''; + var orderId = $(this).attr('data-id'); + location.hash = '#order' + orderId; + + $.ajax({ + url: '/api/message', + type: 'GET', + data: {csrfmiddlewaretoken: csrftoken, 'order': orderId, 'team__isnull': 'true'}, + dataType: 'json', + success: function (json) { + $.each(json.results, function (i, v) { + var senderName = 'Вы'; + var className = 'youChat'; + + if (v.sender.id !== userId) { + senderName = v.sender.username; + className = ''; + } + + inbox.innerHTML += '
' + + '

' + senderName + '

' + v.created + '
' + + '

' + v.text + '

'; + + }); + var height = inbox.scrollHeight; + inbox.scrollTop = height; + } + }); + + $("#order-stages").html(""); + $("#completeWork").hide(); + $("#add-form-order-note").hide(); + $("#reserveSpace").hide(); + }); }); diff --git a/assets/js/chat_contractor.js b/assets/js/chat_contractor.js index 778baa0..a5227c9 100644 --- a/assets/js/chat_contractor.js +++ b/assets/js/chat_contractor.js @@ -78,6 +78,7 @@ $(function () { $(".stage-block-approve").each(function () { var stageId = $(this).attr('data-id'); $.ajax({ + //async: false, url: '/api/stages/' + stageId + '/', type: 'PATCH', beforeSend: function (xhr) { @@ -107,8 +108,20 @@ $(function () { } }); + $('body').append(''); + $('#popupOk').modal('show'); }.bind(orderId, senderId, recipentId), caption); + + }); // Отказаться от этапов @@ -348,6 +361,15 @@ $(function () { location.hash = '#order' + orderId; var recipentId = $(this).attr('data-recipent-id'); var projectId = $(this).attr('data-project-id'); + var teamCurrentId = parseInt($(this).attr('data-team-id')); + + if (teamCurrentId>0){ + $("#fromTeamId").val(teamCurrentId); + $("#fromContractorId").val(""); + }else { + $("#fromTeamId").val("") + $("#fromContractorId").val(userId); + } $("#chat-order-add #orderId").val(orderId); $("#add-form-order-note #orderNote").val(orderId); @@ -534,12 +556,15 @@ $(function () { } else { $("#completeWork").hide(); } - - if ((stagesCompleted.length == stagesResults.length) && stagesCompleted.length > 0 && !data.has_user_review) { + if (!data.has_user_review) { + if ((stagesCompleted.length == stagesResults.length) && stagesCompleted.length > 0) { $("#leaveReview").show(); - }else{ + } else { $("#leaveReview").hide(); } + }else{ + $("#leaveReview").hide(); + } }); diff --git a/assets/js/chat_customer.js b/assets/js/chat_customer.js index 988eeb7..bd8412d 100644 --- a/assets/js/chat_customer.js +++ b/assets/js/chat_customer.js @@ -46,6 +46,12 @@ $(function () { $("#choiceWayOrder").attr('data-stages-ids', stagesIds); + $("#stagesSelect").selectpicker({ + style: 'btn-info', + size: 4 + }); + + } }); @@ -213,7 +219,7 @@ $(function () { ''; if (stage.close_contractor) { - stageWork += '
Закрыть этап ' + stage.pos + '
'; } @@ -286,6 +292,7 @@ $(function () { $.ajax({ url: '/api/orders/' + currentOrderId + '/', type: 'PATCH', + beforeSend: function (xhr) { xhr.setRequestHeader("X-CSRFToken", getCookie('csrftoken')) }, @@ -305,6 +312,7 @@ $(function () { var _this = $(this); console.log($(this).serialize()); $.ajax({ + async: false, url: '/api/stages/', type: 'POST', beforeSend: function (xhr) { @@ -333,8 +341,9 @@ $(function () { $(".update-stages-form").each(function (i, v) { var _this = $(this); var currentStageId = parseInt($(this).attr('data-stage-id')); - console.log($(this).serialize()); + console.log($(this).serialize()); $.ajax({ + async: false, url: '/api/stages/' + currentStageId + '/', type: 'PUT', beforeSend: function (xhr) { @@ -367,7 +376,17 @@ $(function () { "msg": "Этапы для заказа " + currentOrderId + " изменены", } }); - $.jGrowl("Этапы для заказа изменены и отправлены исполнителю", { life: 15000}); + $('body').append(''); + $('#popupOk').modal('show'); + //$.jGrowl("Этапы для заказа изменены и отправлены исполнителю", { life: 15000}); }); @@ -410,97 +429,10 @@ $(function () { } }); - // Нажимаем на кнопку архивные сообщения - $("#trashed-button").on('click',function(e){ - e.preventDefault(); - var state = $(this).attr('data-show'); - var trashedOrderHtml = ""; - - if (state == 'true') { - $(this).attr('data-show','false'); - $(this).text("Скрыть архивные заказы"); - - $.ajax({ - url: '/api/orders/', - type: 'GET', - dataType: 'json', - success: function (json) { - console.log(json.results); - $.each(json.results, function (i, v) { - - var temp = '
' + - '

' + v.project.name + '

' + - 'Исполнитель:'+ v.contractor_name +'

' + - '' + - 'Полное описание заказа
'; - - trashedOrderHtml += temp; - }); - $("#trashed-orders").html(trashedOrderHtml); - - }, - error: function (e, jqxhr) { - console.log(e); - } - }); - - }else { - $(this).attr('data-show','true'); - $(this).text("Показать архивные заказы"); - $("#trashed-orders").html(""); - } - - - }); - - // Нажимаем на заказ в архмвных заказах - $(".messageBlock").on('click','.trashedOrderBlock',function(){ - $("#chat-order-add").css("display", "none"); - $('.order-block, .trashedOrderBlock').each(function () { - $(this).removeClass('orAct'); - }); - $(this).addClass('orAct'); - var inbox = document.getElementById('message-chat-order-space'); - var docList = document.getElementById('documentOrderSpace'); - inbox.innerHTML = ''; - docList.innerHTML = ''; - var orderId = $(this).attr('data-id'); - location.hash = '#order' + orderId; - - $.ajax({ - url: '/api/message', - type: 'GET', - data: {csrfmiddlewaretoken: csrftoken, 'order': orderId, 'team__isnull': 'true'}, - dataType: 'json', - success: function (json) { - $.each(json.results, function (i, v) { - var senderName = 'Вы'; - var className = 'youChat'; - - if (v.sender.id !== userId) { - senderName = v.sender.username; - className = ''; - } - - inbox.innerHTML += '
' + - '

' + senderName + '

' + v.created + '
' + - '

' + v.text + '

'; - - }); - var height = inbox.scrollHeight; - inbox.scrollTop = height; - } - }); - - $("#order-stages").html(""); - $("#completeWork").hide(); - $("#add-form-order-note").hide(); - $("#reserveSpace").hide(); - }); // Для заказов все вытащить $('.order-block').on('click', function () { + var newCount = parseInt($("#count-tab-order").text()); $("#chat-order-add").css("display", "block"); $("#add-form-order-note").css("display", "block"); $("#formsetStage").css("display", "block"); @@ -516,12 +448,22 @@ $(function () { var recipentId = $(this).attr('data-recipent-id'); var secureOrder = $(this).attr('data-secure-deal'); secureOrder = Boolean(secureOrder); + + var teamCurrentId = parseInt($(this).attr('data-team-id')); + + if (teamCurrentId>0){ + $("#targetTeamId").val(teamCurrentId); + $("#targetContractorId").val(""); + }else { + $("#targetTeamId").val("") + $("#targetContractorId").val(recipentId); + } $("#chat-order-add #orderId").val(orderId); $("#add-form-order-note #orderNote").val(orderId); $("#orderArbitrationId").val(orderId); $("#projectReviewId").val(projectId); $("#reserve-button").attr('data-order-id', orderId); - $("#targetContractorId").val(recipentId); + $("#chat-order-add #recipentId").val(recipentId); $("#add-form-order-note #recipentNote").val(recipentId); $(".orderStagesInput").val(orderId); diff --git a/chat/chat.py b/chat/chat.py index 57786f5..f7b9418 100644 --- a/chat/chat.py +++ b/chat/chat.py @@ -30,6 +30,7 @@ class ChatHandler(websocket.WebSocketHandler): # @gen.coroutine def on_message(self, message): parsed = escape.json_decode(message) + print(parsed) if 'dummy' in parsed: return diff --git a/chat/templates/chat_contractor.html b/chat/templates/chat_contractor.html index 75d7a3d..5507ba5 100644 --- a/chat/templates/chat_contractor.html +++ b/chat/templates/chat_contractor.html @@ -17,15 +17,15 @@ @@ -123,7 +123,7 @@

Заказы

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

{{ order }}

@@ -136,6 +136,39 @@
{% endfor %} + + + {% if archive_orders %} +
+ Показать архивные заказы +
+ + + {% endif %} diff --git a/chat/templates/chat_customer.html b/chat/templates/chat_customer.html index f95ad57..2856a66 100644 --- a/chat/templates/chat_customer.html +++ b/chat/templates/chat_customer.html @@ -15,10 +15,12 @@
@@ -27,13 +29,14 @@
{% include 'dialog_delete.html' %}
- +

Контакты

{% for contact in contacts_users %} -
+
{% if contact.avatar %} {% thumbnail contact.avatar "60x60" crop="center" as im %} @@ -44,11 +47,11 @@ {% endif %}

- {% if contact.is_contractor %} - {% url "users:contractor-profile" pk=contact.pk as contact_url %} - {% else %} - {% url "users:customer-profile-open-projects" pk=contact.pk as contact_url %} - {% endif %} + {% if contact.is_contractor %} + {% url "users:contractor-profile" pk=contact.pk as contact_url %} + {% else %} + {% url "users:customer-profile-open-projects" pk=contact.pk as contact_url %} + {% endif %}

@@ -69,17 +72,18 @@
- + - +
- -

Прикрепить файл

+ +

Прикрепить файл

- отправить + отправить
@@ -87,47 +91,51 @@
-

Прикрепленные документы

-
    -
- - Распечатать с помощью ресурса - -
+

Прикрепленные документы

+
    +
+ + Распечатать с помощью ресурса + +

Заметки

-

Для заметок

- - - - сохранить +

Для заметок

+ + + + сохранить
- {% include 'contact-info.html' %} + {% include 'contact-info.html' %}
- + - +

Заказы

{% for order in orders %} -
+ {% endif %} data-id="{{ order.order.id }}">

{{ order }}

@@ -144,21 +152,47 @@ Полное описание заказа - Удалить заказ - + Удалить заказ +
{% endfor %} - -

Архивные заказы

-
-
+ {% if archive_projects %} + + + + {% endif %} +
@@ -167,11 +201,12 @@ - +
- -

Прикрепить файл

+ +

Прикрепить файл

отправить @@ -198,44 +233,44 @@
    + Зарезервировать +
    -
    +
    - {% include 'reverse_stage_modal.html' %} + {% include 'reverse_stage_modal.html' %} -
    -

    3 / Выполнение работы

    -

    - Процесс выполнения задания в заказе до получения +

    +

    3 / Выполнение работы

    +

    + Процесс выполнения задания в заказе до получения заказчиком итогового результата работы. -

    +

    -
    +
    -

    Прикрепленные документы

    -
      - - Распечатать с помощью ресурса - -
      +

      Прикрепленные документы

      + + + Распечатать с помощью ресурса + +
      - + {% include 'partials/footer.html' %} @@ -275,11 +310,11 @@ {% block js_block %} - + {% endblock %} diff --git a/chat/templates/reverse_stage_modal.html b/chat/templates/reverse_stage_modal.html index 6cd9b82..92e2873 100644 --- a/chat/templates/reverse_stage_modal.html +++ b/chat/templates/reverse_stage_modal.html @@ -37,7 +37,7 @@
      -
      diff --git a/chat/templates/review_add_modal.html b/chat/templates/review_add_modal.html index 4c139ad..5435822 100644 --- a/chat/templates/review_add_modal.html +++ b/chat/templates/review_add_modal.html @@ -13,13 +13,13 @@
      {#
      #}
      - Положительный - Отрицательный - Нейтральный
      @@ -27,19 +27,19 @@

      Ваш отзыв

      {% if request.user.is_customer %} - + - + - + {% else %} - - + + - + {% endif %}
      diff --git a/chat/views.py b/chat/views.py index 7dde354..e78ab5f 100644 --- a/chat/views.py +++ b/chat/views.py @@ -55,7 +55,7 @@ class ChatUserView(LoginRequiredMixin, View): users_ids.append(int(user_id)) contacts_users = User.objects.filter(pk__in=users_ids) - + archive_projects = request.user.customer_projects.select_related('order').exclude(state='active') chat_messages = Message.objects.filter(Q(sender=request.user.pk) | Q(recipent=request.user.pk)) orders = request.user.customer_projects.select_related('order').filter(state='active').exclude(order__contractor__isnull=True, order__team__isnull=True) order_ids = [order.order.pk for order in orders] @@ -72,6 +72,7 @@ class ChatUserView(LoginRequiredMixin, View): 'chat_messages': chat_messages, 'contacts_users_count': contacts_users_count, 'orders_ms_count': orders_ms_count, + 'archive_projects': archive_projects, 'orders': orders, 'transaction': transaction[0], 'YANDEX_MONEY': settings.YANDEX_MONEY, @@ -86,7 +87,8 @@ class ChatUserView(LoginRequiredMixin, View): teams = Team.objects.filter(contractors__id=request.user.pk).all() team_orders = Order.objects.filter(team_id__in=[team.pk for team in teams]).all() - orders = Order.objects.filter(Q(contractor=request.user) | Q(team_id__in=team_ids)).filter(project__state='active').all() + orders = Order.objects.filter(Q(contractor=request.user) | Q(team_id__in=team_ids)).filter(project__state='active') + archive_orders = Order.objects.filter(Q(contractor=request.user) | Q(team_id__in=team_ids)).exclude(project__state='active') contractor_contacts = Message.objects.values_list('sender_id', 'recipent_id').filter( Q(recipent_id=request.user.pk) | Q(sender_id=request.user.pk)).filter(Q(team_id=None)).\ filter(is_delete=False).distinct() @@ -113,7 +115,6 @@ class ChatUserView(LoginRequiredMixin, View): orders_ms_count = request.user.new_messages.filter(message__order__in=orders, message__team__isnull=True).count() teams_ms_count = request.user.new_messages.filter(message__team__in=your_teams, message__order__isnull=True).count() - self.template_name = 'chat_contractor.html' return render(request, self.template_name, {'orders': orders, 'contacts_users': contacts_users, @@ -123,7 +124,7 @@ class ChatUserView(LoginRequiredMixin, View): 'chat_messages': chat_messages, 'team_orders': team_orders, 'your_teams': your_teams, - + 'archive_orders': archive_orders, }) diff --git a/reviews/serializers.py b/reviews/serializers.py index edaa702..e985c86 100644 --- a/reviews/serializers.py +++ b/reviews/serializers.py @@ -1,15 +1,18 @@ from rest_framework.serializers import ModelSerializer +from rest_framework import serializers from .models import Review from users.serializers import UserSerializer, TeamSerializer class ReviewSerializer(ModelSerializer): + target_user = serializers.SerializerMethodField(read_only=True) class Meta: model = Review fields = ( + 'id', 'text', 'type', 'created', @@ -20,5 +23,14 @@ class ReviewSerializer(ModelSerializer): 'target_customer', 'target_contractor', 'target_team', + 'target_user', ) + def get_target_user(self, obj): + if obj.target_customer: + return obj.target_customer.pk + elif obj.target_contractor: + return obj.target_contractor.pk + elif obj.target_team: + return obj.target_team.owner.pk + diff --git a/users/templatetags/user_tags.py b/users/templatetags/user_tags.py index 49d3e23..630c813 100644 --- a/users/templatetags/user_tags.py +++ b/users/templatetags/user_tags.py @@ -68,3 +68,18 @@ def get_new_count_for_contact(contact, current_user): return count +@register.simple_tag +def get_new_count_for_order(current_user, order_id): + count = current_user.new_messages.filter(message__order=order_id, message__team__isnull=True).count() + return count + + +@register.simple_tag +def get_new_count_for_team(current_user, team_id, order_id=None): + if order_id: + count = current_user.new_messages.filter(message__order=order_id, message__team=team_id).count() + else: + count = current_user.new_messages.filter(message__order__isnull=True, message__team=team_id).count() + return count + +