diff --git a/archilance/settings/base.py b/archilance/settings/base.py index 9fefbaf..670ed41 100644 --- a/archilance/settings/base.py +++ b/archilance/settings/base.py @@ -41,6 +41,7 @@ THIRD_PARTY_APPS = [ 'mathfilters', # Basic math operations in templates; https://pypi.python.org/pypi/django-mathfilters 'generic_relations', # https://github.com/Ian-Foote/rest-framework-generic-relations 'hitcount', + 'django_activeurl', ] LOCAL_APPS = [ @@ -85,6 +86,7 @@ TEMPLATES = [ 'django.template.context_processors.request', 'django.contrib.auth.context_processors.auth', 'django.contrib.messages.context_processors.messages', + 'django.core.context_processors.request', ], # Load these templatetags by default: diff --git a/assets/js/chat.js b/assets/js/chat.js index c4478b4..d8e0883 100644 --- a/assets/js/chat.js +++ b/assets/js/chat.js @@ -20,7 +20,7 @@ var SocketHandler = function () { } else if (message.answer_type == 'add_message_team') { inbox = document.getElementById('message-chat-team-space'); } else if (message.answer_type == 'approve_stages') { - alert('approve stages'); + console.log('approve stages'); } if (inbox) { var textMessage = message.msg; @@ -94,6 +94,15 @@ function csrfSafeMethod(method) { $(function () { + setTimeout(function () { + $(".user-block").first().trigger('click'); + }, 10); + + setTimeout(function () { + $(".order-block").first().trigger('click'); + }, 100); + + $('.deleteMess').on('click', function (e) { e.preventDefault(); e.stopPropagation(); diff --git a/assets/js/chat_customer.js b/assets/js/chat_customer.js new file mode 100644 index 0000000..3e758a9 --- /dev/null +++ b/assets/js/chat_customer.js @@ -0,0 +1,320 @@ +$(function () { + var currentChatUser = { + { + request.user.pk + } +} + ; + var socket = new SocketHandler(); + var form = document.getElementById('message_form'); + var csrftoken = getCookie('csrftoken'); + + $("#reserve-button").on("click", function (e) { + e.preventDefault(); + var orderId = $(this).attr('data-order-id'); + $.ajax({ + url: '/api/stages/', + type: 'GET', + data: {csrfmiddlewaretoken: csrftoken, 'order': orderId}, + dataType: 'json', + success: function (json) { + console.log(json.results); + } + }); + }); + + function getStages(orderId, senderId, recipentId) { + + $.ajax({ + url: '/api/stages/', + type: 'GET', + data: {csrfmiddlewaretoken: csrftoken, 'order': orderId}, + dataType: 'json', + success: function (json) { + var stageCount = json.results.length; + if (stageCount == 0) { + stageCountVal = 1; + } else { + stageCountVal = stageCount; + } + + var htmlInbox = ""; + + var htmlInboxStage = '

Какое кол-во этапов подразумевает работа? ' + + '

'; + + if (stageCount == 0) { + htmlInboxStage += '
' + + '

Этап 1

' + + '' + + '' + + '' + + '' + + '' + + '' + + '
'; + } + var statusNotAgreed = true; + $.each(json.results, function (i, v) { + if (v.status == "not_agreed") { + htmlInbox += '
' + + '

Этап

' + + '' + + '' + + '' + + '' + + '' + + '
'; + } else { + statusNotAgreed = false; + htmlInboxStage = ""; + htmlInbox += '
' + + '

Этап ' + v.pos + '' + v.name + '

' + + '

Результаты этапа:' + v.result + '

' + + '

до Дата

' + v.cost + '
'; + + } + }); + + if (statusNotAgreed) { + htmlInbox += '
Перейти в режим безопасной сделки' + + '
' + + 'отправить на согласование
'; + } + htmlInbox = htmlInboxStage + htmlInbox; + $("#order-stages").html(htmlInbox); + } + }); + } + + setTimeout(function () { + $(".user-block").first().trigger('click'); + }, 10); + + setTimeout(function () { + $(".order-block").first().trigger('click'); + }, 100); + + $("#order-stages").on('click', "#addStagesForm", function (e) { + e.preventDefault(); + $(".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(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 currentOrderId = $(this).attr('data-order-id'); + var currentRecipentId = $(this).attr('data-recipent-id'); + + getStages(currentOrderId, userId, currentRecipentId); + + socket.send_stages_approve({ + "format_type": "approve_stages", + "data": { + "sender_id": userId, + "recipent_id": currentRecipentId, + "order_id": currentOrderId, + } + }); + + + }); + + $('#order-stages-tab').on('change', '#countStage', function () { + var countStage = parseInt($(this).val()); + var currentCountStage = $(".numberStepp").length; + + 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 = '
' + + '

Этап ' + pos + '

' + + '' + + '' + + '' + + '' + + '' + + '' + '
'; + + 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 recipentId = $(this).attr('data-recipent-id'); + $("#chat-order-add #orderId").val(orderId); + $("#projectReviewId").val(orderId); + $("#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'); + inbox.innerHTML = ''; + $.ajax({ + url: '/api/message', + type: 'GET', + data: {csrfmiddlewaretoken: csrftoken, 'order': orderId}, + 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 += '
' + + '

' + senderName + '

' + v.created + '
' + + '

' + v.text + '

'; + }); + } + }); + getStages(orderId, userId, recipentId); + }); + + // Вытащить сообщения для конактов + $('.user-block').on('click', function () { + var userId = $(this).attr('data-id'); + $("#contact-chat-form #recipentId").val(userId); + $("#add-form-contractor-note #recipentNoteContractor").val(userId); + + $('.user-block').each(function () { + $(this).removeClass('mesAct'); + }); + + $(this).addClass('mesAct'); + var inbox = document.getElementById('message-chat-space'); + inbox.innerHTML = ''; + $.ajax({ + url: '/api/message', + type: 'GET', + data: { + csrfmiddlewaretoken: csrftoken, + 'operand': 'in', + 'sender_id': currentChatUser, + 'recipent_id': userId + }, + dataType: 'json', + success: function (json) { + $.each(json.results, function (i, v) { + var senderName = 'Вы'; + var className = 'youChat'; + if (v.sender.id == userId) { + senderName = v.sender.username; + className = ''; + } + inbox.innerHTML += '
' + + '

' + senderName + '

' + v.created + '
' + + '

' + v.text + '

'; + }); + } + }); + + }); + + $('#contact-chat-add-message').on('click', function (e) { + e.preventDefault(); + var chatMessage = $("#chat").val(); + var recipentId = $("#recipentId").val(); + var senderId = $("#senderId").val(); + + socket.add_contact_message({ + "format_type": "add_message_contact", + "data": { + "sender_id": senderId, + "recipent_id": recipentId, + "chat_message": chatMessage, + } + }); + + $("#chat").val(""); + }); + + $('#order-review-add').on('click', function () { + alert('add review'); + }); + + $('#order-chat-add-message').on('click', function (e) { + e.preventDefault(); + var chatMessage = $("#chat-order-add #chat").val(); + var recipentId = $("#chat-order-add #recipentId").val(); + var senderId = $("#chat-order-add #senderId").val(); + var orderId = $("#chat-order-add #orderId").val(); + + socket.add_contact_message({ + "format_type": "add_message_order", + "data": { + "sender_id": senderId, + "recipent_id": recipentId, + "chat_message": chatMessage, + "order_id": orderId, + + } + }); + + $("#chat-order-add #chat").val(""); + }); + +}); +var userId = '{{ request.user.pk }}'; diff --git a/chat/templates/chat_contractor.html b/chat/templates/chat_contractor.html index edc5f95..c76cb06 100644 --- a/chat/templates/chat_contractor.html +++ b/chat/templates/chat_contractor.html @@ -162,6 +162,18 @@ +
+

3 / Выполнение работы

+

+ Процесс выполнения задания в заказе до получения + заказчиком итогового результата работы. +

+
+ +
+
+ +
@@ -275,14 +287,6 @@ var form = document.getElementById('message_form'); var csrftoken = getCookie('csrftoken'); - setTimeout(function () { - $(".user-block").first().trigger('click'); - }, 10); - - setTimeout(function () { - $(".order-block").first().trigger('click'); - }, 100); - setTimeout(function () { $(".team-order-block").first().trigger('click'); }, 1000); @@ -454,9 +458,14 @@ console.log(json.results); var htmlInbox = ""; var stagesReservedHtml = ""; + var stagesPaidProcess = []; if (json.results.length > 0) { $.each(json.results, function (i, v) { + + if ((v.status == "in_process") && (v.is_paid)){ + stagesPaidProcess.push(v); + } if (v.is_paid) { stagesReservedHtml += '
  • Сумма за этап ' + v.pos + '.Зарезервирована.
  • '; } else { @@ -465,7 +474,7 @@ htmlInbox += '
    ' + '

    Этап ' + v.pos + '' + v.name + '

    ' + '

    Результаты этапа:' + v.result + '

    ' + - '

    ' + v.status + '

    ' + v.cost + '
    '; + '

    ' + v.term + '

    ' + v.cost + '
    '; }); htmlInbox += '
    согласовать
    '; @@ -473,6 +482,20 @@ $("#order-stages").html(htmlInbox); $(".stages-paid").html(stagesReservedHtml); + + if (stagesPaidProcess.length > 0){ + $("#completeWork").show(); + var stage = stagesPaidProcess[0]; + var stageWork = '

    В работе '+ stage.name +'

    ' + + '

    Результат этапа : '+ stage.result +'

    ' + + '

    Срок сдачи 25.08.2016 ' + stage.cost + 'р.

    ' + + 'Завершить этап' + + 'Обратитьсяв арбитраж'; + $("#stagesWork").html(stageWork); + }else{ + $("#completeWork").hide(); + } + } }); @@ -500,6 +523,28 @@ }); }); + $('#tab2').on('click','.closeStage', function(e){ + e.preventDefault(); + var stageId = $(this).attr('data-stage-id'); + $.ajax({ + url: '/api/stages/' + stageId + '/', + type: 'PATCH', + beforeSend: function (xhr) { + xhr.setRequestHeader("X-CSRFToken", getCookie('csrftoken')) + }, + data: "close_contractor=True", + dataType: 'json', + success: function (json) { + alert(json); + console.log(json); + }, + error: function (e) { + console.log('error'); + console.log(e); + } + }); + }); + // Вытащить сообщения для конактов diff --git a/chat/templates/chat_customer.html b/chat/templates/chat_customer.html index ac5c268..c447189 100644 --- a/chat/templates/chat_customer.html +++ b/chat/templates/chat_customer.html @@ -106,7 +106,7 @@

    Заказы

    {% for order in orders %}
    + 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 }}">

    {{ order }}

    @@ -156,7 +156,7 @@
    -
    + @@ -173,12 +173,16 @@ {% include 'reverse_stage_modal.html' %} -
    -

    3 / Выполнение работы

    -

    - Процесс выполнения задания в заказе до получения заказчиком итогового результата работы. -

    -
    +
    +

    3 / Выполнение работы

    +

    + Процесс выполнения задания в заказе до получения + заказчиком итогового результата работы. +

    +
    + +
    +
    @@ -188,7 +192,7 @@
    -
    + @@ -273,20 +230,64 @@ var csrftoken = getCookie('csrftoken'); $("#reserve-button").on("click",function(e) { - e.preventDefault(); + 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) { - console.log(json.results); - } - }); + + $.ajax({ + url: '/api/stages/', + type: 'GET', + data: {csrfmiddlewaretoken: csrftoken, 'order': orderId}, + dataType: 'json', + success: function (json) { + var outputValues = ''; + var totalSum = 0; + var stagesIds = ''; + $.each(json.results, function (i, v) { + console.log(v.cost); + totalSum += parseInt(v.cost); + outputValues += ''; + stagesIds += v.id + ';' + }); + $("#stagesSelect").html(outputValues); + $(".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({ url: '/api/stages/', @@ -296,6 +297,7 @@ success: function (json) { var stageCount = json.results.length; if (stageCount == 0) { + $("#reserveSpace").hide(); stageCountVal = 1; } else { stageCountVal = stageCount; @@ -314,11 +316,17 @@ '' + '' + '' + - '' + + '' + '
    '; } var statusNotAgreed = true; + var stagesPaidProcess = []; + $.each(json.results, function (i, v) { + + if ((v.status == "in_process") && (v.is_paid)){ + stagesPaidProcess.push(v); + } if (v.status == "not_agreed") { htmlInbox += '
    ' + '

    Этап

    ' + @@ -334,30 +342,73 @@ htmlInbox += '
    ' + '

    Этап ' + v.pos + '' + v.name + '

    ' + '

    Результаты этапа:' + v.result + '

    ' + - '

    до Дата

    ' + v.cost + '
    '; + '

    до Дата

    ' + v.cost + '' + + '
    '; } }); if (statusNotAgreed) { - htmlInbox += '
    Перейти в режим безопасной сделки' + - '
    ' + - 'отправить на согласование
    '; + if(secureOrder) { + var orderSecureCheckbox = 'checked="checked"'; + htmlInbox += '
    ' + + '
    ' + + 'Перейти в режим безопасной сделки
    '; + } + + htmlInbox +='
    ' + + 'отправить на согласование
    '; + }else if(json.results.length>0){ + $("#reserveSpace").show(); } htmlInbox = htmlInboxStage + htmlInbox; $("#order-stages").html(htmlInbox); + + + if (stagesPaidProcess.length > 0){ + $("#completeWork").show(); + var stage = stagesPaidProcess[0]; + var stageWork = '

    В работе '+ stage.name +'

    ' + + '

    Результат этапа : '+ stage.result +'

    ' + + '

    Срок сдачи 25.08.2016 ' + stage.cost + 'р.

    '; + + if (stage.close_contractor){ + stageWork += 'Закрыть этап '+ stage.pos +''; + } + $("#stagesWork").html(stageWork); + }else{ + $("#completeWork").hide(); + } } }); } - setTimeout(function () { - $(".user-block").first().trigger('click'); - }, 10); + //Закрыть этап + $('#tab2').on('click','.closeStage', function(e){ + e.preventDefault(); + var stageId = $(this).attr('data-stage-id'); + $.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) { + console.log(json); + }, + error: function (e) { + console.log('error'); + console.log(e); + } + }); + }); - setTimeout(function () { - $(".order-block").first().trigger('click'); - }, 100); + // Добавление этапов $("#order-stages").on('click', "#addStagesForm", function (e) { e.preventDefault(); $(".new-stages-form").each(function (i, v) { @@ -403,11 +454,10 @@ }); }); - var currentOrderId = $(this).attr('data-order-id'); var currentRecipentId = $(this).attr('data-recipent-id'); - - getStages(currentOrderId,userId,currentRecipentId); + var secureOrder = true + getStages(currentOrderId,userId,currentRecipentId,secureOrder); socket.send_stages_approve({ "format_type": "approve_stages", @@ -421,6 +471,7 @@ }); + //Изменение счетчика $('#order-stages-tab').on('change', '#countStage', function () { var countStage = parseInt($(this).val()); var currentCountStage = $(".numberStepp").length; @@ -437,11 +488,9 @@ '' + '' + '' + - '' + '' '
    '; - lastFormStage.after(addFormTemplate); - } }else if (countStage < currentCountStage) { @@ -456,6 +505,7 @@ } }); + // Для заказов все вытащить $('.order-block').on('click', function () { $("#chat-order-add").css("display", "block"); $("#formsetStage").css("display", "block"); @@ -467,6 +517,8 @@ $(this).addClass('orAct'); var orderId = $(this).attr('data-id'); var recipentId = $(this).attr('data-recipent-id'); + var secureOrder = $(this).attr('data-secure-deal'); + secureOrder = Boolean(secureOrder); $("#chat-order-add #orderId").val(orderId); $("#projectReviewId").val(orderId); $("#reserve-button").attr('data-order-id', orderId); @@ -496,7 +548,7 @@ }); } }); - getStages(orderId,userId,recipentId); + getStages(orderId,userId,recipentId, secureOrder); }); // Вытащить сообщения для конактов @@ -557,8 +609,28 @@ $("#chat").val(""); }); - $('#order-review-add').on('click', function () { - alert('add review'); + // Добавление отзыва + $('#order-review-add').on('click', function (e) { + e.preventDefault(); + e.stopPropagation(); + var formData = $("#review-adds-form").serialize(); + $.ajax({ + url: '/api/reviews/', + type: 'POST', + beforeSend: function (xhr) { + xhr.setRequestHeader("X-CSRFToken", getCookie('csrftoken')) + }, + data: formData, + dataType: 'json', + success: function (json) { + console.log("Успешно"); + console.log(json); + }, + error: function (e) { + console.log('error'); + console.log(e); + } + }); }); $('#order-chat-add-message').on('click', function (e) { diff --git a/chat/templates/reverse_stage_modal.html b/chat/templates/reverse_stage_modal.html index 2c483ff..ef4701a 100644 --- a/chat/templates/reverse_stage_modal.html +++ b/chat/templates/reverse_stage_modal.html @@ -12,13 +12,13 @@

    Сумма оплаты всего заказа

    - Общий бюджет заказа: 300 р.
    - Итого к оплате: 344 рубля + Общий бюджет заказа: р.
    + Итого к оплате: р.

    @@ -26,28 +26,45 @@
    -

    Оплатить этап


    +

    Оплатить этап


    - Бюджет Этапа 1: 300 р.
    - Итого к оплате: 344 р. + Бюджет Этапа 1: р.
    + Итого к оплате: р.

    -

    Резервирование средств

    +
    {% csrf_token %} + + + +
    +
    diff --git a/chat/templates/review_add_modal.html b/chat/templates/review_add_modal.html new file mode 100644 index 0000000..21a2b19 --- /dev/null +++ b/chat/templates/review_add_modal.html @@ -0,0 +1,49 @@ + diff --git a/chat/views.py b/chat/views.py index 63fb363..424e45b 100644 --- a/chat/views.py +++ b/chat/views.py @@ -1,5 +1,6 @@ import json from django.shortcuts import render +from django.conf import settings from django.views.generic import View from django.http import HttpResponse, Http404 from django.db.models import Q @@ -7,6 +8,7 @@ from django.contrib.auth.mixins import LoginRequiredMixin from .models import Message from projects.models import Order +from wallets.models import Transaction from users.models import User, Team @@ -16,7 +18,7 @@ class ChatUserView(LoginRequiredMixin, View): def get(self, request, *args, **kwargs): # import code; code.interact(local=dict(globals(), **locals())) 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'). \ 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)) 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' return render(request, self.template_name, {'contacts_users': contacts_users, 'chat_messages': chat_messages, - 'orders': orders}) + 'orders': orders, + 'transaction': transaction[0], + 'YANDEX_MONEY': settings.YANDEX_MONEY, + }) else: orders = request.user.orders.all() contractor_contacts = Message.objects.values_list('sender_id', 'recipent_id').filter( @@ -60,13 +67,13 @@ class ChatUserView(LoginRequiredMixin, View): 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() - # team_orders = [] self.template_name = 'chat_contractor.html' return render(request, self.template_name, {'orders': orders, 'contacts_users': contacts_users, 'chat_messages': chat_messages, 'team_orders': team_orders, + }) diff --git a/projects/migrations/0014_auto_20160824_0154.py b/projects/migrations/0014_auto_20160824_0154.py new file mode 100644 index 0000000..3cfca16 --- /dev/null +++ b/projects/migrations/0014_auto_20160824_0154.py @@ -0,0 +1,29 @@ +# -*- coding: utf-8 -*- +# Generated by Django 1.9.7 on 2016-08-23 22:54 +from __future__ import unicode_literals + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('projects', '0013_auto_20160819_1735'), + ] + + operations = [ + migrations.AlterModelOptions( + name='project', + options={'ordering': ('-created',), 'verbose_name': 'Проект', 'verbose_name_plural': 'Проекты'}, + ), + migrations.AddField( + model_name='stage', + name='close_contractor', + field=models.BooleanField(default=False), + ), + migrations.AddField( + model_name='stage', + name='close_customer', + field=models.BooleanField(default=False), + ), + ] diff --git a/projects/migrations/0015_auto_20160824_1119.py b/projects/migrations/0015_auto_20160824_1119.py new file mode 100644 index 0000000..84fa9a6 --- /dev/null +++ b/projects/migrations/0015_auto_20160824_1119.py @@ -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), + ), + ] diff --git a/projects/migrations/0016_merge.py b/projects/migrations/0016_merge.py new file mode 100644 index 0000000..1de7e3d --- /dev/null +++ b/projects/migrations/0016_merge.py @@ -0,0 +1,16 @@ +# -*- coding: utf-8 -*- +# Generated by Django 1.9.7 on 2016-08-24 14:23 +from __future__ import unicode_literals + +from django.db import migrations + + +class Migration(migrations.Migration): + + dependencies = [ + ('projects', '0015_auto_20160824_1538'), + ('projects', '0015_auto_20160824_1119'), + ] + + operations = [ + ] diff --git a/projects/models.py b/projects/models.py index bfd5064..4be06fd 100644 --- a/projects/models.py +++ b/projects/models.py @@ -199,12 +199,17 @@ class AnswerFile(models.Model): class Order(models.Model): + STATUSES = ( + ('created', 'Создан'), + ('process', 'В процессе'), + ('completed', 'Завершен'), + ) contractor = models.ForeignKey(User, null=True, blank=True, related_name='orders') team = models.ForeignKey(Team, null=True, blank=True, related_name='orders') created = models.DateTimeField(default=timezone.now) project = models.OneToOneField(Project, related_name='order') secure = models.BooleanField(default=False) - status = models.BooleanField(default=False) + status = models.CharField(max_length=30, choices=STATUSES, default='created') def __str__(self): return self.project.name @@ -233,6 +238,8 @@ class Stage(models.Model): created = models.DateTimeField(default=timezone.now) pos = models.IntegerField(default=0, null=True, blank=True) is_paid = models.BooleanField(default=False) + close_contractor = models.BooleanField(default=False) + close_customer = models.BooleanField(default=False) def __str__(self): return self.name diff --git a/projects/serializers.py b/projects/serializers.py index 89fd9f7..0d8fa2e 100755 --- a/projects/serializers.py +++ b/projects/serializers.py @@ -80,6 +80,8 @@ class StageSerializer(ModelSerializer): 'pos', 'status', 'is_paid', + 'close_contractor', + 'close_customer', ) diff --git a/projects/views.py b/projects/views.py index 9558191..4590e0d 100644 --- a/projects/views.py +++ b/projects/views.py @@ -357,8 +357,12 @@ class CustomerProjectCreateView(BaseMixin, View): project.save() form.save_m2m() - Order.objects.create(project=project) + secure = False + if 'secure_deal' in project.deal_type: + secure = True + Order.objects.create(project=project, secure=secure) + for file in request.FILES.getlist('new_files'): ProjectFile.objects.create(file=file, project=project) diff --git a/requirements/base.txt b/requirements/base.txt index b64af10..1c0f8de 100644 --- a/requirements/base.txt +++ b/requirements/base.txt @@ -41,3 +41,4 @@ django-mathfilters gunicorn==19.6.0 rest-framework-generic-relations django-hitcount +django-activeurl==0.1.9 diff --git a/templates/partials/header.html b/templates/partials/header.html index 34bd116..2f88de2 100644 --- a/templates/partials/header.html +++ b/templates/partials/header.html @@ -1,6 +1,7 @@ {% load staticfiles %} {% load thumbnail %} {% load user_tags %} +{% load activeurl %}
    @@ -8,7 +9,7 @@
    - +{% activeurl %} {% if request.user.is_authenticated %}
    {% endif %} - +{% endactiveurl %} {% if request.user.is_authenticated %}
    diff --git a/wallets/migrations/0009_transaction_stages_id.py b/wallets/migrations/0009_transaction_stages_id.py new file mode 100644 index 0000000..a8de5a4 --- /dev/null +++ b/wallets/migrations/0009_transaction_stages_id.py @@ -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), + ), + ] diff --git a/wallets/models.py b/wallets/models.py index bebbc19..6acef3a 100644 --- a/wallets/models.py +++ b/wallets/models.py @@ -70,6 +70,7 @@ class Transaction(models.Model): voids_at = models.DateTimeField() sum = models.DecimalField(max_digits=20, decimal_places=0, default=0) 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): if not self.pk and self.created_at: diff --git a/wallets/views.py b/wallets/views.py index 5fb5406..5eced5c 100644 --- a/wallets/views.py +++ b/wallets/views.py @@ -33,13 +33,14 @@ class ScoreView(LoginRequiredMixin, View): template_name = 'score-detail.html' def get(self, request, *args, **kwargs): - transaction = Transaction.objects.create(customer=request.user, type='add') + # transaction = Transaction.objects.get_or_create(customer=request.user, complete=False) + transaction = Transaction.objects.get_or_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, { - 'transaction': transaction, + 'transaction': transaction[0], 'YANDEX_MONEY': settings.YANDEX_MONEY, 'user_score': user_score, 'user_score_balance': user_score_balance,