diff --git a/api/test.py b/api/test.py new file mode 100644 index 0000000..269a6c8 --- /dev/null +++ b/api/test.py @@ -0,0 +1,6 @@ +from rest_framework.test import APITestCase + + +class FileUploadTests(APITestCase): + pass + diff --git a/api/urls.py b/api/urls.py index a414824..319beed 100755 --- a/api/urls.py +++ b/api/urls.py @@ -9,6 +9,7 @@ from .views import ( MessageViewSet, StageViewSet, NoteViewSet, + DocumentViewSet, ) @@ -17,6 +18,7 @@ router = routers.DefaultRouter() router.register(r'locations', LocationViewSet) router.register(r'projects', ProjectViewSet) router.register(r'stages', StageViewSet) +router.register(r'documents', DocumentViewSet) router.register(r'realties', RealtyViewSet) router.register(r'specializations', SpecializationViewSet) router.register(r'users', UserViewSet) diff --git a/api/views.py b/api/views.py index a2dd477..f4e4f4a 100755 --- a/api/views.py +++ b/api/views.py @@ -18,9 +18,9 @@ from common.models import Location from common.serializers import LocationSerializer from common.filters import LocationFilterSet -from chat.models import Message, Notes -from chat.serializers import MessageSerializer, NoteSerializer -from chat.filters import MessageFilterSet, NoteFilterSet +from chat.models import Message, Notes, Documents +from chat.serializers import MessageSerializer, NoteSerializer, DocumentsSerializer +from chat.filters import MessageFilterSet, NoteFilterSet, DocumentsFilterSet class StageViewSet(ModelViewSet): @@ -30,6 +30,13 @@ class StageViewSet(ModelViewSet): permission_classes = (permissions.IsAuthenticatedOrReadOnly,) +class DocumentViewSet(ModelViewSet): + queryset = Documents.objects.all() + serializer_class = DocumentsSerializer + # filter_class = DocumentsFilterSet + # permission_classes = (permissions.IsAuthenticatedOrReadOnly,) + + class ProjectViewSet(ModelViewSet): queryset = Project.objects.all() serializer_class = ProjectSerializer diff --git a/archilance/settings/base.py b/archilance/settings/base.py index 72aa5ba..9b25660 100644 --- a/archilance/settings/base.py +++ b/archilance/settings/base.py @@ -12,11 +12,10 @@ SECRET_KEY = 'vb6@b9zj7^f!^+x*e8=e!oundyu1!e*&0i(3gu2xwo4%fx4h&n' # SECURITY WARNING: don't run with debug turned on in production! DEBUG = True -TEMPLATE_DEBUG = True # Show debug info in templates. See `projects/templates/project_filter.html` +TEMPLATE_DEBUG = True # Show debug info in templates. See `projects/templates/project_filter.html` ALLOWED_HOSTS = [] - # Application definition DJANGO_APPS = [ @@ -39,20 +38,21 @@ THIRD_PARTY_APPS = [ 'sorl.thumbnail', 'compressor', 'password_reset', - 'mathfilters', # Basic math operations in templates; https://pypi.python.org/pypi/django-mathfilters + 'mathfilters', # Basic math operations in templates; https://pypi.python.org/pypi/django-mathfilters ] LOCAL_APPS = [ - 'specializations', - 'api', - 'common', - 'work_sell', - 'archilance', - 'projects', - 'users', - 'reviews', - 'chat', - 'wallets', + 'specializations', + 'api', + 'common', + 'work_sell', + 'archilance', + 'projects', + 'users', + 'reviews', + 'chat', + 'wallets', + 'ratings', ] INSTALLED_APPS = DJANGO_APPS + THIRD_PARTY_APPS + LOCAL_APPS @@ -85,7 +85,6 @@ TEMPLATES = [ 'django.contrib.messages.context_processors.messages', ], - # Load these templatetags by default: 'builtins': [ @@ -99,7 +98,6 @@ TEMPLATES = [ WSGI_APPLICATION = 'archilance.wsgi.application' - # Database # https://docs.djangoproject.com/en/1.9/ref/settings/#databases @@ -121,7 +119,6 @@ DATABASES = { } } - # Password validation # https://docs.djangoproject.com/en/1.9/ref/settings/#auth-password-validators @@ -209,7 +206,6 @@ USE_L10N = True USE_TZ = True - # Static files (CSS, JavaScript, Images) # https://docs.djangoproject.com/en/1.9/howto/static-files/ @@ -261,10 +257,10 @@ EMAIL_PORT = 25 EMAIL_BACKEND = 'django.core.mail.backends.smtp.EmailBackend' -SHELL_PLUS_POST_IMPORTS = ( # Extra auto imports +SHELL_PLUS_POST_IMPORTS = ( # Extra auto imports 'natsort', ('archilance', 'util'), ('pprint', ('pprint', 'pformat')), ) -PAGE_SIZE = 10 # Pagination +PAGE_SIZE = 10 # Pagination diff --git a/archilance/views.py b/archilance/views.py index f122e41..feec3a6 100644 --- a/archilance/views.py +++ b/archilance/views.py @@ -1,11 +1,13 @@ from django.views.generic import TemplateView, View from django.shortcuts import render from django.template.loader import render_to_string - +from django.core.files.base import ContentFile +from work_sell.models import Picture from projects.models import Order from common.models import MainPage, PrintDocuments from users.models import ContractorResumeFiles - +from chat.models import Documents +from work_sell.models import Picture class HomeTemplateView(View): template_name = 'home.html' @@ -19,5 +21,16 @@ class TestChatTemplateView(View): template_name = 'chat_test.html' def get(self, request, *args, **kwargs): - diploms = ContractorResumeFiles.objects.all() - return render(request, 'chat_test.html', {'diploms': diploms}) + test = [54,55,56] + for pk in test: + picture = Picture.objects.get(pk=pk) + temp_file = ContentFile(picture.file.read()) + temp_file.name = picture.file.name + document = Documents() + document.team_id = 1 + document.order_id = 2 + document.sender_id = 2 + document.recipent_id = 4 + document.file = temp_file + document.save() + diff --git a/chat/admin.py b/chat/admin.py index 127440a..bad96cc 100644 --- a/chat/admin.py +++ b/chat/admin.py @@ -1,5 +1,5 @@ from django.contrib import admin -from .models import Message, Notes +from .models import Message, Notes, Documents class MessageAdmin(admin.ModelAdmin): @@ -10,5 +10,10 @@ class NotesAdmin(admin.ModelAdmin): list_display = ('text', 'sender', 'recipent', 'order',) +class DocumentsAdmin(admin.ModelAdmin): + list_display = ('file', 'sender', 'recipent', 'order','team') + + admin.site.register(Message, MessageAdmin) admin.site.register(Notes, NotesAdmin) +admin.site.register(Documents, DocumentsAdmin) diff --git a/chat/filters.py b/chat/filters.py index 727b598..19a1ab6 100644 --- a/chat/filters.py +++ b/chat/filters.py @@ -1,6 +1,17 @@ from rest_framework_filters import FilterSet, RelatedFilter, AllLookupsFilter -from .models import Message, Notes +from .models import Message, Notes, Documents + + +class DocumentsFilterSet(FilterSet): + file = AllLookupsFilter() + sender = RelatedFilter('users.filters.UserFilterSet') + recipent = RelatedFilter('users.filters.UserFilterSet') + # order = AllLookupsFilter() + # team = AllLookupsFilter() + + class Meta: + model = Documents class MessageFilterSet(FilterSet): diff --git a/chat/migrations/0003_documents.py b/chat/migrations/0003_documents.py new file mode 100644 index 0000000..8c30fc0 --- /dev/null +++ b/chat/migrations/0003_documents.py @@ -0,0 +1,35 @@ +# -*- coding: utf-8 -*- +# Generated by Django 1.9.7 on 2016-08-03 17:03 +from __future__ import unicode_literals + +from django.conf import settings +from django.db import migrations, models +import django.db.models.deletion + + +class Migration(migrations.Migration): + + dependencies = [ + migrations.swappable_dependency(settings.AUTH_USER_MODEL), + ('projects', '0013_auto_20160803_2003'), + ('users', '0003_auto_20160726_1931'), + ('chat', '0002_message_team'), + ] + + operations = [ + migrations.CreateModel( + name='Documents', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('file', models.FileField(upload_to='chat/documents/')), + ('order', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='order_documents', to='projects.Order')), + ('recipent', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='recipent_documents', to=settings.AUTH_USER_MODEL)), + ('sender', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='sender_documents', to=settings.AUTH_USER_MODEL)), + ('team', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='team_documents', to='users.Team')), + ], + options={ + 'verbose_name': 'Входящие Документы', + 'verbose_name_plural': 'Входящие Документы', + }, + ), + ] diff --git a/chat/serializers.py b/chat/serializers.py index 3397e72..cd43c8d 100644 --- a/chat/serializers.py +++ b/chat/serializers.py @@ -1,8 +1,22 @@ from rest_framework.serializers import ModelSerializer -from .models import Message, Notes +from .models import Message, Notes, Documents from users.serializers import UserSerializer +class DocumentsSerializer(ModelSerializer): + + class Meta: + model = Documents + + fields = ( + 'file', + 'sender', + 'recipent', + 'team', + 'order', + ) + + class MessageSerializer(ModelSerializer): sender = UserSerializer() recipent = UserSerializer() diff --git a/chat/templates/chat.js b/chat/templates/chat.js new file mode 100644 index 0000000..f40e51a --- /dev/null +++ b/chat/templates/chat.js @@ -0,0 +1,683 @@ + // + // function csrfSafeMethod(method) { + // // these HTTP methods do not require CSRF protection + // return (/^(GET|HEAD|OPTIONS|TRACE)$/.test(method)); + // } + // + // var SocketHandler = function () { + // var userId = {{ request.user.pk }}; + // var url = 'ws://127.0.0.1:8888/chat/' + userId + '/'; + // var sock = new WebSocket(url); + // var intervalId; + // sock.onopen = function () { + // console.log("Start connect"); + // intervalId = setInterval(function () { + // sock.send('{"dummy": 1}'); + // }, 150000); + // }; + // sock.onmessage = function (event) { + // console.log(event.data); + // var message = JSON.parse(event.data); + // var inbox; + // + // if (message.answer_type == 'contact' || message.answer_type == 'add_message_contact') { + // inbox = document.getElementById('message-chat-space'); + // } else if (message.answer_type == 'order' || message.answer_type == 'add_message_order') { + // inbox = document.getElementById('message-chat-order-space'); + // } else if(message.answer_type == 'add_message_team'){ + // inbox = document.getElementById('message-chat-team-space'); + // } + // console.log(message.answer_type); + // console.log(message.msg); + // + // inbox.innerHTML += '
' + + // '

ВЫ

13.0.2016
' + + // '

' + message.msg + '

'; + // }; + // + // this.send_contact_message = function (userId) { + // var data = { + // "format_type": "add_message", + // "user_id": userId + // } + // sock.send(JSON.stringify(data)); + // console.log(data); + // }; + // + // this.add_team_message = function(messageData){ + // + // console.log(messageData); + // sock.send(JSON.stringify(messageData)); + // } + // + // this.add_contact_message = function (messageData) { + // console.log(messageData); + // sock.send(JSON.stringify(messageData)); + // }; + // + // this.send_message = function (form) { + // var elements = form.elements; + // var data = {}; + // var i = 0; + // for (var i; i < elements.length; i++) { + // if (elements[i].name == 'message') { + // data[elements[i].name] = elements[i].value; + // } + // } + // sock.send(JSON.stringify(data)); + // var textareaMessage = document.getElementById("message"); + // textareaMessage.value = ""; + // } + // + // } + // + // $(function () { + // var currentChatUser = {{ request.user.pk }}; + // var socket = new SocketHandler(); + // 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); + // + // + // var url = '/work_sell/basic/'; + // $('#upload-document-team').fileupload({ + // url: url, + // crossDomain: false, + // beforeSend: function (xhr, settings) { + // $('#progress .progress-bar').css( + // 'width', + // '0%' + // ); + // if (!csrfSafeMethod(settings.type)) { + // xhr.setRequestHeader("X-CSRFToken", csrftoken); + // } + // }, + // dataType: 'json', + // done: function (e, data) {; + // $.each(data.result.files, function (index, file) { + // var currentValue = $("#documentSendIds").val(); + // currentValue += file.id + ';'; + // $("#documentSendIds").val(currentValue); + // var htmlImg = '

'+ file.name+'

'; + // var document_send = $(htmlImg).appendTo("#document-send"); + // }); + // }, + // progressall: function (e, data) { + // var progress = parseInt(data.loaded / data.total * 100, 10); + // $('#progress .progress-bar').css( + // 'width', + // progress + '%' + // ); + // } + // }).prop('disabled', !$.support.fileInput) + // .parent().addClass($.support.fileInput ? undefined : 'disabled'); + // + // + // $("#approve-stages").on('click', function(){ + // $(".stage-block-approve").each(function(){ + // var stageId = $(this).attr('data-id'); + // }); + // }); + // + // $(".team-chat-user").on('click',function(e){ + // e.stopPropagation(); + // var recipentId = $(this).attr('data-id'); + // $("#team-chat-form #recipentId").val(recipentId); + // }); + // + // $(".team-order-block").on('click', function(){ + // + // $('.team-order-block').each(function () { + // $(this).removeClass('orAct'); + // }); + // $(this).addClass('orAct'); + // + // var teamId = $(this).attr('data-team-id'); + // var orderId = $(this).attr('data-order-id'); + // $("#team-chat-form #teamId").val(teamId); + // $("#team-chat-form #orderId").val(orderId); + // + // var inbox = document.getElementById('message-chat-team-space'); + // inbox.innerHTML = ''; + // + // $.ajax({ + // url: '/api/message', + // type: 'GET', + // data: {csrfmiddlewaretoken: csrftoken, 'team': teamId,'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 + '

'; + // }); + // } + // }); + // + // }); + // + // // Вытащить сообщения для чата заказа + // $('.order-block').on('click', function () { + // $('.order-block').each(function () { + // $(this).removeClass('orAct'); + // }); + // $(this).addClass('orAct'); + // + // var orderId = $(this).attr('data-id'); + // var recipentId = $(this).attr('data-recipent-id'); + // $("#chat-contractor-order #orderId").val(orderId); + // $("#add-form-order-note #orderNote").val(orderId); + // + // $("#chat-contractor-order #recipentOrderId").val(recipentId); + // $("#add-form-order-note #recipentNote").val(recipentId); + // + // 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 + '

'; + // }); + // } + // }); + // + // $.ajax({ + // url: '/api/note/', + // type: 'GET', + // data: {csrfmiddlewaretoken: csrftoken, 'order': orderId}, + // dataType: 'json', + // success: function (json) { + // console.log(json.results); + // var noteHtmlInbox = ''; + // $.each(json.results, function (i, v) { + // noteHtmlInbox += '
  • '+ v.text +'
  • '; + // + // }); + // $(".notes-block").html(noteHtmlInbox); + // } + // }); + // + // $.ajax({ + // url: '/api/stages/', + // type: 'GET', + // data: {csrfmiddlewaretoken: csrftoken, 'order': orderId}, + // dataType: 'json', + // success: function (json) { + // console.log(json.results); + // var htmlInbox = ""; + // var stagesReservedHtml = ""; + // if (json.results.length > 0) { + // + // $.each(json.results, function (i, v) { + // if(v.is_paid){ + // stagesReservedHtml += '
  • Сумма за этап '+ i +'.Зарезервирована.
  • '; + // }else{ + // stagesReservedHtml += '
  • Сумма за этап '+ i +'.Не зарезервирована.
  • '; + // } + // htmlInbox += '
    ' + + // '

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

    ' + + // '

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

    ' + + // '

    '+ v.status+'

    ' + v.cost + '
    '; + // }); + // htmlInbox += '
    согласовать
    '; + // + // } + // $("#order-stages").html(htmlInbox); + // $(".stages-paid").html(stagesReservedHtml); + // + // } + // }); + // + // }); + // + // $('#add-note-button').on('click', function(){ + // $.ajax({ + // url: '/api/note/', + // type: 'POST', + // beforeSend: function (xhr) { + // xhr.setRequestHeader("X-CSRFToken", getCookie('csrftoken')) + // }, + // data:$("#add-form-order-note").serialize(), + // dataType: 'json', + // success: function (json) { + // console.log(json); + // $("#add-form-order-note #chat2").val(""); + // + // }, + // error: function(e){ + // console.log('error'); + // console.log(e); + // } + // }); + // }); + // + // // Вытащить сообщения для конактов + // $('.user-block').on('click', function () { + // var userId = $(this).attr('data-id'); + // $("#contact-chat-form #recipentId").val(userId); + // 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) { + // console.log(v.sender.id); + // var senderName = 'Вы'; + // var className = 'youChat'; + // if (v.sender.id == userId) { + // senderName = v.sender.username; + // className = ''; + // } + // inbox.innerHTML += '
    ' + + // '

    ' + senderName + '

    ' + v.created + '
    ' + + // '

    ' + v.text + '

    '; + // }); + // } + // }); + // + // }); + // + // //Добавить сообщение для исполнителей в группе + // $("#add-team-chat-message").on('click', function(){ + // var chatMessage = $("#team-chat-form #chatText").val(); + // var recipentId = $("#team-chat-form #recipentId").val(); + // var senderId = $("#team-chat-form #senderId").val(); + // var teamId = $("#team-chat-form #teamId").val(); + // var orderId = $("#team-chat-form #orderId").val(); + // + // var documentSendIds = $("#documentSendIds").val(); + // console.log(documentSendIds); + // var teamDocumentIds = documentSendIds.split(';'); + // teamDocumentIds.pop(); + // console.log(teamDocumentIds); + // socket.add_team_message({ + // "format_type": "add_message_team", + // "data": { + // "sender_id": senderId, + // "recipent_id": recipentId, + // "chat_message": chatMessage, + // "team_id": teamId, + // "order_id": orderId, + // } + // }); + // + // + // + // $("#team-chat-form #chatText").val(""); + // }); + // + // // Добавить сообщение для контакта + // $('#contact-chat-add-message').on('click', function () { + // 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, + // } + // }); + // + // var inbox = $('#message-chat-space').html(); + // $('#message-chat-space').html(inbox + '
    ' + + // '

    Вы

    Сейчас
    ' + + // '

    ' + chatMessage + '

    '); + // + // $("#chat").val(""); + // }); + // + // $('#order-chat-add-message').on('click', function () { + // var chatMessage = $("#chat-contractor-order #chat").val(); + // var recipentId = $("#chat-contractor-order #recipentOrderId").val(); + // var senderId = $("#chat-contractor-order #senderOrderId").val(); + // var orderId = $("#chat-contractor-order #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-contractor-order #chat").val(""); + // + // }); + // + // }); + // + // + //$(function () { + // var currentChatUser = {{ request.user.pk }}; + // var socket = new SocketHandler(); + // 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); + // + // $("#order-stages").on('click', "#addStagesForm", function(){ + // $(".new-stages-form").each(function(i,v){ + // console.log($(this).serialize()); + // alert($(this).serialize()); + // + // $.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); + // } + // }); + // + // }); + // }); + // + // $('#order-stages-tab').on('change', '#countStage', function(){ + // var countStage = parseInt($(this).val()); + // var updateFormStages = $(".update-stages-form"); + // + // alert(updateFormStages.length); + // alert(typeof updateFormStages.length); + // var limitCount = countStage + 1; + // for (var i = 2; i < limitCount; i++) { + // var stageCopy = $("#stage1").clone().attr("id", "stage" + i).addClass("stages_form"); + // $("#stage1").after(stageCopy); + // } + // }); + // + // $('.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); + // $("#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 + '

    '; + // }); + // } + // }); + // + // $.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 + '

    ' + + // '

    до 16.03.2015

    ' + v.cost + '
    '; + // + // } + // }); + // + // if (statusNotAgreed) { + // htmlInbox += '
    Перейти в режим безопасной сделки' + + // '
    ' + + // 'отправить на согласование
    '; + // } + // htmlInbox = htmlInboxStage + htmlInbox; + // $("#order-stages").html(htmlInbox); + // } + // }); + // + // + // }); + // + // // Вытащить сообщения для конактов + // $('.user-block').on('click', function () { + // var userId = $(this).attr('data-id'); + // $("#contact-chat-form #recipentId").val(userId); + // 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 () { + // 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-chat-add-message').on('click', function () { + // 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 }}'; + // + // var SocketHandler = function () { + // var url = 'ws://127.0.0.1:8888/chat/' + userId + '/'; + // var sock = new WebSocket(url); + // var intervalId; + // sock.onopen = function () { + // console.log("Start connect"); + // intervalId = setInterval(function () { + // sock.send('{"dummy": 1}'); + // }, 150); + // }; + // sock.onmessage = function (event) { + // console.log(event.data); + // var message = JSON.parse(event.data); + // var inbox; + // if (message.answer_type == 'contact') { + // inbox = document.getElementById('message-chat-space'); + // } else if (message.answer_type == 'order' || message.answer_type == 'add_order') { + // inbox = document.getElementById('message-chat-order-space') + // } + // inbox.innerHTML += '
    ' + + // '

    Иванов

    13.0.2016
    ' + + // '

    ' + message.msg + '

    '; + // + // }; + // + // this.send_order_message = function (orderId) { + // var data = { + // "format_type": "order_message", + // "order_id": orderId + // } + // sock.send(JSON.stringify(data)); + // console.log(data); + // }; + // + // this.send_contact_message = function (userId) { + // var data = { + // "format_type": "add_message", + // "user_id": userId + // } + // sock.send(JSON.stringify(data)); + // console.log(data); + // }; + // + // this.add_contact_message = function (messageData) { + // console.log(messageData); + // sock.send(JSON.stringify(messageData)); + // }; + // + // this.send_message = function (form) { + // var elements = form.elements; + // var data = {}; + // var i = 0; + // for (var i; i < elements.length; i++) { + // if (elements[i].name == 'message') { + // data[elements[i].name] = elements[i].value; + // } + // } + // sock.send(JSON.stringify(data)); + // var textareaMessage = document.getElementById("message"); + // textareaMessage.value = ""; + // + // } + // } + // diff --git a/chat/templates/chat_contractor.html b/chat/templates/chat_contractor.html index 6f1aef3..a452670 100644 --- a/chat/templates/chat_contractor.html +++ b/chat/templates/chat_contractor.html @@ -211,15 +211,20 @@ +

    Прикрепить файл

    -
    +
    -
    +
    + +
    + +
    отправить
    @@ -332,8 +337,6 @@ }, 1000); - - var url = '/work_sell/basic/'; $('#upload-document-team').fileupload({ url: url, @@ -350,19 +353,15 @@ dataType: 'json', done: function (e, data) {; $.each(data.result.files, function (index, file) { - alert(file.url); -{# var htmlImg = '
    ' +#} -{# '

    Название

    ' +#} -{# '
    ';#} -{##} -{# var img = $(htmlImg).appendTo("#diplom-gallery");#} - + var currentValue = $("#documentSendIds").val(); + currentValue += file.id + ';'; + $("#documentSendIds").val(currentValue); + var htmlImg = '

    '+ file.name+'

    '; + var document_send = $(htmlImg).appendTo("#document-send"); }); }, progressall: function (e, data) { - var progress = parseInt(data.loaded / data.total * 100, 10); - alert(progress); $('#progress .progress-bar').css( 'width', progress + '%' @@ -573,6 +572,11 @@ var teamId = $("#team-chat-form #teamId").val(); var orderId = $("#team-chat-form #orderId").val(); + var documentSendIds = $("#documentSendIds").val(); + console.log(documentSendIds); + var teamDocumentIds = documentSendIds.split(';'); + teamDocumentIds.pop(); + console.log(teamDocumentIds); socket.add_team_message({ "format_type": "add_message_team", "data": { @@ -584,6 +588,8 @@ } }); + + $("#team-chat-form #chatText").val(""); }); diff --git a/chat/templates/chat_customer.html b/chat/templates/chat_customer.html index babae49..296a404 100644 --- a/chat/templates/chat_customer.html +++ b/chat/templates/chat_customer.html @@ -237,7 +237,13 @@ var socket = new SocketHandler(); 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); $("#order-stages").on('click', "#addStagesForm", function(){ $(".new-stages-form").each(function(i,v){ @@ -277,7 +283,6 @@ } }); - $('.order-block').on('click', function () { $("#chat-order-add").css("display", "block"); $("#formsetStage").css("display","block"); @@ -379,7 +384,6 @@ }); - // Вытащить сообщения для конактов $('.user-block').on('click', function () { var userId = $(this).attr('data-id'); diff --git a/chat/templates/index.html b/chat/templates/index.html deleted file mode 100644 index e5a460a..0000000 --- a/chat/templates/index.html +++ /dev/null @@ -1,42 +0,0 @@ - - - - - Title - - -

    Всем привет , дети мои!!

    -
    -
    - -
    - - -
    - - - - diff --git a/chat/templates/index2.html b/chat/templates/index2.html deleted file mode 100644 index 395bf1a..0000000 --- a/chat/templates/index2.html +++ /dev/null @@ -1,61 +0,0 @@ - - - - - Title - - -

    Chat

    -
    -{% for message in messages %} -

    {{ message["body"] }}

    -

    {{ message["time"] }}

    - {% end%} -
    -
    - - -
    - - - diff --git a/chat/templates/test1.html b/chat/templates/test1.html deleted file mode 100644 index 97e9bd9..0000000 --- a/chat/templates/test1.html +++ /dev/null @@ -1,33 +0,0 @@ -{% extends 'partials/base.html' %} -{% block content %} -

    Test page

    -{% endblock %} -{% block js_block %} - - -{% endblock %} diff --git a/chat/urls.py b/chat/urls.py index 3bd4c93..aa77baa 100644 --- a/chat/urls.py +++ b/chat/urls.py @@ -2,12 +2,10 @@ from django.conf import urls from .views import ( ChatUserView, - test, ) app_name = 'chat' urlpatterns = [ urls.url(r'^$', ChatUserView.as_view(), name='chat-user'), - urls.url(r'^test/$', test), ] diff --git a/chat/views.py b/chat/views.py index 7811b0b..6c1d6d5 100644 --- a/chat/views.py +++ b/chat/views.py @@ -57,5 +57,5 @@ class ChatUserView(View): }) -def test(request): - return render(request, 'test1.html') + + diff --git a/common/models.py b/common/models.py index a1c6e8b..95ca414 100644 --- a/common/models.py +++ b/common/models.py @@ -79,3 +79,4 @@ class PrintDocuments(models.Model): class Meta: verbose_name = 'Документы на распечатку' verbose_name_plural = 'Документы на распечатку' + diff --git a/projects/migrations/0013_auto_20160803_2003.py b/projects/migrations/0013_auto_20160803_2003.py new file mode 100644 index 0000000..7e0656f --- /dev/null +++ b/projects/migrations/0013_auto_20160803_2003.py @@ -0,0 +1,20 @@ +# -*- coding: utf-8 -*- +# Generated by Django 1.9.7 on 2016-08-03 17:03 +from __future__ import unicode_literals + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('projects', '0012_merge'), + ] + + operations = [ + migrations.AlterField( + model_name='answer', + name='portfolios', + field=models.ManyToManyField(blank=True, related_name='portfolios_answers', to='projects.Portfolio'), + ), + ] diff --git a/projects/views.py b/projects/views.py index f063389..2865076 100644 --- a/projects/views.py +++ b/projects/views.py @@ -1,22 +1,25 @@ +import json +import pydash as _; _.map = _.map_; _.filter = _.filter_ +import re + from django.conf import settings from django.contrib import messages from django.contrib.auth.mixins import PermissionRequiredMixin, LoginRequiredMixin from django.core.paginator import Paginator, EmptyPage, PageNotAnInteger from django.core.urlresolvers import reverse, reverse_lazy +from django.core.files.base import ContentFile from django.db.models import Q from django.http import HttpResponseForbidden, HttpResponseRedirect, HttpResponse, Http404 from django.shortcuts import render, get_object_or_404, redirect from django.views.generic import ListView, DetailView, CreateView, View, UpdateView, TemplateView, FormView from django.views.generic.base import ContextMixin from pprint import pprint, pformat -import json -import pydash as _; _.map = _.map_; _.filter = _.filter_ -import re from .mixins import LastAccessMixin -from .models import Project, ProjectFile, Portfolio, Candidate, Answer, Realty, Order +from .models import Project, ProjectFile, Portfolio, Candidate, Answer, Realty, Order, PortfolioPhoto from archilance.mixins import BaseMixin from users.models import User +from work_sell.models import Picture from .forms import ( ContractorProjectAnswerForm, @@ -361,6 +364,10 @@ class ContractorProjectAnswerView(BaseMixin, View): +class PortfolioTrashView(View): + pass + + class CustomerProjectTrashView(View): form_class = CustomerProjectTrashForm @@ -461,9 +468,19 @@ class OfferOrderView(View): def contractor_portfolio_create(request): if request.is_ajax(): form = PortfolioForm(data=request.POST) + # import code; code.interact(local=dict(globals(), **locals())) if form.is_valid(): instance = form.save(commit=False) instance.save() + images_ids = request.POST.get('images-ids').split(';')[:-1] + for pk in images_ids: + picture = Picture.objects.get(pk=pk) + temp_file = ContentFile(picture.file.read()) + temp_file.name = picture.file.name + p_photo = PortfolioPhoto() + p_photo.img = temp_file + p_photo.portfolio = instance + p_photo.save() data = {'status': 'ok'} else: data = {'status': 'no', 'form_errors': form.errors} diff --git a/ratings/__init__.py b/ratings/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/ratings/admin.py b/ratings/admin.py new file mode 100644 index 0000000..e532b50 --- /dev/null +++ b/ratings/admin.py @@ -0,0 +1,5 @@ +from django.contrib import admin +from .models import SpecializationRating, HistoryRating + +admin.site.register(SpecializationRating) +admin.site.register(HistoryRating) diff --git a/ratings/apps.py b/ratings/apps.py new file mode 100644 index 0000000..09b14f2 --- /dev/null +++ b/ratings/apps.py @@ -0,0 +1,5 @@ +from django.apps import AppConfig + + +class RatingsConfig(AppConfig): + name = 'ratings' diff --git a/ratings/migrations/0001_initial.py b/ratings/migrations/0001_initial.py new file mode 100644 index 0000000..5a95587 --- /dev/null +++ b/ratings/migrations/0001_initial.py @@ -0,0 +1,51 @@ +# -*- coding: utf-8 -*- +# Generated by Django 1.9.7 on 2016-08-04 15:52 +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): + + initial = True + + dependencies = [ + ('specializations', '0001_initial'), + migrations.swappable_dependency(settings.AUTH_USER_MODEL), + ('users', '0004_user_contractor_rating'), + ] + + operations = [ + migrations.CreateModel( + name='HistoryRating', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('rating', models.IntegerField(default=0)), + ('created', models.DateTimeField(default=django.utils.timezone.now)), + ('description', models.TextField(blank=True)), + ('team', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='history_ratings', to='users.Team')), + ('user', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='history_ratings', to=settings.AUTH_USER_MODEL)), + ], + options={ + 'verbose_name': 'История рейтинга', + 'verbose_name_plural': 'Истории рейтинга', + }, + ), + migrations.CreateModel( + name='SpecializationRating', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('position', models.PositiveIntegerField(default=0)), + ('specialization', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='specialization_rating', to='specializations.Specialization')), + ('team', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='specialization_rating', to='users.Team')), + ('user', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='specialization_rating', to=settings.AUTH_USER_MODEL)), + ], + options={ + 'verbose_name': 'Рейтинг специализаций', + 'verbose_name_plural': 'Рейтинги специализаций', + }, + ), + ] diff --git a/ratings/migrations/__init__.py b/ratings/migrations/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/ratings/models.py b/ratings/models.py new file mode 100644 index 0000000..4db1001 --- /dev/null +++ b/ratings/models.py @@ -0,0 +1,36 @@ +from django.db import models +from django.utils import timezone +from users.models import User, Team +from specializations.models import Specialization + +class HistoryRating(models.Model): + user = models.ForeignKey(User, related_name='history_ratings', null=True, blank=True) + team = models.ForeignKey(Team, related_name='history_ratings', null=True, blank=True) + rating = models.IntegerField(default=0) + created = models.DateTimeField(default=timezone.now) + description = models.TextField(blank=True) + + def __str__(self): + return self.rating + + class Meta: + verbose_name = 'История рейтинга' + verbose_name_plural = 'Истории рейтинга' + + +class SpecializationRating(models.Model): + user = models.ForeignKey(User, related_name='specialization_rating', null=True, blank=True) + team = models.ForeignKey(Team, related_name='specialization_rating', null=True, blank=True) + specialization = models.ForeignKey(Specialization, related_name='specialization_rating') + position = models.PositiveIntegerField(default=0) + + def __str__(self): + return self.position + + class Meta: + verbose_name = 'Рейтинг специализаций' + verbose_name_plural = 'Рейтинги специализаций' + + + + diff --git a/ratings/tests.py b/ratings/tests.py new file mode 100644 index 0000000..7ce503c --- /dev/null +++ b/ratings/tests.py @@ -0,0 +1,3 @@ +from django.test import TestCase + +# Create your tests here. diff --git a/ratings/views.py b/ratings/views.py new file mode 100644 index 0000000..91ea44a --- /dev/null +++ b/ratings/views.py @@ -0,0 +1,3 @@ +from django.shortcuts import render + +# Create your views here. diff --git a/templates/partials/base.html b/templates/partials/base.html index bfce740..d2f8708 100644 --- a/templates/partials/base.html +++ b/templates/partials/base.html @@ -72,8 +72,8 @@ {% endblock %} diff --git a/users/migrations/0004_user_contractor_rating.py b/users/migrations/0004_user_contractor_rating.py new file mode 100644 index 0000000..a08892a --- /dev/null +++ b/users/migrations/0004_user_contractor_rating.py @@ -0,0 +1,20 @@ +# -*- coding: utf-8 -*- +# Generated by Django 1.9.7 on 2016-08-04 15:52 +from __future__ import unicode_literals + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('users', '0003_auto_20160726_1931'), + ] + + operations = [ + migrations.AddField( + model_name='user', + name='contractor_rating', + field=models.FloatField(default=0.0), + ), + ] diff --git a/users/models.py b/users/models.py index 8b91650..fe91936 100644 --- a/users/models.py +++ b/users/models.py @@ -25,8 +25,9 @@ class UserManager(BaseUserManager): user.save(using=self._db) return user - def create_superuser(self, username, password): - user = self.create_user(username, 'admin@exampletest.com', password) + def create_superuser(self, email, password): + username = email + user = self.create_user(username, email, password) user.is_superuser = True user.save(using=self._db) return user @@ -122,6 +123,7 @@ class User(AbstractBaseUser, PermissionsMixin): contractor_resume = models.OneToOneField(ContractorResume, related_name='contractor', blank=True, null=True) contractor_specializations = TreeManyToManyField(Specialization, related_name='contractors', blank=True) contractor_status = models.CharField(default='free', max_length=20, choices=STATUSES) + contractor_rating = models.FloatField(default=0.0) created = models.DateTimeField(default=timezone.now) cro = models.BooleanField(default=False) date_joined = models.DateTimeField(default=timezone.now) @@ -197,3 +199,6 @@ class Team(models.Model): class Meta: verbose_name = 'Команда' verbose_name_plural = 'Команды' + + + diff --git a/users/templates/contractor_profile.html b/users/templates/contractor_profile.html index 739f94e..3788420 100644 --- a/users/templates/contractor_profile.html +++ b/users/templates/contractor_profile.html @@ -465,13 +465,19 @@ dataType: 'json', success: function (data) { if (data.status == 'ok') { + $('#portfolio-add-form').each(function(){ + this.reset(); + }); location.reload(); + }else if(data.status == 'no'){ + $.each(data.form_errors, function(k,v){ + $('.error-'+ k).html(v).show(); + }); } }, error: function (jqXHR, exception) { console.log(jqXHR.statusCode); } - }); }); var url = '/work_sell/basic/'; @@ -481,7 +487,7 @@ url: url, crossDomain: false, beforeSend: function (xhr, settings) { - $('#progress .progress-bar').css( + $('#progress-portfolio .progress-bar').css( 'width', '0%' ); @@ -504,7 +510,42 @@ progressall: function (e, data) { var progress = parseInt(data.loaded / data.total * 100, 10); console.log(progress); - $('#progress .progress-bar').css( + $('#progress-portfolio .progress-bar').css( + 'width', + progress + '%' + ); + } + }).prop('disabled', !$.support.fileInput) + .parent().addClass($.support.fileInput ? undefined : 'disabled'); + + $('#fileupload-worksell').fileupload({ + url: url, + crossDomain: false, + beforeSend: function (xhr, settings) { + $('#progress-worksell .progress-bar').css( + 'width', + '0%' + ); + if (!csrfSafeMethod(settings.type)) { + xhr.setRequestHeader("X-CSRFToken", csrftoken); + } + }, + dataType: 'json', + done: function (e, data) { + console.log(data); + $.each(data.result.files, function (index, file) { + var img = $('').attr('src', file.url).appendTo("#files-worksell"); + console.log(file); + var currentValue = $("#upload-files-worksell-pk").val(); + currentValue += file.id + ';'; + $("#upload-files-worksell-pk").val(currentValue); + + }); + }, + progressall: function (e, data) { + var progress = parseInt(data.loaded / data.total * 100, 10); + console.log(progress); + $('#progress-worksell .progress-bar').css( 'width', progress + '%' ); diff --git a/users/templates/portfolio_create_form.html b/users/templates/portfolio_create_form.html index ab0a03f..702c37c 100644 --- a/users/templates/portfolio_create_form.html +++ b/users/templates/portfolio_create_form.html @@ -3,13 +3,13 @@
    {% csrf_token %}
    -

    Название{{ portfolio_form.name.errors.as_text }}

    +

    Название{{ portfolio_form.name.errors.as_text }}

    -

    Описание{{ portfolio_form.description.errors.as_text }}

    +

    Описание{{ portfolio_form.description.errors.as_text }}

    @@ -77,24 +77,21 @@
    - +
    -{# #} -{# #} -{# Выберите файлы#} -{# #} -{# #} -{# #} + + + Выберите файлы - +

    -
    +
    diff --git a/users/templates/worksell_create_form.html b/users/templates/worksell_create_form.html index fcb8cbb..ac4258d 100644 --- a/users/templates/worksell_create_form.html +++ b/users/templates/worksell_create_form.html @@ -75,26 +75,25 @@
    -{#
    #} -{# #} -{#
    #} - +
    + +
    Выберите файлы - +

    -
    +
    -
    +