#ARC-16 Fixes bugs

remotes/origin/PR-39
Mukhtar 9 years ago
parent 623efd676b
commit 26674349cd
  1. 2
      api/views.py
  2. 10
      assets/css/main.css
  3. 120
      assets/js/chat.js
  4. 13
      assets/js/chat_contractor.js
  5. 18
      chat/chat.py
  6. 2
      chat/templates/chat_contractor.html
  7. 1
      chat/templates/chat_customer.html
  8. 16
      chat/templates/dialog_delete.html
  9. 7
      chat/views.py
  10. 3
      projects/apps.py
  11. 23
      projects/migrations/0028_stage_approve_time.py
  12. 20
      projects/migrations/0029_auto_20160908_1159.py
  13. 1
      projects/models.py
  14. 14
      projects/signals.py
  15. 26
      templates/home.html
  16. 3
      templates/partials/base.html

@ -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)

@ -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*/
/*end_new*/

@ -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 += '<tr><td>Ник</td><td>' + data.username + '</td>';
}
if(data.fio) {
if (data.fio) {
outTable += '<tr><td>Ф.И.О</td><td>' + data.fio + '</td>';
}
if(data.skype) {
outTable += '<tr><td>Skype</td><td>'+ data.skype +'</td>';
if (data.skype) {
outTable += '<tr><td>Skype</td><td>' + data.skype + '</td>';
}
if(data.website) {
outTable += '<tr><td>Сайт</td><td>'+ data.website +'</td>';
if (data.website) {
outTable += '<tr><td>Сайт</td><td>' + data.website + '</td>';
}
if(data.phone) {
outTable += '<tr><td>Телефон</td><td>'+ data.phone +'</td>';
if (data.phone) {
outTable += '<tr><td>Телефон</td><td>' + data.phone + '</td>';
}
$("#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) {
$("<li>"+ json.text +"</li>").appendTo(".order-notes-block");
$("<li>" + json.text + "</li>").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) {
$("<li>"+ json.text +"</li>").appendTo(".team-notes-block");
$("<li>" + json.text + "</li>").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 += 'Входящий файл: <br> <a href="'+ $(this).attr('href') + '">'+ $(this).text() +'</a><br>';
documentAttachFiles += '<li style="word-break: break-all;">' +
'<a class="file-link" href="' + $(this).attr('href') + '">' + $(this).text() + '</a>' +
'<div class="remove-document" data-id="' + $(this).attr('data-id') + '" style="right:-10px;"></div></li>';
});
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 += 'Входящий файл: <br> <a href="'+ $(this).attr('href') + '">'+ $(this).text() +'</a><br>';
documentAttachFiles += '<li style="word-break: break-all;">' +
'<a class="file-link" href="' + $(this).attr('href') + '">' + $(this).text() + '</a>' +
'<div class="remove-document" data-id="' + $(this).attr('data-id') + '" style="right:-10px;"></div></li>';
});
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 = '<a href="' + file.url + '" class="send-doc" data-id="' + file.id + '">' + file.name + '</a><br />';
var htmlImg = '<a href="/chat/download/' + file.name + '" class="send-doc" data-id="' + file.id + '">' + file.name + '</a><br />';
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 = '<a href="' + file.url + '" class="send-doc" data-id="' + file.id + '">' + file.name + '</a>';
var htmlImg = '<a href="/chat/download/' + file.name + '" class="send-doc" data-id="' + file.id + '">' + file.name + '</a>';
var document_send = $(htmlImg).appendTo("#document-send-contact");
});
},

@ -35,7 +35,7 @@ $(function () {
var currentValue = $("#documentSendIds").val();
currentValue += file.id + ';';
$("#documentSendIds").val(currentValue);
var htmlImg = '<a href="' + file.url + '" class="send-doc" data-id="' + file.id + '">' + file.name + '</a>';
var htmlImg = '<a href="/chat/download/' + file.name + '" class="send-doc" data-id="' + file.id + '">' + file.name + '</a>';
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 += 'Входящий файл: <br> <a href="'+ $(this).attr('href') + '">'+ $(this).text() +'</a><br>';
documentAttachFiles += '<li style="word-break: break-all;">' +
'<a class="file-link" href="' + $(this).attr('href') + '">' + $(this).text() + '</a>' +
'<div class="remove-document" data-id="' + $(this).attr('data-id') + '" style="right:-10px;"></div></li>';
});
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,
}
}
});

@ -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', '<br />')
@ -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 += '<br><br>' + 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

@ -31,7 +31,7 @@
</div>
</div>
</div>
{% include 'dialog_delete.html' %}
<div class="tab-content">
<!-- Tab1 contacts block -->
<div class="chatBlock disTab tab-pane fade in active" id="tab1">

@ -23,6 +23,7 @@
</div>
</div>
</div>
{% include 'dialog_delete.html' %}
<div class="tab-content">
<!-- Tab1 (contacts block)-->
<div class="chatBlock disTab tab-pane fade in active" id="tab1">

@ -0,0 +1,16 @@
<div id="dialog_delete" class="modal fade" role="dialog">
<div class="modal-dialog" role="document" style="width:400px;">
<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-footer">
<button type="button" class="btn btn-danger btn-lg" id="btnNot">Нет</button>
<button type="button" class="btn btn-success btn-lg" id="btnYes">Да</button>
</div>
</div>
</div>
</div>

@ -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:

@ -5,5 +5,6 @@ from django.apps import AppConfig
class ProjectsConfig(AppConfig):
name = 'projects'
def ready(self):
import projects.signals

@ -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,
),
]

@ -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),
),
]

@ -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)

@ -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()
@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()

@ -12,33 +12,35 @@
<div class="container-fluid">
<div class="row">
<div class="col-lg-6">
<div class="changeBlock changeBlock1">
{% if request.user.is_authenticated and request.user.is_contractor %}
<a href="{% url 'users:contractor-profile' pk=request.user.pk %}">Я исполнитель</a>
<div class="col-lg-6">
<div class="changeBlock changeBlock2">
{% if request.user.is_authenticated and request.user.is_customer %}
<a href="{% url 'users:customer-profile-open-projects' pk=request.user.pk %}">Я заказчик</a>
{% else %}
<a href="{% url 'registration_register' %}?type=contractor">Я исполнитель</a>
<a href="{% url 'registration_register' %}?type=customer">Я заказчик</a>
{% endif %}
<p>
{{ main_settings.contractor_text|safe }}
{{ main_settings.customer_text|safe }}
</p>
</div>
<div class="square">
<div class="square">
<div class="insetSquare"></div>
</div>
</div>
<div class="col-lg-6">
<div class="changeBlock changeBlock2">
{% if request.user.is_authenticated and request.user.is_customer %}
<a href="{% url 'users:customer-profile-open-projects' pk=request.user.pk %}">Я заказчик</a>
<div class="changeBlock changeBlock1">
{% if request.user.is_authenticated and request.user.is_contractor %}
<a href="{% url 'users:contractor-profile' pk=request.user.pk %}">Я исполнитель</a>
{% else %}
<a href="{% url 'registration_register' %}?type=customer">Я заказчик</a>
<a href="{% url 'registration_register' %}?type=contractor">Я исполнитель</a>
{% endif %}
<p>
{{ main_settings.customer_text|safe }}
{{ main_settings.contractor_text|safe }}
</p>
</div>
</div>
</div>
</div>

@ -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("Вам пришло новое сообщение!<br />" + 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);
}

Loading…
Cancel
Save