#ARC-18 add close stages and reviews for customers

remotes/origin/PR-39
Mukhtar 10 years ago
parent 60bffa4337
commit f3a1d023b8
  1. 9
      assets/js/chat.js
  2. 320
      assets/js/chat_customer.js
  3. 63
      chat/templates/chat_contractor.html
  4. 191
      chat/templates/chat_customer.html
  5. 14
      chat/templates/reverse_stage_modal.html
  6. 49
      chat/templates/review_add_modal.html
  7. 29
      projects/migrations/0014_auto_20160824_0154.py
  8. 2
      projects/models.py
  9. 2
      projects/serializers.py

@ -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 }}';

@ -156,6 +156,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>
@ -269,14 +281,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);
@ -448,9 +452,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 {
@ -459,7 +468,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>';
@ -467,6 +476,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();
}
}
});
@ -494,6 +517,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);
}
});
});
// Вытащить сообщения для конактов

@ -159,7 +159,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>
@ -168,12 +168,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">
@ -192,54 +196,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>
@ -268,19 +225,33 @@
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;
$.each(json.results, function (i, v) {
console.log(v.cost);
totalSum += parseInt(v.cost);
outputValues += "<option value='"+ v.id +"'>" + v.name + "</option>";
});
$("#stagesSelect").html(outputValues);
$(".totalSum").text(totalSum);
}
});
});
//Получить заказы
function getStages(orderId, senderId, recipentId) {
$.ajax({
@ -313,7 +284,13 @@
'</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 + '">' +
@ -329,30 +306,67 @@
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>';
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);
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) {
@ -398,7 +412,6 @@
});
});
var currentOrderId = $(this).attr('data-order-id');
var currentRecipentId = $(this).attr('data-recipent-id');
@ -416,6 +429,7 @@
});
//Изменение счетчика
$('#order-stages-tab').on('change', '#countStage', function () {
var countStage = parseInt($(this).val());
var currentCountStage = $(".numberStepp").length;
@ -451,6 +465,7 @@
}
});
// Для заказов все вытащить
$('.order-block').on('click', function () {
$("#chat-order-add").css("display", "block");
$("#formsetStage").css("display", "block");
@ -552,8 +567,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) {

@ -17,8 +17,8 @@
</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>
@ -31,17 +31,13 @@
</label>
<p class="text-afer">Оплатить этап</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>

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

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

@ -233,6 +233,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',
)

Loading…
Cancel
Save