diff --git a/api/views.py b/api/views.py index 4c816c0..0ce545b 100755 --- a/api/views.py +++ b/api/views.py @@ -117,7 +117,7 @@ class MessageViewSet(ModelViewSet): filter_class = MessageFilterSet def get_queryset(self): - queryset = Message.objects.all() + queryset = Message.objects.filter(is_delete=False) search_param = self.request.query_params.get('operand', None) recipent_id = self.request.query_params.get('recipent_id', None) sender_id = self.request.query_params.get('sender_id', None) diff --git a/assets/css/main.css b/assets/css/main.css index c791120..14ab808 100644 --- a/assets/css/main.css +++ b/assets/css/main.css @@ -213,14 +213,14 @@ ul li { } .changeBlock1 { - float: right; - margin-right: -15px; + float: left; + margin-left: -15px; background-color: rgba(0,0,0,0.7); } .changeBlock2 { - float: left; - margin-left: -15px; + float: right; + margin-right: -15px; background-color: rgba(255,0,6,0.7); } @@ -5966,4 +5966,4 @@ a.linkS2[data-target="#withdraw-money"]{ input[type="radio"]{ opacity: 0; } -/*end_new*/ \ No newline at end of file +/*end_new*/ diff --git a/assets/js/chat.js b/assets/js/chat.js index 8072b98..dc5dfb4 100644 --- a/assets/js/chat.js +++ b/assets/js/chat.js @@ -15,6 +15,8 @@ var SocketHandler = function () { var message = JSON.parse(event.data); var inbox; if (message.answer_type == 'contact' || message.answer_type == 'add_message_contact') { + var docSpace = document.getElementById('documentSpace'); + docSpace.innerHTML += message.docs_attach; var sumSenderRecipent = parseInt(message.recipent_id) + parseInt(message.sender_id); var inboxClass = document.getElementsByClassName('contact-space' + sumSenderRecipent); if (inboxClass.length > 0) { @@ -24,8 +26,12 @@ var SocketHandler = function () { } } else if (message.answer_type == 'order' || message.answer_type == 'add_message_order') { inbox = document.getElementById('message-chat-order-space'); + var docOrderSpace = document.getElementById('documentOrderSpace'); + docOrderSpace.innerHTML += message.docs_attach; } else if (message.answer_type == 'add_message_team') { inbox = document.getElementById('message-chat-team-space'); + var docSpace = document.getElementById('documentTeamSpace'); + docSpace.innerHTML += message.docs_attach; } else if (message.answer_type == 'approve_stages') { var resOrderId = message.order_id; $.jGrowl(message.msg, { @@ -73,6 +79,21 @@ var socket = new SocketHandler(); var csrftoken = getCookie('csrftoken'); $(function () { + + function dialog(message, yesCallback, notCallback) { + $("#dialog_delete .modal-title").html(message); + var dialog = $("#dialog_delete").modal('show'); + $("#btnYes").click(function () { + yesCallback(); + $("#dialog_delete").modal('hide'); + }); + $("#btnNot").click(function () { + notCallback(); + $("#dialog_delete").modal('hide'); + }); + } + + var currentHash = URI(location.href).hash(); if (currentHash.indexOf("#order") == 0) { var ordHashId = currentHash.replace("#order", ""); @@ -90,7 +111,7 @@ $(function () { $(".order-block").first().trigger('click'); }, 500); } - + // Информация о заказе $(".full-order-info").click('on', function (e) { e.preventDefault(); e.stopPropagation(); @@ -131,23 +152,23 @@ $(function () { dataType: 'json', success: function (data) { var outTable = ''; - if(data.username) { + if (data.username) { outTable += 'Ник' + data.username + ''; } - if(data.fio) { + if (data.fio) { outTable += 'Ф.И.О' + data.fio + ''; } - if(data.skype) { - outTable += 'Skype'+ data.skype +''; + if (data.skype) { + outTable += 'Skype' + data.skype + ''; } - if(data.website) { - outTable += 'Сайт'+ data.website +''; + if (data.website) { + outTable += 'Сайт' + data.website + ''; } - if(data.phone) { - outTable += 'Телефон'+ data.phone +''; + if (data.phone) { + outTable += 'Телефон' + data.phone + ''; } $("#contact-info table").html(outTable); @@ -303,33 +324,42 @@ $(function () { }); - $('.deleteMess').on('click', function (e) { e.preventDefault(); e.stopPropagation(); + var senderId = userId; var recipentId = $(this).attr('data-recipent-id'); var _this = $(this); - $.ajax({ - url: '/chat/messages_delete/', - type: 'POST', - beforeSend: function (xhr) { - xhr.setRequestHeader("X-CSRFToken", getCookie('csrftoken')) - }, - data: {'sender_id': senderId, 'recipent_id': recipentId}, - dataType: 'json', - success: function (json) { - if (json.status == 'ok') { - _this.parent().remove(); - $("#message-chat-space").html(""); - } - }, - error: function (e) { - console.log('error'); - console.log(e); - } - }); + dialog("Вы действительно хотите удалить сообщения этого пользователя?", + function(){ + $.ajax({ + url: '/chat/messages_delete/', + type: 'POST', + beforeSend: function (xhr) { + xhr.setRequestHeader("X-CSRFToken", getCookie('csrftoken')) + }, + data: {'sender_id': senderId, 'recipent_id': recipentId}, + dataType: 'json', + success: function (json) { + + if (json.status == 'ok') { + _this.parent().remove(); + $("#message-chat-space").html(""); + } + + }, + error: function (e) { + console.log('error'); + console.log(e); + } + }); + }.bind(null, senderId, recipentId, _this), + function () { + }); + + }); $('#add-note-contractor').on('click', function (e) { @@ -366,7 +396,7 @@ $(function () { data: $("#add-form-order-note").serialize(), dataType: 'json', success: function (json) { - $("
  • "+ json.text +"
  • ").appendTo(".order-notes-block"); + $("
  • " + json.text + "
  • ").appendTo(".order-notes-block"); $("#add-form-order-note #chat2").val(""); }, error: function (e) { @@ -388,7 +418,7 @@ $(function () { data: $("#add-form-team-note").serialize(), dataType: 'json', success: function (json) { - $("
  • "+ json.text +"
  • ").appendTo(".team-notes-block"); + $("
  • " + json.text + "
  • ").appendTo(".team-notes-block"); $("#add-form-team-note #chat2").val(""); }, error: function (e) { @@ -409,8 +439,14 @@ $(function () { if (chatMessage) { var sendLinks = $("#document-send-order a"); var sendLinkIds = ""; + var documentLinks = ""; + var documentAttachFiles = ""; $.each(sendLinks, function (i, v) { sendLinkIds += $(this).attr('data-id') + ';'; + documentLinks += 'Входящий файл:
    '+ $(this).text() +'
    '; + documentAttachFiles += '
  • ' + + '' + $(this).text() + '' + + '
  • '; }); socket.send_message({ "format_type": "add_message_order", @@ -420,6 +456,10 @@ $(function () { "chat_message": chatMessage, "order_id": orderId, "document_send_links": sendLinkIds, + "document_data": { + "document_links": documentLinks, + "document_attach_files": documentAttachFiles, + } } }); @@ -441,8 +481,15 @@ $(function () { $("#contact-chat-form .errorEmptyMessage").hide(); var sendLinks = $("#document-send-contact a"); var sendLinkIds = ""; + var documentLinks = ""; + var documentAttachFiles = ""; + $.each(sendLinks, function (i, v) { sendLinkIds += $(this).attr('data-id') + ';'; + documentLinks += 'Входящий файл:
    '+ $(this).text() +'
    '; + documentAttachFiles += '
  • ' + + '' + $(this).text() + '' + + '
  • '; }); console.log(sendLinkIds); socket.send_message({ @@ -452,6 +499,10 @@ $(function () { "recipent_id": recipentId, "chat_message": chatMessage, "document_send_links": sendLinkIds, + "document_data": { + "document_links": documentLinks, + "document_attach_files": documentAttachFiles, + } } }); $("#chat").val(""); @@ -541,10 +592,7 @@ $(function () { dataType: 'json', done: function (e, data) { $.each(data.result.files, function (index, file) { - // var currentValue = ''; - // currentValue += file.id + ';'; - //$("#documentSendIds").val(currentValue); - var htmlImg = '' + file.name + '
    '; + var htmlImg = '' + file.name + '
    '; var document_send = $(htmlImg).appendTo("#document-send-order"); }); }, @@ -587,7 +635,7 @@ $(function () { dataType: 'json', done: function (e, data) { $.each(data.result.files, function (index, file) { - var htmlImg = '' + file.name + ''; + var htmlImg = '' + file.name + ''; var document_send = $(htmlImg).appendTo("#document-send-contact"); }); }, diff --git a/assets/js/chat_contractor.js b/assets/js/chat_contractor.js index fd7d13a..1a8b382 100644 --- a/assets/js/chat_contractor.js +++ b/assets/js/chat_contractor.js @@ -35,7 +35,7 @@ $(function () { var currentValue = $("#documentSendIds").val(); currentValue += file.id + ';'; $("#documentSendIds").val(currentValue); - var htmlImg = '' + file.name + ''; + var htmlImg = '' + file.name + ''; var document_send = $(htmlImg).appendTo("#document-send"); }); }, @@ -544,8 +544,15 @@ $(function () { if (chatMessage) { var sendLinks = $("#document-send a"); var sendLinkIds = ""; + var documentLinks = ""; + var documentAttachFiles = ""; $.each(sendLinks, function (i, v) { sendLinkIds += $(this).attr('data-id') + ';'; + documentLinks += 'Входящий файл:
    '+ $(this).text() +'
    '; + documentAttachFiles += '
  • ' + + '' + $(this).text() + '' + + '
  • '; + }); socket.send_message({ "format_type": "add_message_team", @@ -556,6 +563,10 @@ $(function () { "team_id": teamId, "order_id": orderId, "document_send_links": sendLinkIds, + "document_data": { + "document_links": documentLinks, + "document_attach_files": documentAttachFiles, + } } }); diff --git a/chat/chat.py b/chat/chat.py index 79b38ad..c3d2f4a 100644 --- a/chat/chat.py +++ b/chat/chat.py @@ -61,6 +61,12 @@ class ChatHandler(websocket.WebSocketHandler): team_id = message_data['data'].get('team_id', None) message = message_data['data'].get('chat_message', None) docs_send_links = message_data['data'].get('document_send_links', None) + if 'document_data' in message_data['data']: + docs_links = message_data['data']['document_data'].get('document_links', ""); + docs_attach = message_data['data']['document_data'].get('document_attach_files', "") + else: + docs_links = '' + docs_attach = '' message = html.escape(message) message = message.replace('\n', '
    ') @@ -100,10 +106,20 @@ class ChatHandler(websocket.WebSocketHandler): msg_data = cursor_msg.fetchone() sender_name = msg_data[5] msg_time = msg_data[2].strftime("%Y-%m-%d %H:%M:%S") + if docs_links: + message += '

    ' + docs_links; 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': message, 'msg_time': msg_time, 'order_id': order_id, 'recipent_id': recipent_id,'sender_id': sender_id, 'sender_name': sender_name, 'answer_type': answer_type}) + waiter.write_message({'msg': message, + 'msg_time': msg_time, + 'order_id': order_id, + 'recipent_id': recipent_id, + 'sender_id': sender_id, + 'sender_name': sender_name, + 'answer_type': answer_type, + 'docs_attach': docs_attach, + }) def check_origin(self, origin): return True diff --git a/chat/templates/chat_contractor.html b/chat/templates/chat_contractor.html index a644ad9..4e15818 100644 --- a/chat/templates/chat_contractor.html +++ b/chat/templates/chat_contractor.html @@ -31,7 +31,7 @@ - + {% include 'dialog_delete.html' %}
    diff --git a/chat/templates/chat_customer.html b/chat/templates/chat_customer.html index d4df7cb..41aed75 100644 --- a/chat/templates/chat_customer.html +++ b/chat/templates/chat_customer.html @@ -23,6 +23,7 @@
    + {% include 'dialog_delete.html' %}
    diff --git a/chat/templates/dialog_delete.html b/chat/templates/dialog_delete.html new file mode 100644 index 0000000..d030d91 --- /dev/null +++ b/chat/templates/dialog_delete.html @@ -0,0 +1,16 @@ + diff --git a/chat/views.py b/chat/views.py index ba30f68..6ffe399 100644 --- a/chat/views.py +++ b/chat/views.py @@ -77,7 +77,8 @@ class ChatUserView(LoginRequiredMixin, View): orders = Order.objects.filter(Q(contractor=request.user) | Q(team_id__in=team_ids)).all() 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)).distinct() + Q(recipent_id=request.user.pk) | Q(sender_id=request.user.pk)).filter(Q(team_id=None)).\ + filter(is_delete=False).distinct() users_ids = [] for msg in contractor_contacts: a, b = msg @@ -106,8 +107,8 @@ def messages_delete(request): sender = request.POST.get('sender_id') recipent = request.POST.get('recipent_id') queryset = Message.objects.all() - # queryset = queryset.filter(Q(sender__in=[sender,recipent]),Q(recipent__in=[sender,recipent])) - # queryset.delete() + queryset = queryset.filter(Q(sender__in=[sender, recipent]), Q(recipent__in=[sender, recipent])) + queryset.update(is_delete=True) data = {'status': 'ok'} return HttpResponse(json.dumps(data), content_type='application/json') else: diff --git a/projects/apps.py b/projects/apps.py index 5c57f09..95e9770 100644 --- a/projects/apps.py +++ b/projects/apps.py @@ -5,5 +5,6 @@ from django.apps import AppConfig class ProjectsConfig(AppConfig): name = 'projects' - + def ready(self): + import projects.signals diff --git a/projects/migrations/0028_stage_approve_time.py b/projects/migrations/0028_stage_approve_time.py new file mode 100644 index 0000000..61af72e --- /dev/null +++ b/projects/migrations/0028_stage_approve_time.py @@ -0,0 +1,23 @@ +# -*- coding: utf-8 -*- +# Generated by Django 1.9.7 on 2016-09-08 08:17 +from __future__ import unicode_literals + +import datetime +from django.db import migrations, models +from django.utils.timezone import utc + + +class Migration(migrations.Migration): + + dependencies = [ + ('projects', '0027_auto_20160907_1658'), + ] + + operations = [ + migrations.AddField( + model_name='stage', + name='approve_time', + field=models.DateTimeField(default=datetime.datetime(2016, 9, 8, 8, 17, 17, 715320, tzinfo=utc)), + preserve_default=False, + ), + ] diff --git a/projects/migrations/0029_auto_20160908_1159.py b/projects/migrations/0029_auto_20160908_1159.py new file mode 100644 index 0000000..ec83334 --- /dev/null +++ b/projects/migrations/0029_auto_20160908_1159.py @@ -0,0 +1,20 @@ +# -*- coding: utf-8 -*- +# Generated by Django 1.9.7 on 2016-09-08 08:59 +from __future__ import unicode_literals + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('projects', '0028_stage_approve_time'), + ] + + operations = [ + migrations.AlterField( + model_name='stage', + name='approve_time', + field=models.DateTimeField(blank=True, null=True), + ), + ] diff --git a/projects/models.py b/projects/models.py index ccf519c..aa8c6b3 100644 --- a/projects/models.py +++ b/projects/models.py @@ -258,6 +258,7 @@ class Stage(models.Model): term_type = models.CharField(max_length=10, choices=TERM_TYPES, default='hour') status = models.CharField(choices=STATUSES, max_length=30, default='not_agreed') created = models.DateTimeField(default=timezone.now) + approve_time = models.DateTimeField(null=True, blank=True) pos = models.IntegerField(default=0, null=True, blank=True) is_paid = models.BooleanField(default=False) close_contractor = models.BooleanField(default=False) diff --git a/projects/signals.py b/projects/signals.py index b056dda..9a84217 100644 --- a/projects/signals.py +++ b/projects/signals.py @@ -1,8 +1,12 @@ from django.core.signals import request_finished +from django.db.models.signals import post_save +from django.utils import timezone from django.dispatch import receiver -from .models import Project +from .models import Stage -@receiver(request_finished) -def add_project_test(sender, **kwargs): - pr = Project.objects.create(name='Test', price=100, user=2, spec=2) - pr.save() \ No newline at end of file + +@receiver(post_save, sender=Stage) +def set_approve_time(sender, instance, created, **kwargs): + if instance.status == 'in_process' and not instance.approve_time: + instance.approve_time = timezone.now() + instance.save() diff --git a/templates/home.html b/templates/home.html index 44fded1..a0f08a1 100644 --- a/templates/home.html +++ b/templates/home.html @@ -12,33 +12,35 @@
    -
    -
    - {% if request.user.is_authenticated and request.user.is_contractor %} - Я исполнитель +
    +
    + {% if request.user.is_authenticated and request.user.is_customer %} + Я заказчик {% else %} - Я исполнитель + Я заказчик {% endif %}

    - {{ main_settings.contractor_text|safe }} + {{ main_settings.customer_text|safe }}

    -
    +
    -
    - {% if request.user.is_authenticated and request.user.is_customer %} - Я заказчик +
    + {% if request.user.is_authenticated and request.user.is_contractor %} + Я исполнитель {% else %} - Я заказчик + Я исполнитель {% endif %}

    - {{ main_settings.customer_text|safe }} + {{ main_settings.contractor_text|safe }}

    +
    +
    diff --git a/templates/partials/base.html b/templates/partials/base.html index 4c32a99..ae06041 100644 --- a/templates/partials/base.html +++ b/templates/partials/base.html @@ -96,6 +96,7 @@ sock.send('{"dummy": 1}'); }, 15000); }; + sock.onmessage = function (event) { var notificationData = JSON.parse(event.data); console.log(notificationData); @@ -108,7 +109,6 @@ $.jGrowl("Вам пришло новое сообщение!
    " + outMessage, { life: 15000}); }; - this.add_message = function (messageData) { sock.send(JSON.stringify(messageData)); }; @@ -116,7 +116,6 @@ }; var userId = '{{ request.user.pk }}'; - if (userId) { var socketMain = new SocketHandlerMain(userId); }