#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_SECRET = '95e88f7ef396c5b803375f8476cf2ba4'
SOCIAL_AUTH_FACEBOOK_KEY = '1030546170341186'
SOCIAL_AUTH_FACEBOOK_SECRET = '1b22e95040b209c5d2f2d7f69462bf95'
SOCIAL_AUTH_FACEBOOK_KEY = '1047362798683484'
SOCIAL_AUTH_FACEBOOK_SECRET = '98fedcccb1cb941c2289692bd4de84da'
SOCIAL_AUTH_FACEBOOK_SCOPE = ['email']
SOCIAL_AUTH_FACEBOOK_PROFILE_EXTRA_PARAMS = {

@ -168,7 +168,27 @@ $(function () {
$("#paymentfromSite").on('click',function(){
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);
$(".totalSum").text(totalSum);
if(json.results.length>notPaidCount && notPaidCount>0){
$("#choiceWayOrder").hide();
}
$("#choiceWayOrder").val(totalSum)
$("#choiceWayOrder").val(totalSum);
$("#ordermodalId").val(orderId);
$("#stages-pay-form #stageSumPay").val(totalSum);
$("#stages-pay-form #stagesIds").val(stagesIds);
$("#choiceWayOrder").attr('data-stages-ids',stagesIds);
}
@ -455,7 +460,6 @@
$("#stagesWork").html(stageWork);
}
if (!data.secure){
$("#reserveSpace").hide();
}

@ -55,6 +55,7 @@
<input type='hidden' name='paymentType' value='AC'>
<input type='hidden' name='transactionId' value='{{ transaction.pk }}'>
<input type='hidden' name='stagesId' id='stagesIds' value=''>
<input type='hidden' name='ordermodalId' id='ordermodalId'>
</div>
<button type="submit" class="btn btn-primary btn-lg btn-block">Пополнить</button>
</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):
stages = StageSerializer(many=True, read_only=True)
project = ProjectSerializer(read_only=True)
has_user_review = serializers.SerializerMethodField(read_only=True)
class Meta:
model = Order
@ -116,10 +117,16 @@ class OrderSerializer(ModelSerializer):
'project',
'secure',
'status',
'has_user_review',
'stages',
'project',
)
def get_has_user_review(self,obj):
# obj.project.
print(self.context['request'].user)
return "yes"
class PortfolioPhotoSerializer(ModelSerializer):
img = ImageField()

@ -220,7 +220,7 @@ class User(AbstractBaseUser, PermissionsMixin):
def get_popular_specialization(self):
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):

@ -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-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">
<ul class="nav nav-tabs nav-justified">
@ -22,8 +23,8 @@
</div>
</li>
<li role="presentation">
<a href="{% url 'chat:chat-user' %}">Проекты в работе</a>
<li role="presentation" {% if request.path == contractor_office_chat_projects_url %}class="active"{% endif %}>
<a href="{{ contractor_office_chat_projects_url }}">Проекты в работе</a>
<div class="roundsCount">
<div class="countG">0</div>

@ -16,6 +16,7 @@ from .views import (
TeamCreateView,
UserFinancialInfoEditView,
UserProfileEditView,
ContractorChatProjectsView,
)
@ -37,4 +38,5 @@ urlpatterns = [
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+)/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.mixins import BaseMixin
from projects.forms import PortfolioForm
from projects.models import Project, Portfolio
from projects.models import Project, Portfolio, Order
from reviews.models import Review
from specializations.models import Specialization
from work_sell.forms import WorkSellForm
from work_sell.models import WorkSell, Picture
from chat.models import Message
from .forms import (
ContractorFilterForm,
@ -399,6 +400,38 @@ class ContractorOfficeView(DetailView):
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):
template_name = 'contractor_office_open_projects.html'

@ -2,7 +2,7 @@ from django.contrib import admin
from import_export import resources
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):
@ -28,3 +28,4 @@ admin.site.register(InvoiceHistory, InvoiceHistoryAdmin)
admin.site.register(WithDraw, WithDrawAdmin)
admin.site.register(Transaction, TransactionAdmin)
admin.site.register(Wallet)
admin.site.register(PayFromScore)

@ -1,7 +1,7 @@
from django import forms
from django.conf import settings
from .models import WithDraw
from .models import WithDraw, PayFromScore
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):
action = forms.CharField() # Has to be "checkOrder"
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):
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.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
@ -69,6 +69,28 @@ def reserve_stages(sender, instance, created, **kwargs):
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.views.generic import TemplateView
from .views import ScoreDetailView, WithDrawCreate, ScoreView
from .views import PayFromScore, WithDrawCreate, ScoreView
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+)/$', ScoreView.as_view(), name='score-detail'),
urls.url(r'^withdraw/create/$', WithDrawCreate.as_view(), name='withdraw-create'),
urls.url(r'^payfromscore/$', PayFromScore.as_view(), name='payfromscore'),
urls.url(
r'^tmp-yamoney-req/$',
TemplateView.as_view(template_name='tmp_yandex_money_request_example.html'),

@ -13,8 +13,34 @@ from django.views.generic.base import View
import logging
from users.models import User
from .forms import WithDrawForm, TmpCheckOrderForm, TmpPaymentAvisoForm
from .models import InvoiceHistory, WithDraw, Transaction
from .forms import WithDrawForm, TmpCheckOrderForm, TmpPaymentAvisoForm, PayFromScoreForm
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):

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