remotes/origin/PR-39
ArturBaybulatov 10 years ago
commit 11b08c01a7
  1. 5
      api/views.py
  2. 4
      assets/css/extra.css
  3. 263
      assets/js/chat.js
  4. 2
      chat/chat.py
  5. 1
      chat/filters.py
  6. 1
      chat/serializers.py
  7. 111
      chat/templates/chat_contractor.html
  8. 121
      chat/templates/chat_customer.html
  9. 18
      chat/views.py
  10. 20
      common/migrations/0006_settings_noreply_email.py
  11. 2
      common/models.py
  12. 2
      common/views.py
  13. 20
      projects/migrations/0018_auto_20160829_1751.py
  14. 19
      projects/migrations/0019_remove_stage_term.py
  15. 23
      projects/migrations/0020_stage_term.py
  16. 2
      projects/models.py
  17. 14
      projects/serializers.py
  18. 9
      projects/templates/comparison.html
  19. 6
      projects/templates/project_detail.html
  20. 6
      projects/views.py
  21. 10
      templates/partials/base.html
  22. 20
      work_sell/migrations/0007_auto_20160829_1740.py

@ -83,7 +83,7 @@ class DocumentViewSet(ModelViewSet):
if search_param:
# import code; code.interact(local=dict(globals(), **locals()))
if search_param == 'in':
queryset = queryset.filter(Q(sender__in=[sender_id,recipent_id]),Q(recipent__in=[sender_id,recipent_id])).order_by('created')
queryset = queryset.filter(Q(sender__in=[sender_id, recipent_id]),Q(recipent__in=[sender_id, recipent_id])).filter(order__isnull=True).order_by('created')
return queryset
@ -110,6 +110,7 @@ class NoteViewSet(ModelViewSet):
queryset = queryset.filter(Q(sender__in=[sender_id,recipent_id]),Q(recipent__in=[sender_id,recipent_id])).order_by('created')
return queryset
class MessageViewSet(ModelViewSet):
queryset = Message.objects.all()
serializer_class = MessageSerializer
@ -123,7 +124,7 @@ class MessageViewSet(ModelViewSet):
if search_param:
# import code; code.interact(local=dict(globals(), **locals()))
if search_param == 'in':
queryset = queryset.filter(Q(sender__in=[sender_id,recipent_id]),Q(recipent__in=[sender_id,recipent_id])).order_by('created')
queryset = queryset.filter(Q(sender__in=[sender_id,recipent_id]),Q(recipent__in=[sender_id,recipent_id])).filter(order__isnull=True).order_by('created')
return queryset

@ -107,3 +107,7 @@
font-size: 15px;
}
#jGrowl .jGrowl-notification a, #jGrowl .jGrowl-notification a:visited {
color: #777620;
}

@ -14,7 +14,13 @@ var SocketHandler = function () {
var message = JSON.parse(event.data);
var inbox;
if (message.answer_type == 'contact' || message.answer_type == 'add_message_contact') {
inbox = document.getElementById('message-chat-space');
var sumSenderRecipent = parseInt(message.recipent_id) + parseInt(message.sender_id);
var inboxClass = document.getElementsByClassName('contact-space' + sumSenderRecipent);
if (inboxClass.length > 0) {
inbox = inboxClass[0];
}else{
$(".contact-count-" + sumSenderRecipent).text(parseInt($(".contact-count-" + sumSenderRecipent).text()) + 1);
}
} else if (message.answer_type == 'order' || message.answer_type == 'add_message_order') {
inbox = document.getElementById('message-chat-order-space');
} else if (message.answer_type == 'add_message_team') {
@ -123,6 +129,99 @@ $(function () {
}
// Вытащить сообщения для конактов
$('.user-block').on('click', function () {
var contactId = $(this).attr('data-id');
$("#contact-chat-form #recipentContactId").val(contactId);
$("#add-form-contractor-note #recipentNoteContractor").val(contactId);
$('.user-block').each(function () {
$(this).removeClass('mesAct');
});
$(this).addClass('mesAct');
var inbox = document.getElementById('message-chat-space');
var sumSenderRecipent = parseInt(userId) + parseInt(contactId);
$("#message-chat-space").removeClass().addClass("contact-space" + sumSenderRecipent);
$(".contact-count-"+ sumSenderRecipent).text(0);
var docList = document.getElementById('documentSpace');
inbox.innerHTML = '';
docList.innerHTML = '';
$.ajax({
url: '/api/documents',
type: 'GET',
data: {
csrfmiddlewaretoken: csrftoken,
'operand': 'in',
'sender_id': userId,
'recipent_id': contactId,
},
dataType: 'json',
success: function (json) {
console.log(json);
$.each(json.results, function (i, v) {
docList.innerHTML += '<li style="word-break: break-all;">' + v.file + '</li>';
});
},
error: function (e) {
console.log(e);
}
});
$.ajax({
url: '/api/message',
type: 'GET',
data: {
csrfmiddlewaretoken: csrftoken,
'operand': 'in',
'sender_id': userId,
'recipent_id': contactId
},
dataType: 'json',
success: function (json) {
$.each(json.results, function (i, v) {
var senderName = 'Вы';
var className = 'youChat';
if (v.sender.id == contactId) {
senderName = v.sender.username;
className = '';
}
inbox.innerHTML += '<div class="col-lg-12 insetCommChat ' + className + '"><div class="topCommChat">' +
'<p class="nameCommChat">' + senderName + '</p> <span>' + v.created + '</span></div>' +
'<p class="textCommChat">' + v.text + '</p></div>';
});
}
});
$.ajax({
url: '/api/note/',
type: 'GET',
data: {
csrfmiddlewaretoken: csrftoken,
'operand': 'in',
'sender_id': userId,
'recipent_id': contactId
},
dataType: 'json',
success: function (json) {
console.log(json.results);
var noteHtmlInbox = '';
$.each(json.results, function (i, v) {
noteHtmlInbox += '<li>' + v.text + '<li>';
});
$(".contractor-notes-block").html(noteHtmlInbox);
}
});
});
$('.deleteMess').on('click', function (e) {
e.preventDefault();
e.stopPropagation();
@ -182,81 +281,111 @@ $(function () {
var senderId = $("#chat-order-add #senderId").val();
var orderId = $("#chat-order-add #orderId").val();
socket.add_contact_message({
"format_type": "add_message_order",
"data": {
"sender_id": senderId,
"recipent_id": recipentId,
"chat_message": chatMessage,
"order_id": orderId,
if (chatMessage) {
$("#chat-order-add .errorEmptyMessage").hide();
socket.add_contact_message({
"format_type": "add_message_order",
"data": {
"sender_id": senderId,
"recipent_id": recipentId,
"chat_message": chatMessage,
"order_id": orderId,
}
});
}
});
$("#chat-order-add #chat").val("");
$("#document-send-order").html("");
} else {
$("#chat-order-add .errorEmptyMessage").show();
}
});
$('#contact-chat-add-message').on('click', function (e) {
e.preventDefault();
var chatMessage = $("#chat").val();
var recipentId = $("#recipentContactId").val();
var senderId = $("#senderContactId").val();
if (chatMessage) {
$("#contact-chat-form .errorEmptyMessage").hide();
socket.add_contact_message({
"format_type": "add_message_contact",
"data": {
"sender_id": senderId,
"recipent_id": recipentId,
"chat_message": chatMessage,
}
});
$("#chat").val("");
$("#document-send-contact").html("");
} else {
$("#contact-chat-form .errorEmptyMessage").show();
}
$("#chat-order-add #chat").val("");
$("#document-send-order").html("");
});
// Добавление отзыва
$('#order-review-add').on('click', function (e) {
e.preventDefault();
e.stopPropagation();
var formData = $("#review-adds-form").serialize();
$.ajax({
url: '/api/reviews/',
type: 'POST',
beforeSend: function (xhr) {
xhr.setRequestHeader("X-CSRFToken", getCookie('csrftoken'))
},
data: formData,
dataType: 'json',
success: function (json) {
console.log("Успешно");
$("#review-add").modal('hide');
$.jGrowl("Ваш отзыв успешно добавлен", {
life: 4000
});
},
error: function (e) {
console.log('error');
console.log(e);
}
});
e.preventDefault();
e.stopPropagation();
var formData = $("#review-adds-form").serialize();
$.ajax({
url: '/api/reviews/',
type: 'POST',
beforeSend: function (xhr) {
xhr.setRequestHeader("X-CSRFToken", getCookie('csrftoken'))
},
data: formData,
dataType: 'json',
success: function (json) {
console.log("Успешно");
$("#review-add").modal('hide');
$.jGrowl("Ваш отзыв успешно добавлен", {
life: 4000
});
},
error: function (e) {
console.log('error');
console.log(e);
}
});
});
// Добавление сообщения в арбитраж
$('#order-arbitration-add').on('click', function (e) {
e.preventDefault();
e.stopPropagation();
var formData = $("#arbitration-add-form").serialize();
$.ajax({
url: '/projects/arbitration/create/',
type: 'POST',
beforeSend: function (xhr) {
xhr.setRequestHeader("X-CSRFToken", getCookie('csrftoken'))
},
data: formData,
dataType: 'json',
success: function (json) {
console.log(json);
$("#arbitration-add").modal('hide');
$.jGrowl("Обращение в арбитраж добавлено", {
life: 4000
});
},
error: function (e) {
console.log('error');
console.log(e);
}
});
e.preventDefault();
e.stopPropagation();
var formData = $("#arbitration-add-form").serialize();
$.ajax({
url: '/projects/arbitration/create/',
type: 'POST',
beforeSend: function (xhr) {
xhr.setRequestHeader("X-CSRFToken", getCookie('csrftoken'))
},
data: formData,
dataType: 'json',
success: function (json) {
console.log(json);
$("#arbitration-add").modal('hide');
$.jGrowl("Обращение в арбитраж добавлено", {
life: 4000
});
},
error: function (e) {
console.log('error');
console.log(e);
}
});
});
$("#upload-document-order").bind('fileuploadsubmit', function(e, data){
data.formData = {
$("#upload-document-order").bind('fileuploadsubmit', function (e, data) {
data.formData = {
sender: $("#chat-order-add #senderId").val(),
recipent: $("#chat-order-add #recipentId").val(),
order: $("#chat-order-add #orderId").val(),
}
}
});
//Загрузка документов
@ -296,17 +425,15 @@ $(function () {
.parent().addClass($.support.fileInput ? undefined : 'disabled'); //Загрузка документов
$("#upload-document-contact").bind('fileuploadsubmit', function(e, data){
data.formData = {
sender: $("#contact-chat-form #senderContactId").val(),
recipent: $("#contact-chat-form #recipentContactId").val(),
}
$("#upload-document-contact").bind('fileuploadsubmit', function (e, data) {
data.formData = {
sender: $("#contact-chat-form #senderContactId").val(),
recipent: $("#contact-chat-form #recipentContactId").val(),
}
});
$('#upload-document-contact').fileupload({
url: '/chat/create/',
crossDomain: false,

@ -94,7 +94,7 @@ class ChatHandler(websocket.WebSocketHandler):
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, '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})
def check_origin(self, origin):
return True

@ -20,6 +20,7 @@ class MessageFilterSet(FilterSet):
sender = RelatedFilter('users.filters.UserFilterSet')
recipent = RelatedFilter('users.filters.UserFilterSet')
private_type = AllLookupsFilter()
team = RelatedFilter('users.filters.TeamFilterSet')
class Meta:
model = Message

@ -35,6 +35,7 @@ class MessageSerializer(ModelSerializer):
'sender',
'recipent',
'private_type',
'team',
)

@ -58,7 +58,7 @@
<a href="#" class="conMess">Контакты</a>
<span>0</span>
<span class="contact-count-{{ contact.pk|add:request.user.pk }}">0</span>
<a href="#" class="deleteMess" data-recipent-id="{{ contact.pk }}">
Удалить контакт
</a>
@ -71,20 +71,31 @@
<div class="col-lg-6 commChat" id="contact-chat">
<div id="message-chat-space"></div>
<form id="contact-chat-form">
<input type="hidden" value="{{ request.user.pk }}" name="senderId" id="senderId"/>
<input type="hidden" value="" name="recipentId" id="recipentId"/>
<input type="hidden" value="{{ request.user.pk }}" name="senderId" id="senderContactId"/>
<input type="hidden" value="" name="recipentId" id="recipentContactId"/>
<textarea id="chat" name="chat_message" class="box-sizing"></textarea>
<p class="errorEmptyMessage" style="color: red;display:none;">Пустое сообщение нельзя отправить</p>
<div class="bunChat">
<div class="setChat box-sizing">
<p>Прикрепить файл</p>
<span>Не более 10 файлов с общим объемом 500мб</span>
<div class="setChat box-sizing upload">
<input type="file" name="file" id="upload-document-contact">
<p>Прикрепить файл</p>
</div>
<a id="contact-chat-add-message" href="javascript:void(0)">отправить</a>
<div id="document-send-contact"></div>
<a id="contact-chat-add-message" href="#">отправить</a>
</div>
</form>
</div>
<div class="col-lg-3 wrChat1">
<div class="col-lg-12 documentsChat">
<p>Входящие документы</p>
<ul id="documentSpace">
</ul>
{# <a href="javascript:void(0)">#}
{# Распечатать с помощью ресурса#}
{# </a>#}
</div>
<div class="textAreaBlock2 box-sizing disTab">
<ul class="contractor-notes-block">
</ul>
@ -131,6 +142,7 @@
<input type="hidden" id="senderId" value="{{ request.user.pk }}"/>
<input type="hidden" id="recipentId">
<textarea id="chat" class="box-sizing"></textarea>
<p class="errorEmptyMessage" style="color: red;display:none;">Пустое сообщение нельзя отправить</p>
<div class="bunChat">
<div class="setChat box-sizing upload">
<input type="file" name="file" id="upload-document-order"/>
@ -433,7 +445,6 @@
$(this).removeClass('orAct');
});
$(this).addClass('orAct');
var orderId = $(this).attr('data-id');
var recipentId = $(this).attr('data-recipent-id');
var projectId = $(this).attr('data-project-id');
@ -447,15 +458,13 @@
$("#targetCustomerId").val(recipentId);
$("#add-form-order-note #recipentNote").val(recipentId);
var inbox = document.getElementById('message-chat-order-space');
inbox.innerHTML = '';
$.ajax({
url: '/api/message',
type: 'GET',
data: {csrfmiddlewaretoken: csrftoken, 'order': orderId},
data: {csrfmiddlewaretoken: csrftoken, 'order': orderId, 'team__isnull': 'true'},
dataType: 'json',
success: function (json) {
$.each(json.results, function (i, v) {
@ -531,7 +540,7 @@
htmlInbox += '<div data-id="' + v.id + '" class="numberStepp box-sizing stage-block-approve"><div class="insetNumStepp">' +
'<p class="titleNumStepp"><span>Этап ' + v.pos + '</span>' + v.name + '</p>' +
'<p class="textNumStepp">Результаты этапа:' + v.result + '</p><div>' +
'<p>' + v.term + '</p><span>' + v.cost + '<i class="fa fa-rub"></i></span></div></div></div>';
'<p> до ' + v.term + '</p><span>' + v.cost + '<i class="fa fa-rub"></i></span></div></div></div>';
});
if (statusNotAgreed) {
@ -639,67 +648,7 @@
});
});
// Вытащить сообщения для конактов
$('.user-block').on('click', function () {
var userId = $(this).attr('data-id');
$("#contact-chat-form #recipentId").val(userId);
$("#add-form-contractor-note #recipentNoteContractor").val(userId);
$('.user-block').each(function () {
$(this).removeClass('mesAct');
});
$(this).addClass('mesAct');
var inbox = document.getElementById('message-chat-space');
inbox.innerHTML = '';
$.ajax({
url: '/api/message',
type: 'GET',
data: {
csrfmiddlewaretoken: csrftoken,
'operand': 'in',
'sender_id': currentChatUser,
'recipent_id': userId
},
dataType: 'json',
success: function (json) {
$.each(json.results, function (i, v) {
console.log(v.sender.id);
var senderName = 'Вы';
var className = 'youChat';
if (v.sender.id == userId) {
senderName = v.sender.username;
className = '';
}
inbox.innerHTML += '<div class="col-lg-12 insetCommChat ' + className + '"><div class="topCommChat">' +
'<p class="nameCommChat">' + senderName + '</p> <span>' + v.created + '</span></div>' +
'<p class="textCommChat">' + v.text + '</p></div>';
});
}
});
$.ajax({
url: '/api/note/',
type: 'GET',
data: {csrfmiddlewaretoken: csrftoken,
'operand': 'in',
'sender_id': currentChatUser,
'recipent_id': userId},
dataType: 'json',
success: function (json) {
console.log(json.results);
var noteHtmlInbox = '';
$.each(json.results, function (i, v) {
noteHtmlInbox += '<li>' + v.text + '<li>';
});
$(".contractor-notes-block").html(noteHtmlInbox);
}
});
});
//Добавить сообщение для исполнителей в группе
$("#add-team-chat-message").on('click', function () {
var chatMessage = $("#team-chat-form #chatText").val();
var recipentId = $("#team-chat-form #recipentId").val();
@ -727,24 +676,6 @@
$("#document-send").html("");
});
// Добавить сообщение для контакта
$('#contact-chat-add-message').on('click', function () {
var chatMessage = $("#chat").val();
var recipentId = $("#recipentId").val();
var senderId = $("#senderId").val();
socket.add_contact_message({
"format_type": "add_message_contact",
"data": {
"sender_id": senderId,
"recipent_id": recipentId,
"chat_message": chatMessage,
}
});
var inbox = $('#message-chat-space').html();
$("#chat").val("");
});
});
</script>

@ -52,7 +52,7 @@
<a href="#" data-target="#userModal" data-toggle="modal"
class="conMess">Контакты</a>
<span>0</span>
<span class="contact-count-{{ contact.pk|add:request.user.pk }}">0</span>
<a href="#" class="deleteMess" data-recipent-id="{{ contact.pk }}">
Удалить контакт
</a>
@ -67,8 +67,8 @@
<form id="contact-chat-form">
<input type="hidden" value="{{ request.user.pk }}" name="senderId" id="senderContactId"/>
<input type="hidden" name="recipentId" id="recipentContactId">
<textarea id="chat" name="chat_message" class="box-sizing"></textarea>
<p class="errorEmptyMessage" style="color: red;display:none;">Пустое сообщение нельзя отправить</p>
<div class="bunChat">
<div class="setChat box-sizing upload">
@ -137,6 +137,7 @@
<input type="hidden" name="recipentId" id="recipentId">
<input type="hidden" name="orderId" id="orderId">
<textarea id="chat" class="box-sizing"></textarea>
<p class="errorEmptyMessage" style="color: red;display:none;">Пустое сообщение нельзя отправить</p>
<div class="bunChat">
<div class="setChat box-sizing upload">
<input type="file" name="file" id="upload-document-order">
@ -192,6 +193,14 @@
</a>
</div>
<div class="col-lg-12 documentsChat">
<p>Входящие документы</p>
<ul id="documentOrderSpace"></ul>
{# <a href="javascript:void(0)">#}
{# Распечатать с помощью ресурса#}
{# </a>#}
</div>
<div class="textAreaBlock2 box-sizing disTab">
<p>Для заметок</p>
<textarea id="chat2"></textarea>
@ -229,6 +238,12 @@
var currentChatUser = {{ request.user.pk }};
var form = document.getElementById('message_form');
$('body').on('focus',".term-picker", function(){
$(this).datepicker({
minDate: 0,
});
})
$("#reserve-button").on("click",function(e) {
e.preventDefault();
$("#reserve-stage-modal").modal('show');
@ -279,7 +294,6 @@
});
$("#tab2").on("change","#stagesSelect", function(e){
var sumStage = $(this).find('option:selected').attr("data-stage-sum");
$("#choiceWayStage").val(sumStage);
@ -313,7 +327,7 @@
'<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 orderStagesInput" name="order" type="hidden" value="' + orderId + '"/>' +
'<label for="">Срок</label><input class="form-control" name="term" type="text" />' +
'<label for="">Срок</label><input class="term-picker form-control datepicker" name="term" type="text" />' +
'<label for="">Результат</label><input class="form-control" name="result" type="text" />' +
'<input class="form-control" name="pos" value="1" type="hidden" />' +
'</form></div>';
@ -342,7 +356,7 @@
'<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 + '" />' +
'<input class="form-control orderStagesInput" 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="term-picker form-control datepicker" type="text" name="term" value="' + v.term + '" />' +
'<label for="">Результат</label><input class="form-control" type="text" name="result" value="' + v.result + '" />' +
'</form></div>';
} else {
@ -358,14 +372,11 @@
});
if (statusNotAgreed) {
var orderSecureCheckbox = '';
if(data.secure) {
orderSecureCheckbox = "checked";
}
htmlInbox += '<div class="box-sizing disTab">' +
'<div class="checkbox"><input name="secure" id="secureOrder" '+ orderSecureCheckbox +' type="checkbox" style="opacity:1">' +
if(!data.secure) {
htmlInbox += '<div class="box-sizing disTab">' +
'<div class="checkbox"><input name="secure" id="secureOrder" type="checkbox" style="opacity:1">' +
'Перейти в режим безопасной сделки</div></div>';
}
htmlInbox +='<div class="textAreaBlock2 box-sizing disTab">' +
'<a href="#" data-sender-id="' + senderId +'" ' +
@ -447,7 +458,6 @@
});
});
// Добавление этапов
$("#order-stages").on('click', "#addStagesForm", function (e) {
e.preventDefault();
@ -554,7 +564,7 @@
'<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 orderStagesInput" name="order" type="hidden" value="' + orderId + '" />' +
'<label for="">Срок</label><input class="form-control" name="term" type="text" />' +
'<label for="">Срок</label><input class="term-picker form-control datepicker" name="term" type="text" />' +
'<label for="">Результат</label><input class="form-control" name="result" type="text" />' +
'<input class="form-control" name="pos" value="' + pos + '" type="hidden" />'
'</form></div>';
@ -598,44 +608,7 @@
$("#chat-order-add #recipentId").val(recipentId);
$(".orderStagesInput").val(orderId);
var inbox = document.getElementById('message-chat-order-space');
inbox.innerHTML = '';
$.ajax({
url: '/api/message',
type: 'GET',
data: {csrfmiddlewaretoken: csrftoken, 'order': orderId},
dataType: 'json',
success: function (json) {
$.each(json.results, function (i, v) {
var senderName = 'Вы';
var className = 'youChat';
if (v.sender.id !== currentChatUser) {
senderName = v.sender.username;
className = '';
}
inbox.innerHTML += '<div class="col-lg-12 insetCommChat ' + className + '"><div class="topCommChat">' +
'<p class="nameCommChat">' + senderName + '</p><span>' + v.created + '</span></div>' +
'<p class="textCommChat">' + v.text + '</p></div>';
});
}
});
getStages(orderId,userId,recipentId, secureOrder);
});
// Вытащить сообщения для конактов
$('.user-block').on('click', function () {
var userId = $(this).attr('data-id');
$("#contact-chat-form #recipentContactId").val(userId);
$("#add-form-contractor-note #recipentNoteContractor").val(userId);
$('.user-block').each(function () {
$(this).removeClass('mesAct');
});
$(this).addClass('mesAct');
var inbox = document.getElementById('message-chat-space');
var docList = document.getElementById('documentSpace');
var docList = document.getElementById('documentOrderSpace');
inbox.innerHTML = '';
docList.innerHTML = '';
@ -644,68 +617,42 @@
type: 'GET',
data:{
csrfmiddlewaretoken: csrftoken,
'operand': 'in',
'sender_id': currentChatUser,
'recipent_id': userId
'order': orderId
},
dataType: 'json',
success: function (json){
console.log(json);
$.each(json.results, function (i, v) {
docList.innerHTML += '<li style="word-break: break-all;">'+ v.file+'<div></div></li>';
docList.innerHTML += '<li style="word-break: break-all;">'+ v.file+'</li>';
});
},
error: function(e){
console.log(e);
}
});
$.ajax({
url: '/api/message',
type: 'GET',
data: {
csrfmiddlewaretoken: csrftoken,
'operand': 'in',
'sender_id': currentChatUser,
'recipent_id': userId
},
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) {
if (v.sender.id !== currentChatUser) {
senderName = v.sender.username;
className = '';
}
inbox.innerHTML += '<div class="col-lg-12 insetCommChat ' + className + '"><div class="topCommChat">' +
'<p class="nameCommChat">' + senderName + '</p> <span>' + v.created + '</span></div>' +
inbox.innerHTML += '<div class="col-lg-12 insetCommChat ' + className + '"><div class="topCommChat">' +
'<p class="nameCommChat">' + senderName + '</p><span>' + v.created + '</span></div>' +
'<p class="textCommChat">' + v.text + '</p></div>';
});
}
});
});
$('#contact-chat-add-message').on('click', function (e) {
e.preventDefault();
var chatMessage = $("#chat").val();
var recipentId = $("#recipentContactId").val();
var senderId = $("#senderContactId").val();
socket.add_contact_message({
"format_type": "add_message_contact",
"data": {
"sender_id": senderId,
"recipent_id": recipentId,
"chat_message": chatMessage,
}
});
$("#chat").val("");
$("#document-send-contact").html("");
getStages(orderId,userId,recipentId, secureOrder);
});

@ -55,7 +55,7 @@ class ChatUserView(LoginRequiredMixin, View):
contacts_users = User.objects.filter(pk__in=users_ids)
chat_messages = Message.objects.filter(Q(sender=request.user.pk) | Q(recipent=request.user.pk))
orders = request.user.projects.select_related('order').exclude(order__contractor__isnull=True)
orders = request.user.projects.select_related('order').exclude(order__contractor__isnull=True, order__team__isnull=True)
transaction = Transaction.objects.get_or_create(customer=request.user, type='reservation', complete=False)
self.template_name = 'chat_customer.html'
return render(request, self.template_name, {'contacts_users': contacts_users,
@ -65,7 +65,15 @@ class ChatUserView(LoginRequiredMixin, View):
'YANDEX_MONEY': settings.YANDEX_MONEY,
})
else:
orders = request.user.orders.all()
team_ids = []
if request.user.is_owner_team():
team_ids.append(request.user.team.pk)
team_orders = request.user.team.orders.all()
else:
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)).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()
users_ids = []
@ -81,11 +89,7 @@ class ChatUserView(LoginRequiredMixin, View):
chat_messages = Message.objects.filter(Q(sender=request.user.pk) | Q(recipent=request.user.pk)).order_by(
'created')
if request.user.is_owner_team():
team_orders = request.user.team.orders.all()
else:
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()
self.template_name = 'chat_contractor.html'
return render(request, self.template_name, {'orders': orders,

@ -0,0 +1,20 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.9.7 on 2016-08-29 16:59
from __future__ import unicode_literals
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('common', '0005_settings_accountant_send_email'),
]
operations = [
migrations.AddField(
model_name='settings',
name='noreply_email',
field=models.CharField(default='noreply@proekton.com', max_length=50),
),
]

@ -43,7 +43,7 @@ class Settings(models.Model):
document_send_time_remove = models.IntegerField(default=14)
recalculation_spec_time = models.TimeField()
recalculation_rating_time = models.TimeField()
# worksell_count = models.PositiveIntegerField(default=20)
noreply_email = models.CharField(max_length=50,default='noreply@proekton.com')
def __str__(self):
return 'Настройки сайта'

@ -52,7 +52,7 @@ class PrintDocumentCreate(BaseMixin, View):
settings = Settings.objects.all().first()
subject, from_email, to = 'Заявка на распечатку', 'mukhtar@mukhtar', settings.document_send_email
subject, from_email, to = 'Заявка на распечатку', settings.noreply_email, settings.document_send_email
text_content = render_to_string('document_email.txt', ctx_dict)
html_content = get_template('document_email.html').render(ctx_dict)
msg = EmailMultiAlternatives(subject, text_content, from_email, [to])

@ -0,0 +1,20 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.9.7 on 2016-08-29 14:51
from __future__ import unicode_literals
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('projects', '0017_arbitration'),
]
operations = [
migrations.AlterField(
model_name='portfolio',
name='created',
field=models.DateTimeField(auto_created=True, auto_now_add=True),
),
]

@ -0,0 +1,19 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.9.7 on 2016-08-29 14:58
from __future__ import unicode_literals
from django.db import migrations
class Migration(migrations.Migration):
dependencies = [
('projects', '0018_auto_20160829_1751'),
]
operations = [
migrations.RemoveField(
model_name='stage',
name='term',
),
]

@ -0,0 +1,23 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.9.7 on 2016-08-29 15:02
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', '0019_remove_stage_term'),
]
operations = [
migrations.AddField(
model_name='stage',
name='term',
field=models.DateTimeField(auto_now_add=True, default=datetime.datetime(2016, 8, 29, 15, 2, 54, 818311, tzinfo=utc)),
preserve_default=False,
),
]

@ -251,7 +251,7 @@ class Stage(models.Model):
name = models.CharField(max_length=255)
order = models.ForeignKey(Order, related_name='stages')
result = models.CharField(max_length=255)
term = models.IntegerField(default=0)
term = models.DateTimeField(auto_now_add=True)
term_type = models.CharField(max_length=10, choices=TERMS, default='hour')
status = models.CharField(choices=STATUSES, max_length=30, default='not_agreed')
created = models.DateTimeField(default=timezone.now)

@ -1,3 +1,4 @@
from rest_framework import serializers
from generic_relations.relations import GenericRelatedField
from rest_framework.serializers import ModelSerializer, ImageField, FileField, SerializerMethodField, PrimaryKeyRelatedField, ReadOnlyField
@ -47,7 +48,7 @@ class RealtySerializer(ModelSerializer):
class StageSerializer(ModelSerializer):
# order = OrderSerializer()
term = serializers.DateTimeField(format="%d-%m-%Y")
class Meta:
model = Stage
@ -70,17 +71,6 @@ class StageSerializer(ModelSerializer):
)
# def update(self, inst, validated_data):
# import code; code.interact(local=dict(globals(), **locals()))
# inst.id = validated_data.get('id',inst.id)
# inst.name = validated_data.get('name', inst.name)
# inst.cost = validated_data.get('cost', inst.cost)
# inst.order = validated_data.get('order', inst.order)
# inst.result = validated_data.get('result', inst.result)
# inst.save()
# return inst
class OrderSerializer(ModelSerializer):
stages = StageSerializer(many=True, read_only=True)

@ -76,9 +76,12 @@
<td>
<div class="tableButtons disTab">
<a href="{% url 'chat:chat-user' %}">
<div class="btnTab btnTab1"></div>
</a>
<form action="{% url 'projects:customer-offer-order' answer_id=cand.answer.pk project_id=cand.project.pk %}" method="POST" novalidate>
{% csrf_token %}
<a href="#" onclick="$(this).closest('form').submit(); return false">
<div class="btnTab btnTab1"></div>
</a>
</form>
<a href="{% url 'chat:chat-user' %}?user_id={{ cand.answer.author.pk }}">
<div class="btnTab btnTab2"></div>

@ -708,7 +708,11 @@
</div>
<div class="col-lg-3 retts">
{% ratings_widget answer.author.pk 'restList2' %}
{% if answer.author|class_name == 'User' %}
{% ratings_widget answer.author.pk 'restList2' %}
{% elif answer.author|class_name == 'Team'%}
{% ratings_team_widget answer.author.pk 'restList2' %}
{% endif %}
{% if answer.author|class_name == 'User' and answer.author.cro %}
<div class="sroUser sroExecutor">

@ -594,9 +594,9 @@ class ProjectComparisonView(DetailView):
model = Project
template_name = 'comparison.html'
def get_context_data(self, **kwargs):
context = super().get_context_data()
return context
# def get(self, request, **kwargs):
# self.object = self.get_object()
def add_candidate(request, answer_id, project_id):

@ -97,7 +97,15 @@
sock.onmessage = function (event) {
var notificationData = JSON.parse(event.data);
$.jGrowl("Вам пришло новое сообщение!" + notificationData.msg, {sticky: true});
console.log(notificationData);
var outMessage = "";
if (notificationData.answer_type == 'add_message_contact'){
outMessage += "<a href='/chat/?user_id=" + notificationData.sender_id + "'>"+ notificationData.msg +"<a>";
}else if((notificationData.answer_type == 'approve_stages') || (notificationData.answer_type == 'add_message_order')){
outMessage += "<a href='/chat/#order" + notificationData.order_id + "'>"+ notificationData.msg +"<a>";
}
$.jGrowl("Вам пришло новое сообщение!<br />" + outMessage, { life: 15000});
};
}
};

@ -0,0 +1,20 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.9.7 on 2016-08-29 14:40
from __future__ import unicode_literals
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('work_sell', '0006_remove_worksell_team'),
]
operations = [
migrations.AlterField(
model_name='worksell',
name='created',
field=models.DateTimeField(auto_now_add=True),
),
]
Loading…
Cancel
Save