#ARC-16 Fixes

remotes/origin/PR-39
Mukhtar 10 years ago
parent 1f8713db24
commit 8ef7e8f133
  1. 16
      assets/js/chat.js
  2. 25
      chat/chat.py
  3. 2
      chat/serializers.py
  4. 23
      chat/templates/chat_customer.html
  5. 45
      projects/templates/project_detail.html
  6. 2
      projects/urls.py
  7. 9
      projects/views.py
  8. 7
      users/mixins.py
  9. 1
      wallets/forms.py
  10. 2
      wallets/signals.py
  11. 17
      wallets/templates/score-detail.html
  12. 13
      wallets/views.py

@ -1,6 +1,6 @@
var SocketHandler = function () { var SocketHandler = function () {
domain = domain.replace(':' + port, ''); domain = domain.replace(':' + port, '');
var url = 'ws://' + domain + '/chat/' + userId + '/'; var url = 'ws://' + domain + ':8888/chat/' + userId + '/';
var sock = new WebSocket(url); var sock = new WebSocket(url);
var intervalId; var intervalId;
sock.onopen = function () { sock.onopen = function () {
@ -23,9 +23,17 @@ var SocketHandler = function () {
alert('approve stages'); alert('approve stages');
} }
if (inbox) { if (inbox) {
inbox.innerHTML += '<div class="col-lg-12 insetCommChat"><div class="topCommChat">' + var textMessage = message.msg;
'<p class="nameCommChat">ВЫ</p> <span>Сейчас</span></div>' + var classMessage = 'youChat';
'<p class="textCommChat">' + message.msg + '</p></div>'; var senderName = 'Вы';
var timeMessage = message.msg_time;
if (message.sender_id != userId){
senderName = message.sender_name;
classMessage = '';
}
inbox.innerHTML += '<div class="col-lg-12 insetCommChat '+ classMessage +'"><div class="topCommChat">' +
'<p class="nameCommChat">'+ senderName +'</p> <span>' + timeMessage + '</span></div>' +
'<p class="textCommChat">' + textMessage + '</p></div>';
} }
}; };

@ -1,4 +1,4 @@
import os.path import html
from tornado import gen, web, websocket, escape, options from tornado import gen, web, websocket, escape, options
from tornado.ioloop import IOLoop from tornado.ioloop import IOLoop
from tornado.httpserver import HTTPServer from tornado.httpserver import HTTPServer
@ -33,7 +33,6 @@ class ChatHandler(websocket.WebSocketHandler):
if 'dummy' in parsed: if 'dummy' in parsed:
return return
print(parsed['format_type'])
if 'approve_stages' in parsed['format_type']: if 'approve_stages' in parsed['format_type']:
self.approve_stages(parsed) self.approve_stages(parsed)
else: else:
@ -60,6 +59,8 @@ class ChatHandler(websocket.WebSocketHandler):
order_id = message_data['data'].get('order_id', None) order_id = message_data['data'].get('order_id', None)
team_id = message_data['data'].get('team_id', None) team_id = message_data['data'].get('team_id', None)
message = message_data['data'].get('chat_message', None) message = message_data['data'].get('chat_message', None)
message = html.escape(message)
message = message.replace('\n', '<br />')
answer_type = message_data['format_type'] answer_type = message_data['format_type']
private_type = 'true' if not order_id and not team_id else 'false' private_type = 'true' if not order_id and not team_id else 'false'
@ -74,14 +75,26 @@ class ChatHandler(websocket.WebSocketHandler):
insert_sql = "INSERT INTO chat_message (id,text,created, sender_id,recipent_id," \ insert_sql = "INSERT INTO chat_message (id,text,created, sender_id,recipent_id," \
" private_type,team_id, order_id,is_delete,is_new) " \ " private_type,team_id, order_id,is_delete,is_new) " \
"VALUES (DEFAULT,'{0}',NOW(),{1},{2},{3},{4},{5},{6},{7})".\ "VALUES (DEFAULT,'{0}',NOW(),{1},{2},{3},{4},{5},{6},{7}) RETURNING id".\
format(message, sender_id, recipent_id, private_type, team_value,order_value, is_delete, is_new) format(message, sender_id, recipent_id, private_type, team_value,order_value, is_delete, is_new)
yield self.db.execute(insert_sql) cursor_list = yield dict(cursor=self.db.execute(insert_sql))
waiters = tuple(w for c, w in self.waiters if c == recipent_id or c == sender_id) cursor = cursor_list.get('cursor')
result = cursor.fetchone()
message_id = result[0]
select_last_sql = "SELECT chat_message.id, chat_message.text, chat_message.created, chat_message.sender_id," \
"users_user.id, users_user.username FROM chat_message" \
" INNER JOIN users_user ON (chat_message.sender_id = users_user.id)" \
" WHERE chat_message.id = {0}".format(message_id)
cursor_msg = yield self.db.execute(select_last_sql)
msg_data = cursor_msg.fetchone()
sender_name = msg_data[5]
msg_time = msg_data[2].strftime("%Y-%m-%d %H:%M:%S")
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': answer_type}) waiter.write_message({'msg': message, 'msg_time': msg_time, 'sender_id': sender_id, 'sender_name': sender_name, 'answer_type': answer_type})
def check_origin(self, origin): def check_origin(self, origin):
return True return True

@ -1,3 +1,4 @@
from rest_framework import serializers
from rest_framework.serializers import ModelSerializer from rest_framework.serializers import ModelSerializer
from .models import Message, Notes, Documents from .models import Message, Notes, Documents
@ -20,6 +21,7 @@ class DocumentsSerializer(ModelSerializer):
class MessageSerializer(ModelSerializer): class MessageSerializer(ModelSerializer):
sender = UserSerializer() sender = UserSerializer()
recipent = UserSerializer() recipent = UserSerializer()
created = serializers.DateTimeField(format="%Y-%m-%d %H:%M:%S")
class Meta: class Meta:
model = Message model = Message

@ -72,7 +72,7 @@
</span> </span>
</div> </div>
<a id="contact-chat-add-message" href="javascript:void(0)">отправить</a> <a id="contact-chat-add-message" href="#">отправить</a>
</div> </div>
</form> </form>
@ -108,7 +108,7 @@
<p class="pOB"> <p class="pOB">
<span>Испонитель:</span> {{ order.order.contractor.get_full_name }} <span>Испонитель:</span> {{ order.order.contractor.get_full_name }}
</p> </p>
<a href="javascript:void(0)" class="linkChat11"> <a href="#" class="linkChat11">
<span class="glyphicon glyphicon-info-sign" aria-hidden="true"></span> <span class="glyphicon glyphicon-info-sign" aria-hidden="true"></span>
Полное описание заказа Полное описание заказа
</a> </a>
@ -134,7 +134,7 @@
Не более 10 файлов с общим объемом 500мб Не более 10 файлов с общим объемом 500мб
</span> </span>
</div> </div>
<a href="javascript:void(0)" id="order-chat-add-message">отправить</a> <a href="#" id="order-chat-add-message">отправить</a>
</div> </div>
</form> </form>
@ -448,18 +448,7 @@
} }
ii--; ii--;
}); });
} }
{# #}
{# var updateFormStages = $(".update-stages-form");#}
{# var limitCount = countStage + 1;#}
{# for (var i = 2; i < limitCount; i++) {#}
{# var stageCopy = $("#stage1").clone().attr("id", "stage" + i).addClass("stages_form");#}
{# stageCopy.find('.stage-span-id').html(i);#}
{# $("#stage1").after(stageCopy);#}
{##}
{# }#}
}); });
$('.order-block').on('click', function () { $('.order-block').on('click', function () {
@ -545,7 +534,8 @@
}); });
$('#contact-chat-add-message').on('click', function () { $('#contact-chat-add-message').on('click', function (e) {
e.preventDefault();
var chatMessage = $("#chat").val(); var chatMessage = $("#chat").val();
var recipentId = $("#recipentId").val(); var recipentId = $("#recipentId").val();
var senderId = $("#senderId").val(); var senderId = $("#senderId").val();
@ -566,7 +556,8 @@
alert('add review'); alert('add review');
}); });
$('#order-chat-add-message').on('click', function () { $('#order-chat-add-message').on('click', function (e) {
e.preventDefault();
var chatMessage = $("#chat-order-add #chat").val(); var chatMessage = $("#chat-order-add #chat").val();
var recipentId = $("#chat-order-add #recipentId").val(); var recipentId = $("#chat-order-add #recipentId").val();
var senderId = $("#chat-order-add #senderId").val(); var senderId = $("#chat-order-add #senderId").val();

@ -36,21 +36,8 @@
<a href="{% url 'users:customer-profile-open-projects' project.customer.pk %}">{{ project.customer.get_full_name }} [{{ project.customer.username }}]</a> <a href="{% url 'users:customer-profile-open-projects' project.customer.pk %}">{{ project.customer.get_full_name }} [{{ project.customer.username }}]</a>
</p> </p>
<p class="navv2">На сайте {{ project.created|naturaltime }}</p> <p class="navv2">На сайте {{ project.created|naturaltime }}</p>
{% if not request.user.is_contractor %}
<ul class="rettList restList3">
<li>
<a href="javascript:void(0)">Отзывы:
<span> + 0</span>
<small> 0</small>
<mark> - 0</mark>
</a>
</li>
</ul>
{% endif %}
</div> </div>
{% if request.user.is_contractor %}
<div class="col-lg-3 retts"> <div class="col-lg-3 retts">
<ul class="rettList restList2"> <ul class="rettList restList2">
<li>Рейтинг: <span> 0</span></li> <li>Рейтинг: <span> 0</span></li>
@ -64,27 +51,13 @@
</li> </li>
</ul> </ul>
</div> </div>
{% endif %}
<div class="col-lg-2 new-dashed">
{% specialization_widget contractor.pk %}
{# <div class="dashedCol4 dashedCol44 dashedColColor">#}
{# <p class="specUser">#}
{# Специализации:#}
{# </p>#}
{# </div>#}
</div>
<div class="col-lg-3 retts new-list"> <div class="col-lg-3 retts new-list">
<ul class="desListPro"> <ul class="desListPro">
<li> <li>{{ project.created }}</li>
{{ project.created }} <li>{{ project.get_work_type_display }}</li>
</li>
<li>
{{ project.get_work_type_display }}
</li>
</ul> </ul>
{% if project.cro %} {% if project.cro %}
<div class="sroUser sroExecutor sroPro"> <div class="sroUser sroExecutor sroPro">
<div class="iconSRO"></div> <div class="iconSRO"></div>
@ -554,10 +527,14 @@
<a href="{% url 'projects:add-candidate' answer_id=answer.pk project_id=project.pk %}" class="candLink candLink1"> <a href="{% url 'projects:add-candidate' answer_id=answer.pk project_id=project.pk %}" class="candLink candLink1">
Кандидат Кандидат
</a> </a>
<a href="{% url 'chat:chat-user' %}" class="candLink candLink2">
<form action="{% url 'projects:customer-offer-order' answer_id=answer.pk project_id=project.pk %}" method="POST" novalidate>
{% csrf_token %}
<a href="#" onclick="$(this).closest('form').submit(); return false" class="candLink candLink2">
предложить проект предложить проект
</a> </a>
</form>
<form action="{% url 'projects:customer-reject-project-answer' pk=answer.pk %}" method="POST" novalidate> <form action="{% url 'projects:customer-reject-project-answer' pk=answer.pk %}" method="POST" novalidate>
{% csrf_token %} {% csrf_token %}

@ -49,7 +49,7 @@ urlpatterns = [
urls.url(r'^candidate/comparison/sort/$', sort_candidates, name='comparison-sort'), urls.url(r'^candidate/comparison/sort/$', sort_candidates, name='comparison-sort'),
urls.url(r'^candidate/comparison/(?P<pk>\d+)/$', ProjectComparisonView.as_view(), name='comparison'), urls.url(r'^candidate/comparison/(?P<pk>\d+)/$', ProjectComparisonView.as_view(), name='comparison'),
urls.url(r'^offerorder/(?P<answer_id>(\d+))/(?P<project_id>(\d+))/$', OfferOrderView.as_view(), name='offer-order'), urls.url(r'^offerorder/(?P<answer_id>(\d+))/(?P<project_id>(\d+))/$', OfferOrderView.as_view(), name='customer-offer-order'),
# urls.url(r'^portfolio/create/$', PortfolioCreateView.as_view(), name='portfolio-create'), # urls.url(r'^portfolio/create/$', PortfolioCreateView.as_view(), name='portfolio-create'),
] ]

@ -1,4 +1,5 @@
from django.conf import settings from django.conf import settings
from django.core.exceptions import PermissionDenied
from django.contrib import messages from django.contrib import messages
from django.contrib.auth.mixins import PermissionRequiredMixin, LoginRequiredMixin from django.contrib.auth.mixins import PermissionRequiredMixin, LoginRequiredMixin
from django.core.files.base import ContentFile from django.core.files.base import ContentFile
@ -346,7 +347,7 @@ class CustomerProjectCreateView(BaseMixin, View):
if request.user.is_authenticated() and request.user.is_customer(): if request.user.is_authenticated() and request.user.is_customer():
return super().dispatch(request, *args, **kwargs) return super().dispatch(request, *args, **kwargs)
else: else:
return HttpResponseForbidden() raise PermissionDenied
def get(self, request, *args, **kwargs): def get(self, request, *args, **kwargs):
form = self.form_class(request=request) form = self.form_class(request=request)
@ -622,6 +623,7 @@ class CandidateDeleteView(DeleteView):
def get(self, *args, **kwargs): def get(self, *args, **kwargs):
return self.post(*args, **kwargs) return self.post(*args, **kwargs)
def sort_candidates(request): def sort_candidates(request):
if request.is_ajax(): if request.is_ajax():
items = request.POST.getlist('items[]') items = request.POST.getlist('items[]')
@ -641,8 +643,9 @@ def sort_candidates(request):
class OfferOrderView(View): class OfferOrderView(View):
template_name = 'chattest.html' template_name = 'chattest.html'
def get(self, request, *args, **kwargs): def post(self,request, *args, **kwargs):
return render(request, self.template_name) print("Add chat")
return HttpResponseRedirect(reverse('chat:chat-user'))
def contractor_portfolio_create(request): def contractor_portfolio_create(request):

@ -1,5 +1,4 @@
from django.http import HttpResponseForbidden from django.core.exceptions import PermissionDenied
from django.contrib import messages
class CheckForUserMixin(object): class CheckForUserMixin(object):
@ -8,9 +7,9 @@ class CheckForUserMixin(object):
pk = kwargs.get('pk') pk = kwargs.get('pk')
if pk: if pk:
if request.user.pk != int(pk): if request.user.pk != int(pk):
return HttpResponseForbidden('403 Forbidden') raise PermissionDenied
else: else:
return HttpResponseForbidden('403 Forbidden') raise PermissionDenied
return super().dispatch(request, *args, **kwargs) return super().dispatch(request, *args, **kwargs)

@ -43,6 +43,7 @@ class TmpPaymentAvisoForm(forms.Form):
md5 = forms.CharField() md5 = forms.CharField()
shopId = forms.IntegerField() shopId = forms.IntegerField()
invoiceId = forms.IntegerField() invoiceId = forms.IntegerField()
orderSumAmount = forms.DecimalField()
def clean_action(self): def clean_action(self):
action = self.cleaned_data.get('action') action = self.cleaned_data.get('action')

@ -22,7 +22,7 @@ def send_for_accountant(sender, instance, created, **kwargs):
@receiver(post_save, sender=Transaction) @receiver(post_save, sender=Transaction)
def add_invoice_history(sender, instance, created, **kwargs): def add_invoice_history(sender, instance, created, **kwargs):
if 'add' in instance.type: if 'add' in instance.type and instance.complete:
inv_history = InvoiceHistory() inv_history = InvoiceHistory()
inv_history.comment = 'Пополнение счета' inv_history.comment = 'Пополнение счета'
inv_history.sum = instance.sum inv_history.sum = instance.sum

@ -23,7 +23,7 @@
{% endif %} {% endif %}
<div class="col-lg-6"> <div class="col-lg-6">
<a href="javascript:void(0)" data-toggle="modal" data-target="#withdraw-money" <a href="#" data-toggle="modal" data-target="#withdraw-money"
class="linkS linkS2">вывести средства</a> class="linkS linkS2">вывести средства</a>
</div> </div>
@ -75,15 +75,14 @@
<div class="modal-body"> <div class="modal-body">
<div style="height: 150px;"> <div style="height: 150px;">
<div class="textAreaBlock2 text-nn box-sizing disTab"> <div class="textAreaBlock2 text-nn box-sizing disTab">
<p>Кол-во денег {{ YANDEX_MONEY.scid }}</p> <p>Кол-во денег</p>
<input type="text" name="sum"> <input type="text" name="sum">
<p>shopId: <input type='hidden' name='shopId' value='{{ YANDEX_MONEY.shop_id }}'></p> <input type='hidden' name='shopId' value='{{ YANDEX_MONEY.shop_id }}'>
<p>scid: <input type='hidden' name='scid' value='{{ YANDEX_MONEY.scid }}'></p> <input type='hidden' name='scid' value='{{ YANDEX_MONEY.scid }}'>
<p>customerNumber: <input type='hidden' name='customerNumber' value='{{ user_score.pk }}'></p> <input type='hidden' name='customerNumber' value='{{ user_score.pk }}'>
<p>paymentType: <input type='hidden' name='paymentType' value='AC'></p> <input type='hidden' name='paymentType' value='AC'>
<input type='hidden' name='transactionId' value='{{ transaction.pk }}'>
<p>transactionId: <input type='hidden' name='transactionId' value='{{ transaction.pk }}'></p>
</div> </div>
</div> </div>
@ -91,7 +90,7 @@
<div class="modal-footer"> <div class="modal-footer">
<button type="button" class="btn btn-default" data-dismiss="modal">Закрыть</button> <button type="button" class="btn btn-default" data-dismiss="modal">Закрыть</button>
<button type="submit" class="btn btn-primary">Вывести</button> <button type="submit" class="btn btn-primary">Пополнить</button>
</div> </div>
</form> </form>

@ -40,13 +40,17 @@ class ScoreView(View):
return HttpResponseForbidden('403 Forbidden') return HttpResponseForbidden('403 Forbidden')
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)
user_score = get_object_or_404(User.customer_objects, pk=kwargs.get('pk')) transaction = Transaction.objects.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, { return render(request, self.template_name, {
'transaction': transaction, 'transaction': transaction,
'YANDEX_MONEY': settings.YANDEX_MONEY, 'YANDEX_MONEY': settings.YANDEX_MONEY,
'user_score': user_score, 'user_score': user_score,
'user_score_balance': user_score_balance,
}) })
@ -159,6 +163,11 @@ class TmpPaymentAvisoView(View):
form = self.form_class(request.POST) form = self.form_class(request.POST)
if form.is_valid(): if form.is_valid():
transaction = form.cleaned_data.get('transaction_id')
transaction.complete = True
transaction.sum = form.cleaned_data.get('orderSumAmount')
transaction.save()
res = """<?xml version="1.0" encoding="utf-8"?> res = """<?xml version="1.0" encoding="utf-8"?>
<paymentAvisoResponse <paymentAvisoResponse
performedDatetime="{date}" performedDatetime="{date}"

Loading…
Cancel
Save