#ARC-18 Add stages reservation

remotes/origin/PR-39
Mukhtar 10 years ago
parent f3a1d023b8
commit dfb2f1d16c
  1. 2
      assets/js/chat.js
  2. 73
      chat/templates/chat_customer.html
  3. 27
      chat/templates/reverse_stage_modal.html
  4. 13
      chat/views.py
  5. 20
      projects/migrations/0015_auto_20160824_1119.py
  6. 7
      projects/models.py
  7. 6
      projects/views.py
  8. 20
      wallets/migrations/0009_transaction_stages_id.py
  9. 1
      wallets/models.py
  10. 4
      wallets/views.py

@ -20,7 +20,7 @@ var SocketHandler = function () {
} else if (message.answer_type == 'add_message_team') { } else if (message.answer_type == 'add_message_team') {
inbox = document.getElementById('message-chat-team-space'); inbox = document.getElementById('message-chat-team-space');
} else if (message.answer_type == 'approve_stages') { } else if (message.answer_type == 'approve_stages') {
alert('approve stages'); console.log('approve stages');
} }
if (inbox) { if (inbox) {
var textMessage = message.msg; var textMessage = message.msg;

@ -101,7 +101,7 @@
<p>Заказы</p> <p>Заказы</p>
{% for order in orders %} {% for order in orders %}
<div class="orderBlock box-sizing order-block" <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> <span class="dimovChat"></span>
<p class="titleOB">{{ order }}</p> <p class="titleOB">{{ order }}</p>
<div class="hideOBB"> <div class="hideOBB">
@ -151,7 +151,7 @@
<div id="order-stages" class="stepssBlock"></div> <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="titleStepss">2 / Резервирование</p>
<p class="textStepss"> <p class="textStepss">
Резервирование заказчиком суммы оплаты по заказ. Деньги перечисляются и хранятся на Резервирование заказчиком суммы оплаты по заказ. Деньги перечисляются и хранятся на
@ -187,7 +187,7 @@
</div> </div>
<div class="closeChat closeChat1"> <div class="closeChat closeChat1" id="leaveReview" style="display: none;">
<a href="#" data-toggle="modal" data-target="#review-add"> <a href="#" data-toggle="modal" data-target="#review-add">
Закрыть проект<br>и оставить отзыв Закрыть проект<br>и оставить отзыв
</a> </a>
@ -235,24 +235,54 @@
data: {csrfmiddlewaretoken: csrftoken, 'order': orderId}, data: {csrfmiddlewaretoken: csrftoken, 'order': orderId},
dataType: 'json', dataType: 'json',
success: function (json) { success: function (json) {
var outputValues = ""; var outputValues = '';
var totalSum = 0; var totalSum = 0;
var stagesIds = '';
$.each(json.results, function (i, v) { $.each(json.results, function (i, v) {
console.log(v.cost); console.log(v.cost);
totalSum += parseInt(v.cost); totalSum += parseInt(v.cost);
outputValues += "<option value='"+ v.id +"'>" + v.name + "</option>"; outputValues += '<option data-stage-sum="' + v.cost + '" value="'+ v.id +'">' + v.name + '</option>';
stagesIds += v.id + ';'
}); });
$("#stagesSelect").html(outputValues); $("#stagesSelect").html(outputValues);
$(".totalSum").text(totalSum); $(".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({ $.ajax({
url: '/api/stages/', url: '/api/stages/',
@ -262,6 +292,7 @@
success: function (json) { success: function (json) {
var stageCount = json.results.length; var stageCount = json.results.length;
if (stageCount == 0) { if (stageCount == 0) {
$("#reserveSpace").hide();
stageCountVal = 1; stageCountVal = 1;
} else { } else {
stageCountVal = stageCount; stageCountVal = stageCount;
@ -280,7 +311,7 @@
'<input class="form-control orderStagesInput" name="order" type="hidden" value="' + orderId + '"/>' + '<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="term" type="text" />' +
'<label for="">Результат</label><input class="form-control" name="result" 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>'; '</form></div>';
} }
var statusNotAgreed = true; var statusNotAgreed = true;
@ -313,13 +344,19 @@
}); });
if (statusNotAgreed) { if (statusNotAgreed) {
htmlInbox += '<div class="box-sizing disTab" style="text-align:center;">' + if(secureOrder) {
'<div class="checkbox"><input type="checkbox" style="opacity:1">' + var orderSecureCheckbox = 'checked="checked"';
'Перейти в режим безопасной сделки</div></div>' + htmlInbox += '<div class="box-sizing disTab">' +
'<div class="textAreaBlock2 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 +'" ' + '<a href="#" data-sender-id="' + senderId +'" ' +
'data-recipent-id="' + recipentId +'" data-order-id="' + orderId + '" ' + 'data-recipent-id="' + recipentId +'" data-order-id="' + orderId + '" ' +
'id="addStagesForm">отправить на согласование</a> </div>'; 'id="addStagesForm">отправить на согласование</a> </div>';
}else if(json.results.length>0){
$("#reserveSpace").show();
} }
htmlInbox = htmlInboxStage + htmlInbox; htmlInbox = htmlInboxStage + htmlInbox;
$("#order-stages").html(htmlInbox); $("#order-stages").html(htmlInbox);
@ -414,8 +451,8 @@
var currentOrderId = $(this).attr('data-order-id'); var currentOrderId = $(this).attr('data-order-id');
var currentRecipentId = $(this).attr('data-recipent-id'); var currentRecipentId = $(this).attr('data-recipent-id');
var secureOrder = true
getStages(currentOrderId,userId,currentRecipentId); getStages(currentOrderId,userId,currentRecipentId,secureOrder);
socket.send_stages_approve({ socket.send_stages_approve({
"format_type": "approve_stages", "format_type": "approve_stages",
@ -446,11 +483,9 @@
'<input class="form-control orderStagesInput" name="order" type="hidden" value="' + orderId + '" />' + '<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="term" type="text" />' +
'<label for="">Результат</label><input class="form-control" name="result" 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>'; '</form></div>';
lastFormStage.after(addFormTemplate); lastFormStage.after(addFormTemplate);
} }
}else if (countStage < currentCountStage) { }else if (countStage < currentCountStage) {
@ -477,6 +512,8 @@
$(this).addClass('orAct'); $(this).addClass('orAct');
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');
var secureOrder = $(this).attr('data-secure-deal');
secureOrder = Boolean(secureOrder);
$("#chat-order-add #orderId").val(orderId); $("#chat-order-add #orderId").val(orderId);
$("#projectReviewId").val(orderId); $("#projectReviewId").val(orderId);
$("#reserve-button").attr('data-order-id', orderId); $("#reserve-button").attr('data-order-id', orderId);
@ -506,7 +543,7 @@
}); });
} }
}); });
getStages(orderId,userId,recipentId); getStages(orderId,userId,recipentId, secureOrder);
}); });
// Вытащить сообщения для конактов // Вытащить сообщения для конактов

@ -12,7 +12,7 @@
<div class="searchF1 polsF1 polsFF radio-afer"> <div class="searchF1 polsF1 polsFF radio-afer">
<div class="col-lg-6"> <div class="col-lg-6">
<label> <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> <span></span>
</label> </label>
<p class="text-afer">Сумма оплаты всего заказа</p> <p class="text-afer">Сумма оплаты всего заказа</p>
@ -26,10 +26,10 @@
<div class="searchF1 polsF1 polsFF radio-afer"> <div class="searchF1 polsF1 polsFF radio-afer">
<div class="col-lg-6"> <div class="col-lg-6">
<label> <label>
<input type="radio" name="choice_way" value="choice_way"> <input type="radio" name="choice_way" id="choiceWayStage" value="">
<span></span> <span></span>
</label> </label>
<p class="text-afer">Оплатить этап</p><br /> <p class="text-afer" style="width: 250px;">Оплатить этап</p><br />
<p class="des-afer"> <p class="des-afer">
Бюджет Этапа 1: <span class="stageSum"></span>р.<br /> Бюджет Этапа 1: <span class="stageSum"></span>р.<br />
Итого к оплате: <span class="stageSum"></span> р. Итого к оплате: <span class="stageSum"></span> р.
@ -44,6 +44,27 @@
<div class="searchF1 polsF1 polsFF radio-afe" style="padding-top: 20px;padding-left: 50px;"> <div class="searchF1 polsF1 polsFF radio-afe" style="padding-top: 20px;padding-left: 50px;">
<p class="titleStepss">Резервирование средств</p> <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>
</div> </div>

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

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

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

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

@ -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() voids_at = models.DateTimeField()
sum = models.DecimalField(max_digits=20, decimal_places=0, default=0) sum = models.DecimalField(max_digits=20, decimal_places=0, default=0)
type = models.CharField(max_length=20, choices=TYPES, default='add') 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): def save(self, *args, **kwargs):
if not self.pk and self.created_at: if not self.pk and self.created_at:

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

Loading…
Cancel
Save