#ARC-18 Add stages for order

remotes/origin/setup
Mukhtar 10 years ago
parent 61d73035b6
commit 0dfbce1186
  1. 152
      chat/templates/chat_contractor.html
  2. 52
      chat/templates/chat_customer.html
  3. 2
      chat/testapp.py
  4. 6
      projects/admin.py
  5. 2
      projects/filters.py
  6. 37
      projects/migrations/0002_auto_20160725_1605.py
  7. 22
      projects/migrations/0003_auto_20160725_1606.py
  8. 11
      projects/models.py
  9. 3
      projects/serializers.py
  10. 3
      requirements/base.txt
  11. 25
      users/migrations/0002_auto_20160725_1605.py

@ -164,15 +164,6 @@
</div> </div>
<div class="col-lg-6 commChat"> <div class="col-lg-6 commChat">
<div id="message-chat-order-space"> <div id="message-chat-order-space">
{# {% for msg in chat_messages %}#}
{# <div class="col-lg-12 insetCommChat {% if msg.sender.pk == request.user.pk %}youChat{% endif %}">#}
{# <div class="topCommChat">#}
{# <p class="nameCommChat {% if msg.sender.pk == request.user.pk %}greenNCC{% endif %}">{{ msg.sender.get_full_name }}</p>#}
{# <span>{{ msg.created }}</span>#}
{# </div>#}
{# <p class="textCommChat">{{ msg }}</p>#}
{# </div>#}
{# {% endfor %}#}
</div> </div>
<form id="chat-contractor-order"> <form id="chat-contractor-order">
<input type="text" id="orderId"/> <input type="text" id="orderId"/>
@ -187,11 +178,21 @@
Не более 10 файлов с общим объемом 500мб Не более 10 файлов с общим объемом 500мб
</span> </span>
</div> </div>
<a href="javascript:void(0)">отправить</a> <a href="javascript:void(0)" id="order-chat-add-message">отправить</a>
</div> </div>
</form> </form>
</div> </div>
<div class="col-lg-3 wrTAB"> <div class="col-lg-3 wrTAB">
<p>Этапы работы</p>
<div class="stepssBlock box-sizing disTab">
<p class="titleStepss">1 / Согласование условий</p>
<p class="textStepss">
Обсуджение задания и условий выполнения работы. Подтверждение заказа исполнителем.
</p>
</div>
<div id="order-stages"></div>
<div class="textAreaBlock2 box-sizing disTab"> <div class="textAreaBlock2 box-sizing disTab">
<p>Для заметок</p> <p>Для заметок</p>
<textarea id="chat2"></textarea> <textarea id="chat2"></textarea>
@ -225,52 +226,9 @@
</a> </a>
</div> </div>
</div> </div>
<div class="orderBlock box-sizing">
<span class="dimovChat"></span>
<p class="titleOB">
Дизай-проект квартиры на набережной 200 m2
</p>
<div class="hideOBB disTab">
<p class="pOB">
<span>Заказчик:</span> Группа Икс
</p>
<ul class="listChat1">
<li>Иванов Петр Иванович</li>
<li>Сергей Пенкин</li>
</ul>
<a href="javascript:void(0)" class="linkChat11">
<span class="glyphicon glyphicon-info-sign" aria-hidden="true"></span>
Полное описание заказа
</a>
</div>
</div>
</div> </div>
</div> </div>
<div class="col-lg-6 commChat"> <div class="col-lg-6 commChat">
<div class="col-lg-12 insetCommChat">
<div class="topCommChat">
<p class="nameCommChat">
Иванов Петр Иванович
</p>
<span>
13.0.2016 / 21:05
</span>
</div>
<p class="textCommChat">
Lorem ipsum dolor sit amet, consectetur adipiscing elit</p>
</div>
<div class="col-lg-12 insetCommChat youChat">
<div class="topCommChat">
<p class="nameCommChat greenNCC">
Вы
</p>
<span>
13.0.2016 / 21:05
</span>
</div>
<p class="textCommChat">
Lorem ipsum dolor sit amet, consectetur adipiscing elit.</p>
</div>
<textarea id="chat" class="box-sizing"></textarea> <textarea id="chat" class="box-sizing"></textarea>
<div class="bunChat"> <div class="bunChat">
<div class="setChat box-sizing"> <div class="setChat box-sizing">
@ -290,34 +248,8 @@
Обсуджение задания и условий выполнения работы. Подтверждение заказа исполнителем. Обсуджение задания и условий выполнения работы. Подтверждение заказа исполнителем.
</p> </p>
</div> </div>
<div class="numberStepp box-sizing"> <div id="order-stages"></div>
<div class="insetNumStepp">
<p class="titleNumStepp">
<span>Этап 1</span>Название этапа
</p>
<p class="textNumStepp">
Результаты этапа: Готовый чертеж 1
</p>
<div>
<p>до 16.03.2015</p>
<span>30 000 <i class="fa fa-rub"></i></span>
</div>
</div>
</div>
<div class="numberStepp box-sizing">
<div class="insetNumStepp">
<p class="titleNumStepp">
<span>Этап 2</span>Название этапа
</p>
<p class="textNumStepp">
Результаты этапа: Готовый чертеж 1
</p>
<div>
<p>до 16.03.2015</p>
<span>30 000 <i class="fa fa-rub"></i></span>
</div>
</div>
</div>
<div class="textAreaBlock2 FFD box-sizing disTab"> <div class="textAreaBlock2 FFD box-sizing disTab">
<a href="javascript:void()">согласовать</a> <a href="javascript:void()">согласовать</a>
</div> </div>
@ -368,13 +300,17 @@
}; };
sock.onmessage = function (event) { sock.onmessage = function (event) {
console.log(event.data); console.log(event.data);
alert(event.data);
var message = JSON.parse(event.data); var message = JSON.parse(event.data);
var inbox = document.getElementById('message-chat-space'); var inbox;
if (message.answer_type == 'contact') {
inbox = document.getElementById('message-chat-space');
} else if (message.answer_type == 'order' || message.answer_type == 'add_order') {
inbox = document.getElementById('message-chat-order-space');
}
inbox.innerHTML += '<div class="col-lg-12 insetCommChat"><div class="topCommChat">' + inbox.innerHTML += '<div class="col-lg-12 insetCommChat"><div class="topCommChat">' +
'<p class="nameCommChat">Иванов</p> <span>13.0.2016</span></div>' + '<p class="nameCommChat">ВЫ</p> <span>13.0.2016</span></div>' +
'<p class="textCommChat">' + message.msg + '</p></div>'; '<p class="textCommChat">' + message.msg + '</p></div>';
}; };
this.send_contact_message = function (userId) { this.send_contact_message = function (userId) {
@ -419,11 +355,10 @@
var orderId = $(this).attr('data-id'); var orderId = $(this).attr('data-id');
var recipentId = $(this).attr('data-recipent-id'); var recipentId = $(this).attr('data-recipent-id');
$("#chat-contractor-order #orderId").val(orderId); $("#chat-contractor-order #orderId").val(orderId);
$("#chat-contractor-order #recipentId").val(recipentId); $("#chat-contractor-order #recipentOrderId").val(recipentId);
var inbox = document.getElementById('message-chat-order-space'); var inbox = document.getElementById('message-chat-order-space');
inbox.innerHTML = ''; inbox.innerHTML = '';
$.ajax({ $.ajax({
url: '/api/message', url: '/api/message',
type: 'GET', type: 'GET',
@ -434,7 +369,7 @@
var senderName = 'Вы'; var senderName = 'Вы';
var className = 'youChat'; var className = 'youChat';
if (v.sender.id == currentChatUser) { if (v.sender.id !== currentChatUser) {
senderName = v.sender.username; senderName = v.sender.username;
className = ''; className = '';
} }
@ -445,6 +380,25 @@
} }
}); });
$.ajax({
url: '/api/stages/',
type: 'GET',
data: {csrfmiddlewaretoken: csrftoken, 'order': orderId},
dataType: 'json',
success: function (json) {
console.log(json.results);
var htmlInbox = "";
$.each(json.results, function (i, v) {
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>до 16.03.2015</p><span>'+ v.cost +'<i class="fa fa-rub"></i></span></div></div></div>';
});
$("#order-stages").html(htmlInbox);
}
});
}); });
// Вытащить сообщения для конактов // Вытащить сообщения для конактов
@ -465,7 +419,6 @@
dataType: 'json', dataType: 'json',
success: function (json) { success: function (json) {
$.each(json.results, function (i, v) { $.each(json.results, function (i, v) {
console.log(v.sender.id); console.log(v.sender.id);
var senderName = 'Вы'; var senderName = 'Вы';
var className = 'youChat'; var className = 'youChat';
@ -473,7 +426,6 @@
senderName = v.sender.username; senderName = v.sender.username;
className = ''; className = '';
} }
inbox.innerHTML += '<div class="col-lg-12 insetCommChat ' + className + '"><div class="topCommChat">' + inbox.innerHTML += '<div class="col-lg-12 insetCommChat ' + className + '"><div class="topCommChat">' +
'<p class="nameCommChat">' + senderName + '</p> <span>' + v.created + '</span></div>' + '<p class="nameCommChat">' + senderName + '</p> <span>' + v.created + '</span></div>' +
'<p class="textCommChat">' + v.text + '</p></div>'; '<p class="textCommChat">' + v.text + '</p></div>';
@ -506,6 +458,26 @@
$("#chat").val(""); $("#chat").val("");
}); });
$('#order-chat-add-message').on('click', function () {
var chatMessage = $("#chat-contractor-order #chat").val();
var recipentId = $("#chat-contractor-order #recipentOrderId").val();
var senderId = $("#chat-contractor-order #senderOrderId").val();
var orderId = $("#chat-contractor-order #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-contractor-order #chat").val("");
});
}); });
</script> </script>

@ -157,9 +157,9 @@
</div> </div>
<form id="chat-order-add"> <form id="chat-order-add">
<input type="text" name="senderId" id="senderId" value="{{ request.user.pk }}"/> <input type="hidden" name="senderId" id="senderId" value="{{ request.user.pk }}"/>
<input type="text" name="recipentId" id="recipentId" value=""/> <input type="hidden" name="recipentId" id="recipentId" value=""/>
<input type="text" name="orderId" id="orderId" value=""/> <input type="hidden" name="orderId" id="orderId" value=""/>
<textarea id="chat" class="box-sizing"></textarea> <textarea id="chat" class="box-sizing"></textarea>
<div class="bunChat"> <div class="bunChat">
<div class="setChat box-sizing"> <div class="setChat box-sizing">
@ -198,19 +198,22 @@
<input type="text" value="Результат этапа" /> <input type="text" value="Результат этапа" />
<input type="text" value="Срок этапа" /> <input type="text" value="Срок этапа" />
<input type="text" value="Цена этапа" /> <input type="text" value="Цена этапа" />
<input type="text" value="" class="orderStagesInput" />
</form> </form>
</div> </div>
</div> </div>
<div class="textAreaBlock2 box-sizing disTab"> <div class="textAreaBlock2 box-sizing disTab">
<a href="javascript:void()">сохранить</a> <a href="javascript:void()">сохранить</a>
</div> </div>
</div> </div>
<div class="textAreaBlock2 FFD box-sizing disTab"> <div class="textAreaBlock2 FFD box-sizing disTab">
<a href="javascript:void()">согласовать</a> <a href="javascript:void()">согласовать</a>
</div> </div>
<div id="order-stages"></div>
<div class="textAreaBlock2 box-sizing disTab"> <div class="textAreaBlock2 box-sizing disTab">
<p>Для заметок</p> <p>Для заметок</p>
<textarea id="chat2"></textarea> <textarea id="chat2"></textarea>
@ -260,9 +263,9 @@
var recipentId = $(this).attr('data-recipent-id'); var recipentId = $(this).attr('data-recipent-id');
$("#chat-order-add #orderId").val(orderId); $("#chat-order-add #orderId").val(orderId);
$("#chat-order-add #recipentId").val(recipentId); $("#chat-order-add #recipentId").val(recipentId);
$(".orderStagesInput").val(orderId);
var inbox = document.getElementById('message-chat-order-space'); var inbox = document.getElementById('message-chat-order-space');
inbox.innerHTML = ''; inbox.innerHTML = '';
$.ajax({ $.ajax({
url: '/api/message', url: '/api/message',
type: 'GET', type: 'GET',
@ -270,12 +273,39 @@
dataType: 'json', dataType: 'json',
success: function (json) { success: function (json) {
$.each(json.results, function (i, v) { $.each(json.results, function (i, v) {
inbox.innerHTML += '<div class="col-lg-12 insetCommChat"><div class="topCommChat">' + var senderName = 'Вы';
'<p class="nameCommChat">Иванов</p> <span>13.0.2016</span></div>' + 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>'; '<p class="textCommChat">' + v.text + '</p></div>';
}); });
} }
}); });
$.ajax({
url: '/api/stages/',
type: 'GET',
data: {csrfmiddlewaretoken: csrftoken, 'order': orderId},
dataType: 'json',
success: function (json) {
var htmlInbox = "";
$.each(json.results, function (i, v) {
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>до 16.03.2015</p><span>'+ v.cost +'<i class="fa fa-rub"></i></span></div></div></div>';
});
$("#order-stages").html(htmlInbox);
}
});
}); });
@ -335,7 +365,6 @@
var senderId = $("#chat-order-add #senderId").val(); var senderId = $("#chat-order-add #senderId").val();
var orderId = $("#chat-order-add #orderId").val(); var orderId = $("#chat-order-add #orderId").val();
socket.add_contact_message({ socket.add_contact_message({
"format_type": "add_message_order", "format_type": "add_message_order",
"data": { "data": {
@ -350,8 +379,6 @@
$("#chat-order-add #chat").val(""); $("#chat-order-add #chat").val("");
}); });
}); });
var userId = '{{ request.user.pk }}'; var userId = '{{ request.user.pk }}';
@ -368,13 +395,12 @@
}; };
sock.onmessage = function (event) { sock.onmessage = function (event) {
console.log(event.data); console.log(event.data);
alert(event.data);
var message = JSON.parse(event.data); var message = JSON.parse(event.data);
var inbox; var inbox;
if (message.answer_type == 'contact') { if (message.answer_type == 'contact') {
inbox = document.getElementById('message-chat-order-space');
} else if (message.answer_type == 'order') {
inbox = document.getElementById('message-chat-space'); inbox = document.getElementById('message-chat-space');
} else if (message.answer_type == 'order' || message.answer_type == 'add_order') {
inbox = document.getElementById('message-chat-order-space')
} }
inbox.innerHTML += '<div class="col-lg-12 insetCommChat"><div class="topCommChat">' + inbox.innerHTML += '<div class="col-lg-12 insetCommChat"><div class="topCommChat">' +
'<p class="nameCommChat">Иванов</p> <span>13.0.2016</span></div>' + '<p class="nameCommChat">Иванов</p> <span>13.0.2016</span></div>' +

@ -101,7 +101,7 @@ class TutorialHandler(websocket.WebSocketHandler):
insert_sql = "INSERT INTO chat_message (id,text,created,order_id, sender_id,recipent_id, private_type) " \ insert_sql = "INSERT INTO chat_message (id,text,created,order_id, sender_id,recipent_id, private_type) " \
"VALUES (DEFAULT,'{0}',NOW(),{1},{2},{3},'false')".format(message,order_id, sender_id, recipent_id) "VALUES (DEFAULT,'{0}',NOW(),{1},{2},{3},'false')".format(message,order_id, sender_id, recipent_id)
yield self.db.execute(insert_sql) yield self.db.execute(insert_sql)
waiters = tuple(w for c, w in self.waiters if c == recipent_id) waiters = tuple(w for c, w in self.waiters if c == recipent_id or c == sender_id)
for waiter in waiters: for waiter in waiters:
waiter.write_message({'msg': message, 'answer_type': 'add_order'}) waiter.write_message({'msg': message, 'answer_type': 'add_order'})

@ -32,13 +32,17 @@ class ProjectAdmin(admin.ModelAdmin):
form = ProjectAdminForm form = ProjectAdminForm
class StageAdmin(admin.ModelAdmin):
list_display = ('name','status','pos','order',)
admin.site.register(Answer) admin.site.register(Answer)
admin.site.register(Portfolio) admin.site.register(Portfolio)
admin.site.register(PortfolioPhoto) admin.site.register(PortfolioPhoto)
admin.site.register(Realty) admin.site.register(Realty)
admin.site.register(Order) admin.site.register(Order)
admin.site.register(Candidate) admin.site.register(Candidate)
admin.site.register(Stage) admin.site.register(Stage, StageAdmin)
admin.site.register(BuildingClassfication) admin.site.register(BuildingClassfication)
admin.site.register(ConstructionType) admin.site.register(ConstructionType)
admin.site.register(Project, ProjectAdmin) admin.site.register(Project, ProjectAdmin)

@ -62,6 +62,8 @@ class StageFilterSet(FilterSet):
term = AllLookupsFilter() term = AllLookupsFilter()
cost_type = AllLookupsFilter() cost_type = AllLookupsFilter()
term_type = AllLookupsFilter() term_type = AllLookupsFilter()
status = AllLookupsFilter()
pos = AllLookupsFilter()
order = RelatedFilter('projects.filters.OrderFilterSet') order = RelatedFilter('projects.filters.OrderFilterSet')
class Meta: class Meta:

@ -0,0 +1,37 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.9.7 on 2016-07-25 13:05
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', '0001_initial'),
]
operations = [
migrations.AddField(
model_name='stage',
name='created',
field=models.DateTimeField(default=datetime.datetime(2016, 7, 25, 13, 5, 40, 39347, tzinfo=utc)),
),
migrations.AddField(
model_name='stage',
name='pos',
field=models.IntegerField(blank=True, default=0, null=True),
),
migrations.AddField(
model_name='stage',
name='status',
field=models.CharField(choices=[('not_agreed', 'Не согласован'), ('in_process', 'В процессе'), ('completed', 'Завершен')], default='not_agreed', max_length=30),
),
migrations.AlterField(
model_name='project',
name='deal_type',
field=models.CharField(choices=[('secure_deal', 'Безопасная сделка'), ('direct_payment', 'Прямая оплата')], default='secure_deal', max_length=20),
),
]

@ -0,0 +1,22 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.9.7 on 2016-07-25 13:06
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', '0002_auto_20160725_1605'),
]
operations = [
migrations.AlterField(
model_name='stage',
name='created',
field=models.DateTimeField(default=datetime.datetime(2016, 7, 25, 13, 6, 34, 550741, tzinfo=utc)),
),
]

@ -149,6 +149,13 @@ class Order(models.Model):
verbose_name_plural = 'Заказы' verbose_name_plural = 'Заказы'
STATUSES = (
('not_agreed','Не согласован'),
('in_process','В процессе'),
('completed','Завершен'),
)
class Stage(models.Model): class Stage(models.Model):
cost = models.DecimalField(max_digits=10, decimal_places=0) cost = models.DecimalField(max_digits=10, decimal_places=0)
cost_type = models.CharField(max_length=5, choices=CURRENCIES, default='rur') cost_type = models.CharField(max_length=5, choices=CURRENCIES, default='rur')
@ -157,11 +164,15 @@ class Stage(models.Model):
result = models.CharField(max_length=255) result = models.CharField(max_length=255)
term = models.IntegerField(default=0) term = models.IntegerField(default=0)
term_type = models.CharField(max_length=10, choices=TERMS, default='hour') 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())
pos = models.IntegerField(default=0, null=True, blank=True)
def __str__(self): def __str__(self):
return self.name return self.name
class Meta: class Meta:
ordering = ['pos']
verbose_name = 'Этап' verbose_name = 'Этап'
verbose_name_plural = 'Этапы' verbose_name_plural = 'Этапы'

@ -74,6 +74,9 @@ class StageSerializer(ModelSerializer):
'name', 'name',
'order', 'order',
'result', 'result',
'pos',
'status',
) )

@ -36,5 +36,6 @@ six==1.10.0
sorl-thumbnail==12.3 sorl-thumbnail==12.3
sqlparse==0.1.19 sqlparse==0.1.19
tornado==4.3 tornado==4.3
natsort nats
ort
django-mathfilters django-mathfilters

@ -0,0 +1,25 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.9.7 on 2016-07-25 13:05
from __future__ import unicode_literals
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('users', '0001_initial'),
]
operations = [
migrations.AlterField(
model_name='contractorresume',
name='resume_file',
field=models.FileField(blank=True, null=True, upload_to='users/resume/files/'),
),
migrations.AlterField(
model_name='contractorresume',
name='text',
field=models.TextField(blank=True, null=True),
),
]
Loading…
Cancel
Save