#ARC-27 Fix

remotes/origin/PR-39
Mukhtar 10 years ago
parent bf0157d738
commit ffac41da05
  1. 4
      archilance/settings/base.py
  2. 22
      assets/js/chat.js
  3. 8
      chat/templates/chat_customer.html
  4. 1
      chat/templates/reverse_stage_modal.html
  5. 16
      projects/migrations/0025_merge.py
  6. 7
      projects/serializers.py
  7. 2
      users/models.py
  8. 632
      users/templates/contractor_office_chat_projects.html
  9. 5
      users/templates/partials/contractor_profile_tabs.html
  10. 2
      users/urls.py
  11. 35
      users/views.py
  12. 3
      wallets/admin.py
  13. 12
      wallets/forms.py
  14. 16
      wallets/migrations/0013_merge.py
  15. 29
      wallets/migrations/0014_payfromscore.py
  16. 15
      wallets/models.py
  17. 24
      wallets/signals.py
  18. 1
      wallets/templates/score-test.html
  19. 5
      wallets/urls.py
  20. 30
      wallets/views.py
  21. 16
      work_sell/migrations/0010_merge.py

@ -173,8 +173,8 @@ AUTHENTICATION_BACKENDS = (
# SOCIAL_AUTH_FACEBOOK_KEY = '222531191461451' # SOCIAL_AUTH_FACEBOOK_KEY = '222531191461451'
# SOCIAL_AUTH_FACEBOOK_SECRET = '95e88f7ef396c5b803375f8476cf2ba4' # SOCIAL_AUTH_FACEBOOK_SECRET = '95e88f7ef396c5b803375f8476cf2ba4'
SOCIAL_AUTH_FACEBOOK_KEY = '1030546170341186' SOCIAL_AUTH_FACEBOOK_KEY = '1047362798683484'
SOCIAL_AUTH_FACEBOOK_SECRET = '1b22e95040b209c5d2f2d7f69462bf95' SOCIAL_AUTH_FACEBOOK_SECRET = '98fedcccb1cb941c2289692bd4de84da'
SOCIAL_AUTH_FACEBOOK_SCOPE = ['email'] SOCIAL_AUTH_FACEBOOK_SCOPE = ['email']
SOCIAL_AUTH_FACEBOOK_PROFILE_EXTRA_PARAMS = { SOCIAL_AUTH_FACEBOOK_PROFILE_EXTRA_PARAMS = {

@ -168,7 +168,27 @@ $(function () {
$("#paymentfromSite").on('click',function(){ $("#paymentfromSite").on('click',function(){
var sum = $("#stageSumPay").val(); var sum = $("#stageSumPay").val();
alert(sum); var stages = $("#stagesIds").val();
var orderId = $("#ordermodalId").val();
$.ajax({
url: '/wallets/payfromscore/',
type: 'POST',
data: {
csrfmiddlewaretoken: csrftoken,
sum: sum,
stages_id: stages,
},
dataType: 'json',
success: function (json) {
if(json.status == 'ok'){
$("#reserve-stage-modal").modal('hide');
$("#orderBlock" + orderId).trigger('click');
}
},
error: function(e, jqxhr){
console.log(e);
}
})
}); });

@ -286,12 +286,17 @@
$("#stagesSelect").html(outputValues); $("#stagesSelect").html(outputValues);
$(".totalSum").text(totalSum); $(".totalSum").text(totalSum);
if(json.results.length>notPaidCount && notPaidCount>0){ if(json.results.length>notPaidCount && notPaidCount>0){
$("#choiceWayOrder").hide(); $("#choiceWayOrder").hide();
} }
$("#choiceWayOrder").val(totalSum)
$("#choiceWayOrder").val(totalSum);
$("#ordermodalId").val(orderId);
$("#stages-pay-form #stageSumPay").val(totalSum); $("#stages-pay-form #stageSumPay").val(totalSum);
$("#stages-pay-form #stagesIds").val(stagesIds); $("#stages-pay-form #stagesIds").val(stagesIds);
$("#choiceWayOrder").attr('data-stages-ids',stagesIds); $("#choiceWayOrder").attr('data-stages-ids',stagesIds);
} }
@ -455,7 +460,6 @@
$("#stagesWork").html(stageWork); $("#stagesWork").html(stageWork);
} }
if (!data.secure){ if (!data.secure){
$("#reserveSpace").hide(); $("#reserveSpace").hide();
} }

@ -55,6 +55,7 @@
<input type='hidden' name='paymentType' value='AC'> <input type='hidden' name='paymentType' value='AC'>
<input type='hidden' name='transactionId' value='{{ transaction.pk }}'> <input type='hidden' name='transactionId' value='{{ transaction.pk }}'>
<input type='hidden' name='stagesId' id='stagesIds' value=''> <input type='hidden' name='stagesId' id='stagesIds' value=''>
<input type='hidden' name='ordermodalId' id='ordermodalId'>
</div> </div>
<button type="submit" class="btn btn-primary btn-lg btn-block">Пополнить</button> <button type="submit" class="btn btn-primary btn-lg btn-block">Пополнить</button>
</div> </div>

@ -0,0 +1,16 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.9.7 on 2016-09-02 07:45
from __future__ import unicode_literals
from django.db import migrations
class Migration(migrations.Migration):
dependencies = [
('projects', '0024_auto_20160901_1247'),
('projects', '0024_auto_20160901_1548'),
]
operations = [
]

@ -104,6 +104,7 @@ class ProjectSerializer(ModelSerializer):
class OrderSerializer(ModelSerializer): class OrderSerializer(ModelSerializer):
stages = StageSerializer(many=True, read_only=True) stages = StageSerializer(many=True, read_only=True)
project = ProjectSerializer(read_only=True) project = ProjectSerializer(read_only=True)
has_user_review = serializers.SerializerMethodField(read_only=True)
class Meta: class Meta:
model = Order model = Order
@ -116,10 +117,16 @@ class OrderSerializer(ModelSerializer):
'project', 'project',
'secure', 'secure',
'status', 'status',
'has_user_review',
'stages', 'stages',
'project', 'project',
) )
def get_has_user_review(self,obj):
# obj.project.
print(self.context['request'].user)
return "yes"
class PortfolioPhotoSerializer(ModelSerializer): class PortfolioPhotoSerializer(ModelSerializer):
img = ImageField() img = ImageField()

@ -220,7 +220,7 @@ class User(AbstractBaseUser, PermissionsMixin):
def get_popular_specialization(self): def get_popular_specialization(self):
from ratings.models import SpecializationRating from ratings.models import SpecializationRating
return SpecializationRating.objects.filter(user=self).order_by('position').first().specialization.name # return SpecializationRating.objects.filter(user=self).order_by('position').first().specialization.name
class Team(models.Model): class Team(models.Model):

@ -0,0 +1,632 @@
{% extends 'partials/base.html' %}
{% load project_tags %}
{% load specializtions_tags %}
{% load thumbnail %}
{% block content %}
{% include 'partials/header.html' %}
<div class="container mainScore">
<div class="row">
<div class="col-lg-12">
<p class="titleScore">Личный кабинет</p>
</div>
{% include 'partials/contractor_profile_tabs.html' %}
<div class="projectsBlock disTab">
<!-- Tab2 (chat order block)-->
<div class="chatBlock disTab tab-pane">
<div class="col-lg-3 wrMessages">
<div class="messageBlock box-sizing disTab">
<p>Заказы</p>
{% for order in orders %}
<div class="orderBlock box-sizing order-block" data-project-id="{{ order.id }}"
id="orderBlock{{ order.order.id }}"
data-secure-deal="{% if order.order.secure %}true{% else %}false{% endif %}"
{% if order.order.contractor %}
data-recipent-id="{{ order.order.contractor.pk }}"
{% else %}
data-recipent-id="{{ order.order.team.owner.pk }}"
{% endif %} data-id="{{ order.order.id }}">
<span class="dimovChat"></span>
<p class="titleOB">{{ order }}</p>
<div class="hideOBB">
<p class="pOB">
<span>Исполнитель:</span>
{% if order.order.contractor %}
{{ order.order.contractor.get_full_name }}
{% else %}
{{ order.order.team.name }}
{% endif %}
</p>
<a href="#" class="linkChat11 full-order-info">
<span class="glyphicon glyphicon-info-sign" aria-hidden="true"></span>
Полное описание заказа
</a>
</div>
</div>
{% endfor %}
</div>
</div>
<div class="col-lg-6 commChat">
<div id="message-chat-order-space"></div>
<form id="chat-order-add">
<input type="hidden" name="senderId" id="senderId" value="{{ request.user.pk }}"/>
<input type="hidden" name="recipentId" id="recipentId">
<input type="hidden" name="orderId" id="orderId">
<textarea id="chat" class="box-sizing"></textarea>
<p class="errorEmptyMessage" style="color: red;display:none;">Пустое сообщение нельзя
отправить</p>
<div class="bunChat">
<div class="setChat box-sizing upload">
<input type="file" name="file" id="upload-document-order">
<p>Прикрепить файл</p>
</div>
<div id="document-send-order"></div>
<a href="#" id="order-chat-add-message">отправить</a>
</div>
</form>
</div>
<div class="col-lg-3 wrstepschat" id="order-stages-tab">
<p>Этапы работы</p>
<div class="stepssBlock box-sizing disTab">
<p class="titleStepss">1 / Согласование условий</p>
<p class="textStepss">
Обсуджение задания и условий выполнения работы. Подтверждение заказа исполнителем.
</p>
</div>
<div id="order-stages" class="stepssBlock"></div>
<div class="stepssBlock box-sizing disTab" id="reserveSpace" style="display:none;">
<p class="titleStepss">2 / Резервирование</p>
<p class="textStepss">
Резервирование заказчиком суммы оплаты по заказ.
Деньги перечисляются и хранятся насайте.
</p>
<ul class="stages-paid"></ul>
<div class="textAreaBlock2 FFD box-sizing disTab">
<a href="#" id="reserve-button" data-order-id="">Зарезервировать</a>
</div>
</div>
<!-- Зарезервировать средства (модальное окно)-->
{% include 'reverse_stage_modal.html' %}
<!-- Конец блока -->
<div class="stepssBlock box-sizing disTab" id="completeWork">
<p class="titleStepss">3 / Выполнение работы</p>
<p class="textStepss">
Процесс выполнения задания в заказе до получения
заказчиком итогового результата работы.
</p>
<div id="stagesWork" class="stages-work"></div>
</div>
<div class="closeChat closeChat1" id="leaveReview" style="display: none;">
<a href="#" data-toggle="modal" data-target="#review-add">
Закрыть проект<br>и оставить отзыв
</a>
</div>
<div class="col-lg-12 documentsChat">
<p>Входящие документы</p>
<ul id="documentOrderSpace"></ul>
{# <a href="javascript:void(0)">#}
{# Распечатать с помощью ресурса#}
{# </a>#}
</div>
<div class="textAreaBlock2 box-sizing disTab">
<p>Для заметок</p>
<textarea id="chat2"></textarea>
<a href="#">сохранить</a>
</div>
<!-- Review add -->
{% include 'review_add_modal.html' %}
<!-- -->
<!-- Arbitration add -->
{% include 'arbitration_modal.html' %}
<!-- -->
<!-- order-info -->
{% include 'order_info.html' %}
<!-- -->
</div>
</div>
<!-- End block (chat order block) -->
</div>
{% include 'partials/footer.html' %}
</div>
</div>
{% endblock %}
{% block js_block %}
<script type="text/javascript">
var userId = {{ request.user.pk }};
var domain = '{{ request.META.HTTP_HOST }}';
var port = '{{ request.META.SERVER_PORT }}';
</script>
<script type="text/javascript" src='{% static "js/chat.js" %}'></script>
<script type="text/javascript">
$(function () {
var currentChatUser = {{ request.user.pk }};
var form = document.getElementById('message_form');
$('body').on('focus',".term-picker", function(){
$(this).datepicker({
{# minDate: 0,#}
});
})
$("#reserve-button").on("click",function(e) {
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) {
var outputValues = '';
var totalSum = 0;
var stagesIds = '';
var notPaidCount = 0;
$.each(json.results, function (i, v) {
if((v.status == 'in_process') && (!v.is_paid)) {
totalSum += parseInt(v.cost);
notPaidCount +=1;
outputValues += '<option data-stage-sum="' + v.cost + '" value="' + v.id + '">' + v.name + '</option>';
stagesIds += v.id + ';'
}
});
$("#stagesSelect").html(outputValues);
$(".totalSum").text(totalSum);
if(json.results.length>notPaidCount && notPaidCount>0){
$("#choiceWayOrder").hide();
}
$("#choiceWayOrder").val(totalSum);
$("#ordermodalId").val(orderId);
$("#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);
$(".stageSum").text(sumStage);
$("#stages-pay-form #stagesIds").val($(this).val());
});
//Получить заказы
function getStages(orderId, senderId, recipentId, secureOrder) {
$.ajax({
url:'/api/orders/' + orderId + '/',
type: 'GET',
data:{csrfmiddlewaretoken: csrftoken},
dataType: 'json',
}).then(function(data){
var stagesResults = data.stages;
var stageCount = stagesResults.length;
if (stageCount == 0) {
$("#reserveSpace").hide();
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="term-picker form-control datepicker" name="term" type="text" />' +
'<label for="">Результат</label><input class="form-control" name="result" type="text" />' +
'<input class="form-control" name="pos" value="1" type="hidden" />' +
'</form></div>';
}
var statusNotAgreed = true;
var stagesInWork = [];
var stagesPaidProcess = [];
var stagesCompleted = [];
var stagePaidCount = 0;
var stagesReservedHtml = "";
$.each(stagesResults, function (i, v) {
if (v.status == "completed"){
stagesCompleted.push(v);
}
if(!data.secure){
if(v.status == "in_process") {
stagesInWork.push(v);
}
}else if ((v.status == "in_process") && (v.is_paid)){
stagesInWork.push(v);
stagesPaidProcess.push(v);
}
if(v.is_paid){
stagePaidCount +=1;
}
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="term-picker form-control datepicker" 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 = "";
var statusName = '';
if (v.status == 'completed'){
statusName = 'Завершен';
}
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>до '+ v.term +'</p><span>' + v.cost + '<i class="fa fa-rub"></i></span>' +
'</div><div><p>'+ statusName +'</p></div></div></div>';
}
if(data.secure) {
if (v.is_paid) {
stagesReservedHtml += '<li class="reserved">Сумма за этап ' + v.pos + '.Зарезервирована.</li>';
} else {
stagesReservedHtml += '<li class="unreserved">Сумма за этап ' + v.pos + '.Не зарезервирована.</li>';
}
}
});
if (stagesResults.length == stagePaidCount && data.secure){
$("#reserve-button").parent().hide();
}else {
$("#reserve-button").parent().show();
}
if (statusNotAgreed) {
if(!data.secure) {
htmlInbox += '<div class="box-sizing disTab">' +
'<div class="checkbox"><input name="secure" id="secureOrder" 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((stagesResults.length>0) && (data.secure)){
$("#reserveSpace").show();
}
htmlInbox = htmlInboxStage + htmlInbox;
$("#order-stages").html(htmlInbox);
$("#completeWork").hide();
if(stagesInWork.length > 0){
$("#completeWork").show();
var stage = stagesInWork[0];
var stageWork = '<div class="numberStepp box-sizing">' +
'<div class="insetNumStepp"><div><p>В работе '+ stage.name +'</p></div> ' +
'<div><p>Результат этапа : '+ stage.result +'</p></div>' +
'<div><p>Срок сдачи '+ stage.term +'</p><span>' + stage.cost + '<i class="fa fa-rub"></i></span></div>' +
'</div></div>';
if (stage.close_contractor){
stageWork += '<div class="textAreaBlock2 FFD box-sizing disTab"><a href="#" class="closeStage" data-order-id="'+ orderId + '" data-sender-id="{{ request.user.pk }}"' +
' data-recipent-id="'+ recipentId + '" data-stage-id="'+ stage.id+'">Закрыть этап '+ stage.pos +'</a></div>';
}
if (data.secure){
stageWork += '<div class="textAreaBlock2 FFD box-sizing disTab"><a href="#" data-toggle="modal" data-target="#arbitration-add">Обратитьсяв арбитраж</a></div>';
}
$("#stagesWork").html(stageWork);
}
if (!data.secure){
$("#reserveSpace").hide();
}
if((stagesCompleted.length == stagesResults.length) && (stagesCompleted.length > 0)){
$("#leaveReview").show();
console.log("Все этапы завершены");
}else {
$("#leaveReview").hide();
}
if (data.status == 'completed'){
$("#leaveReview").hide();
}
$(".stages-paid").html(stagesReservedHtml);
});
}
//Закрыть этап
$('#tab2').on('click','.closeStage', function(e){
e.preventDefault();
var stageId = $(this).attr('data-stage-id');
var _this = $(this);
$.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) {
socket.send_stages_approve({
"format_type": "approve_stages",
"data": {
"sender_id": _this.attr('data-sender-id'),
"recipent_id": _this.attr('data-recipent-id'),
"order_id": _this.attr('data-order-id'),
"msg": "Заказчик закрыл этап " + json.name,
}
});
console.log(json);
},
error: function (e) {
console.log('error');
console.log(e);
}
});
});
// Добавление этапов
$("#order-stages").on('click', "#addStagesForm", function (e) {
e.preventDefault();
var currentOrderId = $(this).attr('data-order-id');
var secureOrderEl = $("#secureOrder");
if(secureOrderEl.length > 0) {
var secOrderVal = false;
if (secureOrderEl.prop('checked')) {
secOrderVal = true;
}
$.ajax({
url: '/api/orders/' + currentOrderId + '/',
type: 'PATCH',
beforeSend: function (xhr) {
xhr.setRequestHeader("X-CSRFToken", getCookie('csrftoken'))
},
data: {secure: secOrderVal},
dataType: 'json',
success: function (json){
},
error: function(e){
console.log(e);
}
});
}
$(".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('error');
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 currentRecipentId = $(this).attr('data-recipent-id');
var secureOrder = true
socket.send_stages_approve({
"format_type": "approve_stages",
"data": {
"sender_id": userId,
"recipent_id": currentRecipentId,
"order_id": currentOrderId,
"msg": "Этапы для заказа "+ currentOrderId +"изменены",
}
});
{# setTimeout(function () {#}
{# getStages(currentOrderId,userId,currentRecipentId,secureOrder);#}
{##}
{# }, 1000);#}
});
//Изменение счетчика
$('#order-stages-tab').on('change', '#countStage', function () {
var countStage = parseInt($(this).val());
var currentCountStage = $(".numberStepp").length;
if ((countStage<1) || isNaN(countStage)) {
countStage = 1;
$('#order-stages-tab #countStage').val(currentCountStage);
}else {
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="term-picker form-control datepicker" name="term" type="text" />' +
'<label for="">Результат</label><input class="form-control" name="result" type="text" />' +
'<input class="form-control" name="pos" value="' + pos + '" type="hidden" />'
'</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 projectId = $(this).attr('data-project-id');
var recipentId = $(this).attr('data-recipent-id');
var secureOrder = $(this).attr('data-secure-deal');
secureOrder = Boolean(secureOrder);
$("#chat-order-add #orderId").val(orderId);
$("#orderArbitrationId").val(orderId);
$("#projectReviewId").val(projectId);
$("#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');
var docList = document.getElementById('documentOrderSpace');
inbox.innerHTML = '';
docList.innerHTML = '';
$.ajax({
url:'/api/documents',
type: 'GET',
data:{
csrfmiddlewaretoken: csrftoken,
'order': orderId
},
dataType: 'json',
success: function (json){
console.log(json);
$.each(json.results, function (i, v) {
docList.innerHTML += '<li style="word-break: break-all;"><a class="file-link" href="'+ v.file_url +'">'+ v.file+'</a></li>';
});
},
error: function(e){
console.log(e);
}
});
$.ajax({
url: '/api/message',
type: 'GET',
data: {csrfmiddlewaretoken: csrftoken, 'order': orderId,'team__isnull': 'true'},
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, secureOrder);
});
});
var userId = '{{ request.user.pk }}';
</script>
{% endblock %}

@ -1,5 +1,6 @@
{% url 'users:contractor-office' pk=contractor.pk as contractor_office_url %} {% url 'users:contractor-office' pk=contractor.pk as contractor_office_url %}
{% url 'users:contractor-office-open-projects' pk=contractor.pk as contractor_office_open_projects_url %} {% url 'users:contractor-office-open-projects' pk=contractor.pk as contractor_office_open_projects_url %}
{% url 'users:contractor-office-chat-projects' pk=contractor.pk as contractor_office_chat_projects_url %}
<div class="profileTabs"> <div class="profileTabs">
<ul class="nav nav-tabs nav-justified"> <ul class="nav nav-tabs nav-justified">
@ -22,8 +23,8 @@
</div> </div>
</li> </li>
<li role="presentation"> <li role="presentation" {% if request.path == contractor_office_chat_projects_url %}class="active"{% endif %}>
<a href="{% url 'chat:chat-user' %}">Проекты в работе</a> <a href="{{ contractor_office_chat_projects_url }}">Проекты в работе</a>
<div class="roundsCount"> <div class="roundsCount">
<div class="countG">0</div> <div class="countG">0</div>

@ -16,6 +16,7 @@ from .views import (
TeamCreateView, TeamCreateView,
UserFinancialInfoEditView, UserFinancialInfoEditView,
UserProfileEditView, UserProfileEditView,
ContractorChatProjectsView,
) )
@ -37,4 +38,5 @@ urlpatterns = [
urls.url(r'^contractors/(?P<pk>\d+)/$', ContractorProfileDetailView.as_view(), name='contractor-profile'), urls.url(r'^contractors/(?P<pk>\d+)/$', ContractorProfileDetailView.as_view(), name='contractor-profile'),
urls.url(r'^contractor-office/(?P<pk>\d+)/$', ContractorOfficeView.as_view(), name='contractor-office'), urls.url(r'^contractor-office/(?P<pk>\d+)/$', ContractorOfficeView.as_view(), name='contractor-office'),
urls.url(r'^contractor-office/(?P<pk>\d+)/open-projects/$', ContractorOfficeProjectsView.as_view(), name='contractor-office-open-projects'), urls.url(r'^contractor-office/(?P<pk>\d+)/open-projects/$', ContractorOfficeProjectsView.as_view(), name='contractor-office-open-projects'),
urls.url(r'^contractor-office/(?P<pk>\d+)/work-projects/$', ContractorChatProjectsView.as_view(), name='contractor-office-chat-projects'),
] ]

@ -21,11 +21,12 @@ from .forms import TeamForm, ContractorResumeFilesForm, ContractorResumeForm
from archilance import util from archilance import util
from archilance.mixins import BaseMixin from archilance.mixins import BaseMixin
from projects.forms import PortfolioForm from projects.forms import PortfolioForm
from projects.models import Project, Portfolio from projects.models import Project, Portfolio, Order
from reviews.models import Review from reviews.models import Review
from specializations.models import Specialization from specializations.models import Specialization
from work_sell.forms import WorkSellForm from work_sell.forms import WorkSellForm
from work_sell.models import WorkSell, Picture from work_sell.models import WorkSell, Picture
from chat.models import Message
from .forms import ( from .forms import (
ContractorFilterForm, ContractorFilterForm,
@ -399,6 +400,38 @@ class ContractorOfficeView(DetailView):
return context return context
class ContractorChatProjectsView(BaseMixin, View):
template_name = 'contractor_office_chat_projects.html'
def get(self, request, *args, **kwargs):
context = self.get_context_data(**kwargs)
contractor = get_object_or_404(User.contractor_objects, pk=kwargs.get('pk'))
context['contractor'] = contractor
team_ids = []
if request.user.is_owner_team():
team_ids.append(request.user.team.pk)
team_orders = request.user.team.orders.all()
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()
orders = Order.objects.filter(Q(contractor=request.user) | Q(team_id__in=team_ids)).all()
contractor_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()
users_ids = []
for msg in contractor_contacts:
a, b = msg
if a != request.user.pk:
users_ids.append(a)
if b != request.user.pk:
users_ids.append(b)
# contacts_users = User.objects.filter(pk__in=users_ids)
chat_messages = Message.objects.filter(Q(sender=request.user.pk) | Q(recipent=request.user.pk)).order_by(
'created')
context['orders'] = orders
return render(request, self.template_name, context)
class ContractorOfficeProjectsView(BaseMixin, View): class ContractorOfficeProjectsView(BaseMixin, View):
template_name = 'contractor_office_open_projects.html' template_name = 'contractor_office_open_projects.html'

@ -2,7 +2,7 @@ from django.contrib import admin
from import_export import resources from import_export import resources
from import_export.admin import ImportExportModelAdmin from import_export.admin import ImportExportModelAdmin
from .models import InvoiceHistory, WithDraw, Transaction, Wallet from .models import InvoiceHistory, WithDraw, Transaction, Wallet, PayFromScore
class InvoiceHistoryAdmin(admin.ModelAdmin): class InvoiceHistoryAdmin(admin.ModelAdmin):
@ -28,3 +28,4 @@ admin.site.register(InvoiceHistory, InvoiceHistoryAdmin)
admin.site.register(WithDraw, WithDrawAdmin) admin.site.register(WithDraw, WithDrawAdmin)
admin.site.register(Transaction, TransactionAdmin) admin.site.register(Transaction, TransactionAdmin)
admin.site.register(Wallet) admin.site.register(Wallet)
admin.site.register(PayFromScore)

@ -1,7 +1,7 @@
from django import forms from django import forms
from django.conf import settings from django.conf import settings
from .models import WithDraw from .models import WithDraw, PayFromScore
class WithDrawForm(forms.ModelForm): class WithDrawForm(forms.ModelForm):
@ -15,6 +15,16 @@ class WithDrawForm(forms.ModelForm):
) )
class PayFromScoreForm(forms.ModelForm):
class Meta:
model = PayFromScore
fields = (
'sum',
'stages_id',
)
class TmpCheckOrderForm(forms.Form): class TmpCheckOrderForm(forms.Form):
action = forms.CharField() # Has to be "checkOrder" action = forms.CharField() # Has to be "checkOrder"
md5 = forms.CharField() md5 = forms.CharField()

@ -0,0 +1,16 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.9.7 on 2016-09-02 07:45
from __future__ import unicode_literals
from django.db import migrations
class Migration(migrations.Migration):
dependencies = [
('wallets', '0012_auto_20160901_1247'),
('wallets', '0012_auto_20160901_1548'),
]
operations = [
]

@ -0,0 +1,29 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.9.7 on 2016-09-02 09:25
from __future__ import unicode_literals
from django.conf import settings
from django.db import migrations, models
import django.db.models.deletion
import django.utils.timezone
class Migration(migrations.Migration):
dependencies = [
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
('wallets', '0013_merge'),
]
operations = [
migrations.CreateModel(
name='PayFromScore',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('sum', models.DecimalField(decimal_places=0, default=0, max_digits=20)),
('stages_id', models.CharField(blank=True, max_length=100, null=True)),
('created_at', models.DateTimeField(default=django.utils.timezone.now, editable=False)),
('customer', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='customer_payfromscore', to=settings.AUTH_USER_MODEL)),
],
),
]

@ -104,3 +104,18 @@ class Transaction(models.Model):
def __str__(self): def __str__(self):
return str(self.pk) return str(self.pk)
class PayFromScore(models.Model):
customer = models.ForeignKey(User, related_name='customer_payfromscore')
sum = models.DecimalField(max_digits=20, decimal_places=0, default=0)
stages_id = models.CharField(max_length=100, null=True, blank=True)
created_at = models.DateTimeField(default=timezone.now, editable=False)
def __str__(self):
return str(self.pk)
class Meta:
ordering = ('-created_at',)
verbose_name = 'Оплата со счета'
verbose_name_plural = 'Оплата со счета'

@ -3,7 +3,7 @@ from django.dispatch import receiver
from django.core.mail import send_mail, EmailMultiAlternatives from django.core.mail import send_mail, EmailMultiAlternatives
from django.template.loader import get_template, render_to_string from django.template.loader import get_template, render_to_string
from .models import WithDraw, InvoiceHistory, Transaction from .models import WithDraw, InvoiceHistory, Transaction, PayFromScore
from projects.models import Stage from projects.models import Stage
@ -69,6 +69,28 @@ def reserve_stages(sender, instance, created, **kwargs):
inv_history.save() inv_history.save()
@receiver(post_save, sender=PayFromScore)
def reserve_stages(sender, instance, created, **kwargs):
order = None
stages_names = []
stages_ids_raw = instance.stages_id
if stages_ids_raw:
stages_ids = [s for s in stages_ids_raw.split(';') if s]
for pk in stages_ids:
stage = Stage.objects.get(pk=pk)
stages_names.append(stage.name)
stage.is_paid = True
order = stage.order
stage.save()
inv_history = InvoiceHistory()
inv_history.comment = 'Резервирование средств за этапы ' + ' , '.join(stages_names) + ' заказа' + str(order)
inv_history.sum = -instance.sum
inv_history.user = instance.customer
inv_history.type = "score"
inv_history.save()

@ -0,0 +1 @@
<h1> Ваш счет: {{ score }}</h1>

@ -1,7 +1,7 @@
from django.conf import urls, settings from django.conf import urls, settings
from django.views.generic import TemplateView from django.views.generic import TemplateView
from .views import ScoreDetailView, WithDrawCreate, ScoreView from .views import PayFromScore, WithDrawCreate, ScoreView
app_name = 'wallets' app_name = 'wallets'
@ -10,7 +10,8 @@ urlpatterns = [
# urls.url(r'^score/(?P<pk>\d+)/$', ScoreDetailView.as_view(), name='score-detail'), # urls.url(r'^score/(?P<pk>\d+)/$', ScoreDetailView.as_view(), name='score-detail'),
urls.url(r'^score/(?P<pk>\d+)/$', ScoreView.as_view(), name='score-detail'), urls.url(r'^score/(?P<pk>\d+)/$', ScoreView.as_view(), name='score-detail'),
urls.url(r'^withdraw/create/$', WithDrawCreate.as_view(), name='withdraw-create'), urls.url(r'^withdraw/create/$', WithDrawCreate.as_view(), name='withdraw-create'),
urls.url(r'^payfromscore/$', PayFromScore.as_view(), name='payfromscore'),
urls.url( urls.url(
r'^tmp-yamoney-req/$', r'^tmp-yamoney-req/$',
TemplateView.as_view(template_name='tmp_yandex_money_request_example.html'), TemplateView.as_view(template_name='tmp_yandex_money_request_example.html'),

@ -13,8 +13,34 @@ from django.views.generic.base import View
import logging import logging
from users.models import User from users.models import User
from .forms import WithDrawForm, TmpCheckOrderForm, TmpPaymentAvisoForm from .forms import WithDrawForm, TmpCheckOrderForm, TmpPaymentAvisoForm, PayFromScoreForm
from .models import InvoiceHistory, WithDraw, Transaction from .models import InvoiceHistory, WithDraw, Transaction, PayFromScore
class PayFromScore(CreateView):
model = PayFromScore
form_class = PayFromScoreForm
def form_valid(self, form):
if self.request.is_ajax():
self.object = form.save(commit=False)
self.object.customer = self.request.user
self.object.save()
data = {
'pk': self.object.pk,
'status': 'ok',
}
return JsonResponse(data)
return super().form_valid(form)
def form_invalid(self, form):
if self.request.is_ajax():
data = {
'errors': form.errors,
'status': 'error',
}
return JsonResponse(data)
return super().form_invalid(form)
class ScoreDetailView(DetailView): class ScoreDetailView(DetailView):

@ -0,0 +1,16 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.9.7 on 2016-09-02 07:45
from __future__ import unicode_literals
from django.db import migrations
class Migration(migrations.Migration):
dependencies = [
('work_sell', '0009_auto_20160901_1548'),
('work_sell', '0009_auto_20160901_1247'),
]
operations = [
]
Loading…
Cancel
Save