remotes/origin/PR-39
ArturBaybulatov 10 years ago
commit 6309168666
  1. 2
      archilance/settings/base.py
  2. 11
      assets/js/chat.js
  3. 320
      assets/js/chat_customer.js
  4. 63
      chat/templates/chat_contractor.html
  5. 250
      chat/templates/chat_customer.html
  6. 41
      chat/templates/reverse_stage_modal.html
  7. 49
      chat/templates/review_add_modal.html
  8. 13
      chat/views.py
  9. 29
      projects/migrations/0014_auto_20160824_0154.py
  10. 20
      projects/migrations/0015_auto_20160824_1119.py
  11. 16
      projects/migrations/0016_merge.py
  12. 9
      projects/models.py
  13. 2
      projects/serializers.py
  14. 6
      projects/views.py
  15. 1
      requirements/base.txt
  16. 5
      templates/partials/header.html
  17. 20
      wallets/migrations/0009_transaction_stages_id.py
  18. 1
      wallets/models.py
  19. 5
      wallets/views.py

@ -41,6 +41,7 @@ THIRD_PARTY_APPS = [
'mathfilters', # Basic math operations in templates; https://pypi.python.org/pypi/django-mathfilters
'generic_relations', # https://github.com/Ian-Foote/rest-framework-generic-relations
'hitcount',
'django_activeurl',
]
LOCAL_APPS = [
@ -85,6 +86,7 @@ TEMPLATES = [
'django.template.context_processors.request',
'django.contrib.auth.context_processors.auth',
'django.contrib.messages.context_processors.messages',
'django.core.context_processors.request',
],
# Load these templatetags by default:

@ -20,7 +20,7 @@ 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') {
alert('approve stages');
console.log('approve stages');
}
if (inbox) {
var textMessage = message.msg;
@ -94,6 +94,15 @@ function csrfSafeMethod(method) {
$(function () {
setTimeout(function () {
$(".user-block").first().trigger('click');
}, 10);
setTimeout(function () {
$(".order-block").first().trigger('click');
}, 100);
$('.deleteMess').on('click', function (e) {
e.preventDefault();
e.stopPropagation();

@ -0,0 +1,320 @@
$(function () {
var currentChatUser = {
{
request.user.pk
}
}
;
var socket = new SocketHandler();
var form = document.getElementById('message_form');
var csrftoken = getCookie('csrftoken');
$("#reserve-button").on("click", function (e) {
e.preventDefault();
var orderId = $(this).attr('data-order-id');
$.ajax({
url: '/api/stages/',
type: 'GET',
data: {csrfmiddlewaretoken: csrftoken, 'order': orderId},
dataType: 'json',
success: function (json) {
console.log(json.results);
}
});
});
function getStages(orderId, senderId, recipentId) {
$.ajax({
url: '/api/stages/',
type: 'GET',
data: {csrfmiddlewaretoken: csrftoken, 'order': orderId},
dataType: 'json',
success: function (json) {
var stageCount = json.results.length;
if (stageCount == 0) {
stageCountVal = 1;
} else {
stageCountVal = stageCount;
}
var htmlInbox = "";
var htmlInboxStage = '<p class="textStepss">Какое кол-во этапов подразумевает работа? ' +
'<input type="text" id="countStage" value="' + stageCountVal + '"size="3"/></p>';
if (stageCount == 0) {
htmlInboxStage += '<div class="numberStepp box-sizing" id="stage1">' +
'<p>Этап <span class="stage-span-id">1</span></p><form class="new-stages-form" id="stage-form">' +
'<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="form-control" name="result" type="text" />' +
'<label for="">Позиция</label><input class="form-control" name="pos" value="1" type="text" />' +
'</form></div>';
}
var statusNotAgreed = true;
$.each(json.results, function (i, v) {
if (v.status == "not_agreed") {
htmlInbox += '<div class="numberStepp box-sizing">' +
'<p>Этап</p><form class="update-stages-form" data-stage-id="' + v.id + '" id="stage-form-' + v.pos + '">' +
'<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="form-control" type="text" name="result" value="' + v.result + '" />' +
'</form></div>';
} else {
statusNotAgreed = false;
htmlInboxStage = "";
htmlInbox += '<div class="numberStepp box-sizing"><div class="insetNumStepp">' +
'<p class="titleNumStepp"><span>Этап ' + v.pos + '</span>' + v.name + '</p>' +
'<p class="textNumStepp">Результаты этапа:' + v.result + '</p><div>' +
'<p>до Дата</p><span>' + v.cost + '<i class="fa fa-rub"></i></span></div></div></div>';
}
});
if (statusNotAgreed) {
htmlInbox += '<div class="box-sizing disTab" style="text-align:center;"><div class="checkbox"><input type="checkbox" style="opacity:1">Перейти в режим безопасной сделки' +
'</div></div><div class="textAreaBlock2 box-sizing disTab">' +
'<a href="#" data-sender-id="' + senderId + '" data-recipent-id="' + recipentId + '" data-order-id="' + orderId + '" id="addStagesForm">отправить на согласование</a> </div>';
}
htmlInbox = htmlInboxStage + htmlInbox;
$("#order-stages").html(htmlInbox);
}
});
}
setTimeout(function () {
$(".user-block").first().trigger('click');
}, 10);
setTimeout(function () {
$(".order-block").first().trigger('click');
}, 100);
$("#order-stages").on('click', "#addStagesForm", function (e) {
e.preventDefault();
$(".new-stages-form").each(function (i, v) {
$.ajax({
url: '/api/stages/',
type: 'POST',
beforeSend: function (xhr) {
xhr.setRequestHeader("X-CSRFToken", getCookie('csrftoken'))
},
data: $(this).serialize(),
dataType: 'json',
success: function (json) {
console.log(json);
},
error: function (e) {
console.log(e);
}
});
});
$(".update-stages-form").each(function (i, v) {
var currentStageId = parseInt($(this).attr('data-stage-id'));
$.ajax({
url: '/api/stages/' + currentStageId + '/',
type: 'PUT',
beforeSend: function (xhr) {
xhr.setRequestHeader("X-CSRFToken", getCookie('csrftoken'))
},
data: $(this).serialize(),
dataType: 'json',
success: function (json) {
console.log(json);
},
error: function (e) {
console.log('error');
console.log(e);
}
});
});
var currentOrderId = $(this).attr('data-order-id');
var currentRecipentId = $(this).attr('data-recipent-id');
getStages(currentOrderId, userId, currentRecipentId);
socket.send_stages_approve({
"format_type": "approve_stages",
"data": {
"sender_id": userId,
"recipent_id": currentRecipentId,
"order_id": currentOrderId,
}
});
});
$('#order-stages-tab').on('change', '#countStage', function () {
var countStage = parseInt($(this).val());
var currentCountStage = $(".numberStepp").length;
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 = '<div class="numberStepp box-sizing" id="stage1">' +
'<p>Этап <span class="stage-span-id">' + pos + '</span></p><form class="new-stages-form" id="stage-form">' +
'<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="form-control" name="result" type="text" />' +
'<label for="">Позиция</label><input class="form-control" name="pos" value="' + pos + '" type="text" />'
'</form></div>';
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();
}
ii--;
});
}
});
$('.order-block').on('click', function () {
$("#chat-order-add").css("display", "block");
$("#formsetStage").css("display", "block");
$('.order-block').each(function () {
$(this).removeClass('orAct');
});
$(this).addClass('orAct');
var orderId = $(this).attr('data-id');
var recipentId = $(this).attr('data-recipent-id');
$("#chat-order-add #orderId").val(orderId);
$("#projectReviewId").val(orderId);
$("#reserve-button").attr('data-order-id', orderId);
$("#targetContractorId").val(recipentId);
$("#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);
});
// Вытащить сообщения для конактов
$('.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) {
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>';
});
}
});
});
$('#contact-chat-add-message').on('click', function (e) {
e.preventDefault();
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,
}
});
$("#chat").val("");
});
$('#order-review-add').on('click', function () {
alert('add review');
});
$('#order-chat-add-message').on('click', function (e) {
e.preventDefault();
var chatMessage = $("#chat-order-add #chat").val();
var recipentId = $("#chat-order-add #recipentId").val();
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,
}
});
$("#chat-order-add #chat").val("");
});
});
var userId = '{{ request.user.pk }}';

@ -162,6 +162,18 @@
</div>
<div class="stepssBlock box-sizing disTab" id="completeWork">
<p class="titleStepss">3 / Выполнение работы</p>
<p class="textStepss">
Процесс выполнения задания в заказе до получения
заказчиком итогового результата работы.
</p>
<div id="stagesWork" class="stages-work textAreaBlock2">
</div>
</div>
<div class="textAreaBlock2 box-sizing disTab">
<ul class="notes-block">
</ul>
@ -275,14 +287,6 @@
var form = document.getElementById('message_form');
var csrftoken = getCookie('csrftoken');
setTimeout(function () {
$(".user-block").first().trigger('click');
}, 10);
setTimeout(function () {
$(".order-block").first().trigger('click');
}, 100);
setTimeout(function () {
$(".team-order-block").first().trigger('click');
}, 1000);
@ -454,9 +458,14 @@
console.log(json.results);
var htmlInbox = "";
var stagesReservedHtml = "";
var stagesPaidProcess = [];
if (json.results.length > 0) {
$.each(json.results, function (i, v) {
if ((v.status == "in_process") && (v.is_paid)){
stagesPaidProcess.push(v);
}
if (v.is_paid) {
stagesReservedHtml += '<li class="reserved">Сумма за этап ' + v.pos + '.Зарезервирована.</li>';
} else {
@ -465,7 +474,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.status + '</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>';
});
htmlInbox += '<div class="textAreaBlock2 FFD box-sizing disTab"><a id="approve-stages" href="#">согласовать</a></div>';
@ -473,6 +482,20 @@
$("#order-stages").html(htmlInbox);
$(".stages-paid").html(stagesReservedHtml);
if (stagesPaidProcess.length > 0){
$("#completeWork").show();
var stage = stagesPaidProcess[0];
var stageWork = '<p>В работе '+ stage.name +'</p> ' +
'<p>Результат этапа : '+ stage.result +'</p>' +
'<p>Срок сдачи 25.08.2016 <b>' + stage.cost + 'р.</b></p>' +
'<a href="#" class="closeStage" data-stage-id="'+ stage.id +'">Завершить этап</a>' +
'<a href="#">Обратитьсяв арбитраж</a>';
$("#stagesWork").html(stageWork);
}else{
$("#completeWork").hide();
}
}
});
@ -500,6 +523,28 @@
});
});
$('#tab2').on('click','.closeStage', function(e){
e.preventDefault();
var stageId = $(this).attr('data-stage-id');
$.ajax({
url: '/api/stages/' + stageId + '/',
type: 'PATCH',
beforeSend: function (xhr) {
xhr.setRequestHeader("X-CSRFToken", getCookie('csrftoken'))
},
data: "close_contractor=True",
dataType: 'json',
success: function (json) {
alert(json);
console.log(json);
},
error: function (e) {
console.log('error');
console.log(e);
}
});
});
// Вытащить сообщения для конактов

@ -106,7 +106,7 @@
<p>Заказы</p>
{% for order in orders %}
<div class="orderBlock box-sizing order-block"
data-recipent-id="{{ order.order.contractor.pk }}" data-id="{{ order.order.id }}">
id="orderBlock{{ order.order.id }}" data-secure-deal="{% if order.order.secure %}true{% else %}false{% endif %}" data-recipent-id="{{ order.order.contractor.pk }}" data-id="{{ order.order.id }}">
<span class="dimovChat"></span>
<p class="titleOB">{{ order }}</p>
<div class="hideOBB">
@ -156,7 +156,7 @@
<div id="order-stages" class="stepssBlock"></div>
<div class="stepssBlock box-sizing disTab">
<div class="stepssBlock box-sizing disTab" id="reserveSpace" style="display:none;">
<p class="titleStepss">2 / Резервирование</p>
<p class="textStepss">
Резервирование заказчиком суммы оплаты по заказ. Деньги перечисляются и хранятся на
@ -164,7 +164,7 @@
</p>
<div class="textAreaBlock2 FFD box-sizing disTab">
<a href="#" id="reserve-button" data-order-id="" data-toggle="modal" data-target="#reserve-stage-modal">Зарезирвировать</a>
<a href="#" id="reserve-button" data-order-id="">Зарезирвировать</a>
</div>
</div>
@ -173,12 +173,16 @@
{% include 'reverse_stage_modal.html' %}
<!-- Конец блока -->
<div class="stepssBlock box-sizing disTab">
<p class="titleStepss">3 / Выполнение работы</p>
<p class="textStepss">
Процесс выполнения задания в заказе до получения заказчиком итогового результата работы.
</p>
</div>
<div class="stepssBlock box-sizing disTab" id="completeWork">
<p class="titleStepss">3 / Выполнение работы</p>
<p class="textStepss">
Процесс выполнения задания в заказе до получения
заказчиком итогового результата работы.
</p>
<div id="stagesWork" class="stages-work textAreaBlock2">
</div>
</div>
<div class="textAreaBlock2 box-sizing disTab">
@ -188,7 +192,7 @@
</div>
<div class="closeChat closeChat1">
<div class="closeChat closeChat1" id="leaveReview" style="display: none;">
<a href="#" data-toggle="modal" data-target="#review-add">
Закрыть проект<br>и оставить отзыв
</a>
@ -197,54 +201,7 @@
<!-- Review add -->
<div id="review-add" class="modal fade" role="dialog">
<div class="modal-dialog" role="document" style="width:900px;">
<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>
<form id="review-adds-form" method="POST">{% csrf_token %}
<div class="modal-body">
<div style="height: 250px;">
<div class="text-nn box-sizing disTab">
<input type="radio" value="positive"
name="type">Положительный
<input type="radio" value="negative"
name="type">Отрицательный
<input type="radio" value="neutral"
name="type">Нейтральный
</div>
<div class="textAreaBlock2 text-nn box-sizing disTab">
<textarea cols="40" name="text" rows="10"></textarea>
<input type="hidden" name="from_customer"
value="{{ request.user.pk }}"/>
<input type="hidden" name="target_contractor"
id="targetContractorId"/>
<input type="hidden" name="project" id="projectReviewId"/>
</div>
</div>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-default" data-dismiss="modal">Закрыть
</button>
<button type="submit" id="order-review-add" class="btn btn-primary">Оставить
отзыв
</button>
</div>
</form>
</div>
</div>
</div>
{% include 'review_add_modal.html' %}
<!-- -->
</div>
@ -273,20 +230,64 @@
var csrftoken = getCookie('csrftoken');
$("#reserve-button").on("click",function(e) {
e.preventDefault();
e.preventDefault();
$("#reserve-stage-modal").modal('show');
var orderId = $(this).attr('data-order-id');
$.ajax({
url: '/api/stages/',
type: 'GET',
data: {csrfmiddlewaretoken: csrftoken, 'order': orderId},
dataType: 'json',
success: function (json) {
console.log(json.results);
}
});
$.ajax({
url: '/api/stages/',
type: 'GET',
data: {csrfmiddlewaretoken: csrftoken, 'order': orderId},
dataType: 'json',
success: function (json) {
var outputValues = '';
var totalSum = 0;
var stagesIds = '';
$.each(json.results, function (i, v) {
console.log(v.cost);
totalSum += parseInt(v.cost);
outputValues += '<option data-stage-sum="' + v.cost + '" value="'+ v.id +'">' + v.name + '</option>';
stagesIds += v.id + ';'
});
$("#stagesSelect").html(outputValues);
$(".totalSum").text(totalSum);
$("#choiceWayOrder").val(totalSum)
$("#stages-pay-form #stageSumPay").val(totalSum);
$("#stages-pay-form #stagesIds").val(stagesIds);
$("#choiceWayOrder").attr('data-stages-ids',stagesIds);
}
});
});
$("#tab2").on("change","input[name=choice_way]:radio", function(e){
var sumStage = $("#stagesSelect").find('option:selected').attr('data-stage-sum');
var currIdStage = $("#stagesSelect").find('option:selected').val();
$("#choiceWayStage").val(sumStage);
var currValue = $(this).val();
$("#stages-pay-form #stageSumPay").val(currValue);
var selectId = ($(this).attr('id'));
if (selectId == 'choiceWayOrder'){
$("#stages-pay-form #stagesIds").val($(this).attr('data-stages-ids'));
$("#stagesSelect").prop('disabled', 'disabled');
}else {
$("#stages-pay-form #stagesIds").val(currIdStage);
$("#stagesSelect").prop('disabled', false);
}
});
$("#tab2").on("change","#stagesSelect", function(e){
var sumStage = $(this).find('option:selected').attr("data-stage-sum");
$("#choiceWayStage").val(sumStage);
$("#stages-pay-form #stageSumPay").val(sumStage);
$("#stages-pay-form #stagesIds").val($(this).val());
});
function getStages(orderId, senderId, recipentId) {
//Получить заказы
function getStages(orderId, senderId, recipentId, secureOrder) {
$.ajax({
url: '/api/stages/',
@ -296,6 +297,7 @@
success: function (json) {
var stageCount = json.results.length;
if (stageCount == 0) {
$("#reserveSpace").hide();
stageCountVal = 1;
} else {
stageCountVal = stageCount;
@ -314,11 +316,17 @@
'<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="form-control" name="result" type="text" />' +
'<label for="">Позиция</label><input class="form-control" name="pos" value="1" type="text" />' +
'<input class="form-control" name="pos" value="1" type="hidden" />' +
'</form></div>';
}
var statusNotAgreed = true;
var stagesPaidProcess = [];
$.each(json.results, function (i, v) {
if ((v.status == "in_process") && (v.is_paid)){
stagesPaidProcess.push(v);
}
if (v.status == "not_agreed") {
htmlInbox += '<div class="numberStepp box-sizing">' +
'<p>Этап</p><form class="update-stages-form" data-stage-id="' + v.id + '" id="stage-form-' + v.pos + '">' +
@ -334,30 +342,73 @@
htmlInbox += '<div class="numberStepp box-sizing"><div class="insetNumStepp">' +
'<p class="titleNumStepp"><span>Этап ' + v.pos + '</span>' + v.name + '</p>' +
'<p class="textNumStepp">Результаты этапа:' + v.result + '</p><div>' +
'<p>до Дата</p><span>' + v.cost + '<i class="fa fa-rub"></i></span></div></div></div>';
'<p>до Дата</p><span>' + v.cost + '<i class="fa fa-rub"></i></span>' +
'</div></div></div>';
}
});
if (statusNotAgreed) {
htmlInbox += '<div class="box-sizing disTab" style="text-align:center;"><div class="checkbox"><input type="checkbox" style="opacity:1">Перейти в режим безопасной сделки' +
'</div></div><div class="textAreaBlock2 box-sizing disTab">' +
'<a href="#" data-sender-id="' + senderId +'" data-recipent-id="' + recipentId +'" data-order-id="' + orderId + '" id="addStagesForm">отправить на согласование</a> </div>';
if(secureOrder) {
var orderSecureCheckbox = 'checked="checked"';
htmlInbox += '<div class="box-sizing disTab">' +
'<div class="checkbox"><input name="secure" id="secureOrder"'+ orderSecureCheckbox +'type="checkbox" style="opacity:1">' +
'Перейти в режим безопасной сделки</div></div>';
}
htmlInbox +='<div class="textAreaBlock2 box-sizing disTab">' +
'<a href="#" data-sender-id="' + senderId +'" ' +
'data-recipent-id="' + recipentId +'" data-order-id="' + orderId + '" ' +
'id="addStagesForm">отправить на согласование</a> </div>';
}else if(json.results.length>0){
$("#reserveSpace").show();
}
htmlInbox = htmlInboxStage + htmlInbox;
$("#order-stages").html(htmlInbox);
if (stagesPaidProcess.length > 0){
$("#completeWork").show();
var stage = stagesPaidProcess[0];
var stageWork = '<p>В работе '+ stage.name +'</p> ' +
'<p>Результат этапа : '+ stage.result +'</p>' +
'<p>Срок сдачи 25.08.2016 <b>' + stage.cost + 'р.</b></p>';
if (stage.close_contractor){
stageWork += '<a href="#" class="closeStage" data-stage-id="'+ stage.id+'">Закрыть этап '+ stage.pos +'</a>';
}
$("#stagesWork").html(stageWork);
}else{
$("#completeWork").hide();
}
}
});
}
setTimeout(function () {
$(".user-block").first().trigger('click');
}, 10);
//Закрыть этап
$('#tab2').on('click','.closeStage', function(e){
e.preventDefault();
var stageId = $(this).attr('data-stage-id');
$.ajax({
url: '/api/stages/' + stageId + '/',
type: 'PATCH',
beforeSend: function (xhr) {
xhr.setRequestHeader("X-CSRFToken", getCookie('csrftoken'))
},
data: {close_customer: true, status: 'completed'},
dataType: 'json',
success: function (json) {
console.log(json);
},
error: function (e) {
console.log('error');
console.log(e);
}
});
});
setTimeout(function () {
$(".order-block").first().trigger('click');
}, 100);
// Добавление этапов
$("#order-stages").on('click', "#addStagesForm", function (e) {
e.preventDefault();
$(".new-stages-form").each(function (i, v) {
@ -403,11 +454,10 @@
});
});
var currentOrderId = $(this).attr('data-order-id');
var currentRecipentId = $(this).attr('data-recipent-id');
getStages(currentOrderId,userId,currentRecipentId);
var secureOrder = true
getStages(currentOrderId,userId,currentRecipentId,secureOrder);
socket.send_stages_approve({
"format_type": "approve_stages",
@ -421,6 +471,7 @@
});
//Изменение счетчика
$('#order-stages-tab').on('change', '#countStage', function () {
var countStage = parseInt($(this).val());
var currentCountStage = $(".numberStepp").length;
@ -437,11 +488,9 @@
'<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="form-control" name="result" type="text" />' +
'<label for="">Позиция</label><input class="form-control" name="pos" value="'+ pos +'" type="text" />'
'<input class="form-control" name="pos" value="'+ pos +'" type="hidden" />'
'</form></div>';
lastFormStage.after(addFormTemplate);
}
}else if (countStage < currentCountStage) {
@ -456,6 +505,7 @@
}
});
// Для заказов все вытащить
$('.order-block').on('click', function () {
$("#chat-order-add").css("display", "block");
$("#formsetStage").css("display", "block");
@ -467,6 +517,8 @@
$(this).addClass('orAct');
var orderId = $(this).attr('data-id');
var recipentId = $(this).attr('data-recipent-id');
var secureOrder = $(this).attr('data-secure-deal');
secureOrder = Boolean(secureOrder);
$("#chat-order-add #orderId").val(orderId);
$("#projectReviewId").val(orderId);
$("#reserve-button").attr('data-order-id', orderId);
@ -496,7 +548,7 @@
});
}
});
getStages(orderId,userId,recipentId);
getStages(orderId,userId,recipentId, secureOrder);
});
// Вытащить сообщения для конактов
@ -557,8 +609,28 @@
$("#chat").val("");
});
$('#order-review-add').on('click', function () {
alert('add review');
// Добавление отзыва
$('#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("Успешно");
console.log(json);
},
error: function (e) {
console.log('error');
console.log(e);
}
});
});
$('#order-chat-add-message').on('click', function (e) {

@ -12,13 +12,13 @@
<div class="searchF1 polsF1 polsFF radio-afer">
<div class="col-lg-6">
<label>
<input type="radio" name="choice_way" value="secure_deal">
<input data-stages-ids="" type="radio" checked="checked" id="choiceWayOrder"name="choice_way" value="">
<span></span>
</label>
<p class="text-afer">Сумма оплаты всего заказа</p>
<p class="des-afer">
Общий бюджет заказа: 300 р. <br />
Итого к оплате: 344 рубля
Общий бюджет заказа: <span class="totalSum" id="totalSum"></span>р. <br />
Итого к оплате: <span class="totalSum"></span> р.
</p>
</div>
</div>
@ -26,28 +26,45 @@
<div class="searchF1 polsF1 polsFF radio-afer">
<div class="col-lg-6">
<label>
<input type="radio" name="choice_way" value="choice_way">
<input type="radio" name="choice_way" id="choiceWayStage" value="">
<span></span>
</label>
<p class="text-afer">Оплатить этап</p><br />
<p class="text-afer" style="width: 250px;">Оплатить этап</p><br />
<p class="des-afer">
Бюджет Этапа 1: 300 р.<br />
Итого к оплате: 344 р.
Бюджет Этапа 1: <span class="stageSum"></span>р.<br />
Итого к оплате: <span class="stageSum"></span> р.
</p>
</div>
<div class="col-lg-6">
<select class="selectpicker">
<option>Этап1</option>
<option>Этап1</option>
<option>Этап1</option>
<select id="stagesSelect">
</select>
</div>
</div>
<div class="searchF1 polsF1 polsFF radio-afe" style="padding-top: 20px;padding-left: 50px;">
<p class="titleStepss">Резервирование средств</p>
<form id="stages-pay-form" action="{{ YANDEX_MONEY.url }}" method="POST">{% csrf_token %}
<div class="modal-body">
<div style="height: 150px;">
<div class="textAreaBlock2 text-nn box-sizing disTab">
<p>Кол-во денег {{ transaction.pk }} </p>
<input type="text" name="sum" id="stageSumPay">
<input type='hidden' name='shopId' value='{{ YANDEX_MONEY.shop_id }}'>
<input type='hidden' name='scid' value='{{ YANDEX_MONEY.scid }}'>
<input type='hidden' name='customerNumber' value='{{ user_score.pk }}'>
<input type='hidden' name='paymentType' value='AC'>
<input type='hidden' name='transactionId' value='{{ transaction.pk }}'>
<input type='text' name='stagesId' id='stagesIds' value=''>
</div>
</div>
</div>
<div class="modal-footer">
<button type="submit" class="btn btn-primary">Пополнить</button>
</div>
</form>
</div>
</div>

@ -0,0 +1,49 @@
<div id="review-add" class="modal fade" role="dialog">
<div class="modal-dialog" role="document" style="width:900px;">
<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>
<form id="review-adds-form" method="POST">
<div class="modal-body">
<div style="height: 250px;">
<div class="searchF1 polsF1 polsFF radio-afer">
<input type="radio" value="positive"
name="type">Положительный
<input type="radio" value="negative"
name="type">Отрицательный
<input type="radio" value="neutral"
name="type">Нейтральный
</div>
<div class="textAreaBlock2 text-nn box-sizing disTab">
<p>Ваш отзыв</p>
<textarea id="text-new" name="text"></textarea>
<input type="hidden" name="from_customer" value="{{ request.user.pk }}"/>
<input type="hidden" name="target_contractor" id="targetContractorId"/>
<input type="hidden" name="project" id="projectReviewId"/>
<input type="hidden" name="target_team">
<input type="hidden" name="target_customer">
<input type="hidden" name="from_contractor">
<input type="hidden" name="from_team">
</div>
</div>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-default" data-dismiss="modal">Закрыть
</button>
<button type="button" id="order-review-add" class="btn btn-primary">Оставить
отзыв
</button>
</div>
</form>
</div>
</div>
</div>

@ -1,5 +1,6 @@
import json
from django.shortcuts import render
from django.conf import settings
from django.views.generic import View
from django.http import HttpResponse, Http404
from django.db.models import Q
@ -7,6 +8,7 @@ from django.contrib.auth.mixins import LoginRequiredMixin
from .models import Message
from projects.models import Order
from wallets.models import Transaction
from users.models import User, Team
@ -16,7 +18,7 @@ class ChatUserView(LoginRequiredMixin, View):
def get(self, request, *args, **kwargs):
# import code; code.interact(local=dict(globals(), **locals()))
user_id = request.GET.get('user_id',None)
if request.user.is_authenticated() and request.user.is_customer():
if request.user.is_customer():
customer_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()
@ -34,10 +36,15 @@ class ChatUserView(LoginRequiredMixin, View):
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)
transaction = Transaction.objects.get_or_create(customer=request.user, type='reservation')
print(transaction)
self.template_name = 'chat_customer.html'
return render(request, self.template_name, {'contacts_users': contacts_users,
'chat_messages': chat_messages,
'orders': orders})
'orders': orders,
'transaction': transaction[0],
'YANDEX_MONEY': settings.YANDEX_MONEY,
})
else:
orders = request.user.orders.all()
contractor_contacts = Message.objects.values_list('sender_id', 'recipent_id').filter(
@ -60,13 +67,13 @@ class ChatUserView(LoginRequiredMixin, View):
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()
# team_orders = []
self.template_name = 'chat_contractor.html'
return render(request, self.template_name, {'orders': orders,
'contacts_users': contacts_users,
'chat_messages': chat_messages,
'team_orders': team_orders,
})

@ -0,0 +1,29 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.9.7 on 2016-08-23 22:54
from __future__ import unicode_literals
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('projects', '0013_auto_20160819_1735'),
]
operations = [
migrations.AlterModelOptions(
name='project',
options={'ordering': ('-created',), 'verbose_name': 'Проект', 'verbose_name_plural': 'Проекты'},
),
migrations.AddField(
model_name='stage',
name='close_contractor',
field=models.BooleanField(default=False),
),
migrations.AddField(
model_name='stage',
name='close_customer',
field=models.BooleanField(default=False),
),
]

@ -0,0 +1,20 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.9.7 on 2016-08-24 08:19
from __future__ import unicode_literals
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('projects', '0014_auto_20160824_0154'),
]
operations = [
migrations.AlterField(
model_name='order',
name='status',
field=models.CharField(choices=[('created', 'Создан'), ('process', 'В процессе'), ('completed', 'Завершен')], default='created', max_length=30),
),
]

@ -0,0 +1,16 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.9.7 on 2016-08-24 14:23
from __future__ import unicode_literals
from django.db import migrations
class Migration(migrations.Migration):
dependencies = [
('projects', '0015_auto_20160824_1538'),
('projects', '0015_auto_20160824_1119'),
]
operations = [
]

@ -199,12 +199,17 @@ class AnswerFile(models.Model):
class Order(models.Model):
STATUSES = (
('created', 'Создан'),
('process', 'В процессе'),
('completed', 'Завершен'),
)
contractor = models.ForeignKey(User, null=True, blank=True, related_name='orders')
team = models.ForeignKey(Team, null=True, blank=True, related_name='orders')
created = models.DateTimeField(default=timezone.now)
project = models.OneToOneField(Project, related_name='order')
secure = models.BooleanField(default=False)
status = models.BooleanField(default=False)
status = models.CharField(max_length=30, choices=STATUSES, default='created')
def __str__(self):
return self.project.name
@ -233,6 +238,8 @@ class Stage(models.Model):
created = models.DateTimeField(default=timezone.now)
pos = models.IntegerField(default=0, null=True, blank=True)
is_paid = models.BooleanField(default=False)
close_contractor = models.BooleanField(default=False)
close_customer = models.BooleanField(default=False)
def __str__(self):
return self.name

@ -80,6 +80,8 @@ class StageSerializer(ModelSerializer):
'pos',
'status',
'is_paid',
'close_contractor',
'close_customer',
)

@ -357,8 +357,12 @@ class CustomerProjectCreateView(BaseMixin, View):
project.save()
form.save_m2m()
Order.objects.create(project=project)
secure = False
if 'secure_deal' in project.deal_type:
secure = True
Order.objects.create(project=project, secure=secure)
for file in request.FILES.getlist('new_files'):
ProjectFile.objects.create(file=file, project=project)

@ -41,3 +41,4 @@ django-mathfilters
gunicorn==19.6.0
rest-framework-generic-relations
django-hitcount
django-activeurl==0.1.9

@ -1,6 +1,7 @@
{% load staticfiles %}
{% load thumbnail %}
{% load user_tags %}
{% load activeurl %}
<div class="wrTop {% if request.user.is_authenticated %} disTab {% endif %}">
<div class="container-fluid topMain">
@ -8,7 +9,7 @@
<div class="col-lg-3">
<div class="logo" onClick="window.location='/'"></div>
</div>
{% activeurl %}
{% if request.user.is_authenticated %}
<div class="col-lg-7">
<ul class="mainMenu">
@ -54,7 +55,7 @@
</ul>
</div>
{% endif %}
{% endactiveurl %}
{% if request.user.is_authenticated %}
<div class="col-lg-2">
<div class="imgProfile">

@ -0,0 +1,20 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.9.7 on 2016-08-24 12:53
from __future__ import unicode_literals
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('wallets', '0008_wallet'),
]
operations = [
migrations.AddField(
model_name='transaction',
name='stages_id',
field=models.CharField(blank=True, max_length=100, null=True),
),
]

@ -70,6 +70,7 @@ class Transaction(models.Model):
voids_at = models.DateTimeField()
sum = models.DecimalField(max_digits=20, decimal_places=0, default=0)
type = models.CharField(max_length=20, choices=TYPES, default='add')
stages_id = models.CharField(max_length=100, null=True, blank=True)
def save(self, *args, **kwargs):
if not self.pk and self.created_at:

@ -33,13 +33,14 @@ class ScoreView(LoginRequiredMixin, View):
template_name = 'score-detail.html'
def get(self, request, *args, **kwargs):
transaction = Transaction.objects.create(customer=request.user, type='add')
# transaction = Transaction.objects.get_or_create(customer=request.user, complete=False)
transaction = Transaction.objects.get_or_create(customer=request.user, type='add')
user_score = get_object_or_404(User.objects, pk=kwargs.get('pk'))
current_sum_info = InvoiceHistory.objects.filter(user=user_score).aggregate(Sum('sum'))
user_score_balance = current_sum_info['sum__sum'] or 0
return render(request, self.template_name, {
'transaction': transaction,
'transaction': transaction[0],
'YANDEX_MONEY': settings.YANDEX_MONEY,
'user_score': user_score,
'user_score_balance': user_score_balance,

Loading…
Cancel
Save