#ARC-10 Add models and relations

remotes/origin/setup
Mukhtar 10 years ago
parent 6b1bdeb30b
commit 25f617bb96
  1. 6
      api/test.py
  2. 2
      api/urls.py
  3. 13
      api/views.py
  4. 34
      archilance/settings/base.py
  5. 21
      archilance/views.py
  6. 7
      chat/admin.py
  7. 13
      chat/filters.py
  8. 35
      chat/migrations/0003_documents.py
  9. 16
      chat/serializers.py
  10. 683
      chat/templates/chat.js
  11. 32
      chat/templates/chat_contractor.html
  12. 8
      chat/templates/chat_customer.html
  13. 42
      chat/templates/index.html
  14. 61
      chat/templates/index2.html
  15. 33
      chat/templates/test1.html
  16. 2
      chat/urls.py
  17. 4
      chat/views.py
  18. 1
      common/models.py
  19. 20
      projects/migrations/0013_auto_20160803_2003.py
  20. 25
      projects/views.py
  21. 0
      ratings/__init__.py
  22. 5
      ratings/admin.py
  23. 5
      ratings/apps.py
  24. 51
      ratings/migrations/0001_initial.py
  25. 0
      ratings/migrations/__init__.py
  26. 36
      ratings/models.py
  27. 3
      ratings/tests.py
  28. 3
      ratings/views.py
  29. 11
      templates/partials/base.html
  30. 20
      users/migrations/0004_user_contractor_rating.py
  31. 9
      users/models.py
  32. 47
      users/templates/contractor_profile.html
  33. 19
      users/templates/portfolio_create_form.html
  34. 13
      users/templates/worksell_create_form.html

@ -0,0 +1,6 @@
from rest_framework.test import APITestCase
class FileUploadTests(APITestCase):
pass

@ -9,6 +9,7 @@ from .views import (
MessageViewSet, MessageViewSet,
StageViewSet, StageViewSet,
NoteViewSet, NoteViewSet,
DocumentViewSet,
) )
@ -17,6 +18,7 @@ router = routers.DefaultRouter()
router.register(r'locations', LocationViewSet) router.register(r'locations', LocationViewSet)
router.register(r'projects', ProjectViewSet) router.register(r'projects', ProjectViewSet)
router.register(r'stages', StageViewSet) router.register(r'stages', StageViewSet)
router.register(r'documents', DocumentViewSet)
router.register(r'realties', RealtyViewSet) router.register(r'realties', RealtyViewSet)
router.register(r'specializations', SpecializationViewSet) router.register(r'specializations', SpecializationViewSet)
router.register(r'users', UserViewSet) router.register(r'users', UserViewSet)

@ -18,9 +18,9 @@ from common.models import Location
from common.serializers import LocationSerializer from common.serializers import LocationSerializer
from common.filters import LocationFilterSet from common.filters import LocationFilterSet
from chat.models import Message, Notes from chat.models import Message, Notes, Documents
from chat.serializers import MessageSerializer, NoteSerializer from chat.serializers import MessageSerializer, NoteSerializer, DocumentsSerializer
from chat.filters import MessageFilterSet, NoteFilterSet from chat.filters import MessageFilterSet, NoteFilterSet, DocumentsFilterSet
class StageViewSet(ModelViewSet): class StageViewSet(ModelViewSet):
@ -30,6 +30,13 @@ class StageViewSet(ModelViewSet):
permission_classes = (permissions.IsAuthenticatedOrReadOnly,) permission_classes = (permissions.IsAuthenticatedOrReadOnly,)
class DocumentViewSet(ModelViewSet):
queryset = Documents.objects.all()
serializer_class = DocumentsSerializer
# filter_class = DocumentsFilterSet
# permission_classes = (permissions.IsAuthenticatedOrReadOnly,)
class ProjectViewSet(ModelViewSet): class ProjectViewSet(ModelViewSet):
queryset = Project.objects.all() queryset = Project.objects.all()
serializer_class = ProjectSerializer serializer_class = ProjectSerializer

@ -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! # SECURITY WARNING: don't run with debug turned on in production!
DEBUG = True 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 = [] ALLOWED_HOSTS = []
# Application definition # Application definition
DJANGO_APPS = [ DJANGO_APPS = [
@ -39,20 +38,21 @@ THIRD_PARTY_APPS = [
'sorl.thumbnail', 'sorl.thumbnail',
'compressor', 'compressor',
'password_reset', '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 = [ LOCAL_APPS = [
'specializations', 'specializations',
'api', 'api',
'common', 'common',
'work_sell', 'work_sell',
'archilance', 'archilance',
'projects', 'projects',
'users', 'users',
'reviews', 'reviews',
'chat', 'chat',
'wallets', 'wallets',
'ratings',
] ]
INSTALLED_APPS = DJANGO_APPS + THIRD_PARTY_APPS + LOCAL_APPS INSTALLED_APPS = DJANGO_APPS + THIRD_PARTY_APPS + LOCAL_APPS
@ -85,7 +85,6 @@ TEMPLATES = [
'django.contrib.messages.context_processors.messages', 'django.contrib.messages.context_processors.messages',
], ],
# Load these templatetags by default: # Load these templatetags by default:
'builtins': [ 'builtins': [
@ -99,7 +98,6 @@ TEMPLATES = [
WSGI_APPLICATION = 'archilance.wsgi.application' WSGI_APPLICATION = 'archilance.wsgi.application'
# Database # Database
# https://docs.djangoproject.com/en/1.9/ref/settings/#databases # https://docs.djangoproject.com/en/1.9/ref/settings/#databases
@ -121,7 +119,6 @@ DATABASES = {
} }
} }
# Password validation # Password validation
# https://docs.djangoproject.com/en/1.9/ref/settings/#auth-password-validators # https://docs.djangoproject.com/en/1.9/ref/settings/#auth-password-validators
@ -209,7 +206,6 @@ USE_L10N = True
USE_TZ = True USE_TZ = True
# Static files (CSS, JavaScript, Images) # Static files (CSS, JavaScript, Images)
# https://docs.djangoproject.com/en/1.9/howto/static-files/ # 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' EMAIL_BACKEND = 'django.core.mail.backends.smtp.EmailBackend'
SHELL_PLUS_POST_IMPORTS = ( # Extra auto imports SHELL_PLUS_POST_IMPORTS = ( # Extra auto imports
'natsort', 'natsort',
('archilance', 'util'), ('archilance', 'util'),
('pprint', ('pprint', 'pformat')), ('pprint', ('pprint', 'pformat')),
) )
PAGE_SIZE = 10 # Pagination PAGE_SIZE = 10 # Pagination

@ -1,11 +1,13 @@
from django.views.generic import TemplateView, View from django.views.generic import TemplateView, View
from django.shortcuts import render from django.shortcuts import render
from django.template.loader import render_to_string 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 projects.models import Order
from common.models import MainPage, PrintDocuments from common.models import MainPage, PrintDocuments
from users.models import ContractorResumeFiles from users.models import ContractorResumeFiles
from chat.models import Documents
from work_sell.models import Picture
class HomeTemplateView(View): class HomeTemplateView(View):
template_name = 'home.html' template_name = 'home.html'
@ -19,5 +21,16 @@ class TestChatTemplateView(View):
template_name = 'chat_test.html' template_name = 'chat_test.html'
def get(self, request, *args, **kwargs): def get(self, request, *args, **kwargs):
diploms = ContractorResumeFiles.objects.all() test = [54,55,56]
return render(request, 'chat_test.html', {'diploms': diploms}) 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()

@ -1,5 +1,5 @@
from django.contrib import admin from django.contrib import admin
from .models import Message, Notes from .models import Message, Notes, Documents
class MessageAdmin(admin.ModelAdmin): class MessageAdmin(admin.ModelAdmin):
@ -10,5 +10,10 @@ class NotesAdmin(admin.ModelAdmin):
list_display = ('text', 'sender', 'recipent', 'order',) 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(Message, MessageAdmin)
admin.site.register(Notes, NotesAdmin) admin.site.register(Notes, NotesAdmin)
admin.site.register(Documents, DocumentsAdmin)

@ -1,6 +1,17 @@
from rest_framework_filters import FilterSet, RelatedFilter, AllLookupsFilter 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): class MessageFilterSet(FilterSet):

@ -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': 'Входящие Документы',
},
),
]

@ -1,8 +1,22 @@
from rest_framework.serializers import ModelSerializer from rest_framework.serializers import ModelSerializer
from .models import Message, Notes from .models import Message, Notes, Documents
from users.serializers import UserSerializer from users.serializers import UserSerializer
class DocumentsSerializer(ModelSerializer):
class Meta:
model = Documents
fields = (
'file',
'sender',
'recipent',
'team',
'order',
)
class MessageSerializer(ModelSerializer): class MessageSerializer(ModelSerializer):
sender = UserSerializer() sender = UserSerializer()
recipent = UserSerializer() recipent = UserSerializer()

@ -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 += '<div class="col-lg-12 insetCommChat"><div class="topCommChat">' +
// '<p class="nameCommChat">ВЫ</p> <span>13.0.2016</span></div>' +
// '<p class="textCommChat">' + message.msg + '</p></div>';
// };
//
// 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 = '<p>'+ file.name+'</p>';
// 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 += '<div class="col-lg-12 insetCommChat"><div class="topCommChat">' +
// '<p class="nameCommChat">' + senderName + '</p> <span>' + v.created + '</span></div>' +
// '<p class="textCommChat">' + v.text + '</p></div>';
// });
// }
// });
//
// });
//
// // Вытащить сообщения для чата заказа
// $('.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 += '<div class="col-lg-12 insetCommChat"><div class="topCommChat">' +
// '<p class="nameCommChat">' + senderName + '</p> <span>' + v.created + '</span></div>' +
// '<p class="textCommChat">' + v.text + '</p></div>';
// });
// }
// });
//
// $.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 += '<li>'+ v.text +'<li>';
//
// });
// $(".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 += '<li class="reserved">Сумма за этап '+ i +'.Зарезервирована.</li>';
// }else{
// stagesReservedHtml += '<li class="unreserved">Сумма за этап '+ i +'.Не зарезервирована.</li>';
// }
// htmlInbox += '<div data-id="' + v.id + '" class="numberStepp box-sizing stage-block-approve"><div class="insetNumStepp">' +
// '<p class="titleNumStepp"><span>Этап ' + v.pos + '</span>' + v.name + '</p>' +
// '<p class="textNumStepp">Результаты этапа:' + v.result + '</p><div>' +
// '<p>'+ v.status+'</p><span>' + v.cost + '<i class="fa fa-rub"></i></span></div></div></div>';
// });
// htmlInbox += '<div class="textAreaBlock2 FFD box-sizing disTab"><a id="approve-stages" href="javascript:void()">согласовать</a></div>';
//
// }
// $("#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 += '<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>';
// });
// }
// });
//
// });
//
// //Добавить сообщение для исполнителей в группе
// $("#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 + '<div class="col-lg-12 insetCommChat"><div class="topCommChat">' +
// '<p class="nameCommChat">Вы</p> <span>Сейчас</span></div>' +
// '<p class="textCommChat">' + chatMessage + '</p></div>');
//
// $("#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 += '<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>';
// });
// }
// });
//
// $.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 = '<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" name="order" type="text" value="'+ orderId +'" class="orderStagesInput"/> />' +
// '<label for="">Срок</label><input class="form-control" name="term" type="text" />' +
// '<label for="">Результат</label><input class="form-control" name="result" type="text" />' +
// '</form></div>';
// }
// var statusNotAgreed = true;
// $.each(json.results, function (i, v) {
// if (v.status == "not_agreed") {
// htmlInbox += '<div class="numberStepp box-sizing">' +
// '<p>Этап</p><form class="update-stages-form" id="stage-form-'+ v.pos +'">' +
// '<label for="">Название</label><input class="form-control" type="text" value="'+ v.name +'" />' +
// '<label for="">Цена</label><input class="form-control" type="text" value="'+ v.cost +'" />' +
// '<input class="form-control" type="hidden" value="'+ v.order +'" />' +
// '<label for="">Срок</label><input class="form-control" type="text" value="'+ v.term +'" />' +
// '<label for="">Результат</label><input class="form-control" type="text" value="'+ v.result +'" />' +
// '</form></div>';
// } else {
// statusNotAgreed = false;
// htmlInboxStage = "";
// 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>до 16.03.2015</p><span>' + v.cost + '<i class="fa fa-rub"></i></span></div></div></div>';
//
// }
// });
//
// if (statusNotAgreed) {
// htmlInbox += '<div class="box-sizing disTab" style="text-align:center;"><div class="checkbox"><input type="checkbox" style="opacity:1">Перейти в режим безопасной сделки' +
// '</div></div><div class="textAreaBlock2 box-sizing disTab">' +
// '<a href="javascript:void()" id="addStagesForm">отправить на согласование</a> </div>';
// }
// 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 += '<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>';
// });
// }
// });
//
// });
//
// $('#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 += '<div class="col-lg-12 insetCommChat"><div class="topCommChat">' +
// '<p class="nameCommChat">Иванов</p> <span>13.0.2016</span></div>' +
// '<p class="textCommChat">' + message.msg + '</p></div>';
//
// };
//
// 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 = "";
//
// }
// }
//

@ -211,15 +211,20 @@
<input type="text" name="recipent" id="recipentId" value="" /> <input type="text" name="recipent" id="recipentId" value="" />
<input type="text" name="order" id="orderId" value="" /> <input type="text" name="order" id="orderId" value="" />
<input type="text" name="team" id="teamId" value="" /> <input type="text" name="team" id="teamId" value="" />
<input type="text" name="document-send" id="documentSendIds" />
<textarea id="chatText" class="chat-textarea box-sizing"></textarea> <textarea id="chatText" class="chat-textarea box-sizing"></textarea>
<div class="bunChat"> <div class="bunChat">
<div class="setChat box-sizing upload"> <div class="setChat box-sizing upload">
<input type="file" name="file" id="upload-document-team"/> <input type="file" name="file" id="upload-document-team"/>
<p>Прикрепить файл</p> <p>Прикрепить файл</p>
</div> </div>
<div id="progress" class="progress"> <div id="progress" class="progress">
<div class="progress-bar progress-bar-success"></div> <div class="progress-bar progress-bar-success"></div>
</div> </div>
<div id="document-send">
</div>
<a href="javascript:void(0)" id="add-team-chat-message">отправить</a> <a href="javascript:void(0)" id="add-team-chat-message">отправить</a>
</div> </div>
</form> </form>
@ -332,8 +337,6 @@
}, 1000); }, 1000);
var url = '/work_sell/basic/'; var url = '/work_sell/basic/';
$('#upload-document-team').fileupload({ $('#upload-document-team').fileupload({
url: url, url: url,
@ -350,19 +353,15 @@
dataType: 'json', dataType: 'json',
done: function (e, data) {; done: function (e, data) {;
$.each(data.result.files, function (index, file) { $.each(data.result.files, function (index, file) {
alert(file.url); var currentValue = $("#documentSendIds").val();
{# var htmlImg = '<div class="col-lg-4"><div class="insetCol box-sizing disTab"><div class="imgGal" style="background: url(+ file.url +) no-repeat center;"><div class="imgFigure"></div></div></div> ' +#} currentValue += file.id + ';';
{# '<div class="insetCol2 box-sizing disTab"><p>Название</p><div class="buttonsImg" distab="">' +#} $("#documentSendIds").val(currentValue);
{# '<div class="insetBI insetBI2"><i class="fa fa-times"></i></div></div></div></div>';#} var htmlImg = '<p>'+ file.name+'</p>';
{##} var document_send = $(htmlImg).appendTo("#document-send");
{# var img = $(htmlImg).appendTo("#diplom-gallery");#}
}); });
}, },
progressall: function (e, data) { progressall: function (e, data) {
var progress = parseInt(data.loaded / data.total * 100, 10); var progress = parseInt(data.loaded / data.total * 100, 10);
alert(progress);
$('#progress .progress-bar').css( $('#progress .progress-bar').css(
'width', 'width',
progress + '%' progress + '%'
@ -573,6 +572,11 @@
var teamId = $("#team-chat-form #teamId").val(); var teamId = $("#team-chat-form #teamId").val();
var orderId = $("#team-chat-form #orderId").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({ socket.add_team_message({
"format_type": "add_message_team", "format_type": "add_message_team",
"data": { "data": {
@ -584,6 +588,8 @@
} }
}); });
$("#team-chat-form #chatText").val(""); $("#team-chat-form #chatText").val("");
}); });

@ -237,7 +237,13 @@
var socket = new SocketHandler(); var socket = new SocketHandler();
var form = document.getElementById('message_form'); var form = document.getElementById('message_form');
var csrftoken = getCookie('csrftoken'); 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(){ $("#order-stages").on('click', "#addStagesForm", function(){
$(".new-stages-form").each(function(i,v){ $(".new-stages-form").each(function(i,v){
@ -277,7 +283,6 @@
} }
}); });
$('.order-block').on('click', function () { $('.order-block').on('click', function () {
$("#chat-order-add").css("display", "block"); $("#chat-order-add").css("display", "block");
$("#formsetStage").css("display","block"); $("#formsetStage").css("display","block");
@ -379,7 +384,6 @@
}); });
// Вытащить сообщения для конактов // Вытащить сообщения для конактов
$('.user-block').on('click', function () { $('.user-block').on('click', function () {
var userId = $(this).attr('data-id'); var userId = $(this).attr('data-id');

@ -1,42 +0,0 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<h1>Всем привет , дети мои!!</h1>
<div id="output">
</div>
<form id="chatform">
<input id="text" type="text" />
<input type="submit" />
</form>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.2.2/jquery.min.js"></script>
<script type="text/javascript">
$(document).ready(function(){
var url = 'ws://127.0.0.1:8888/chat';
var socket = new WebSocket(url);
socket.onopen = function(){
console.log("Соединение установлено");
socket.send("start");
}
socket.onmessage = function (event) {
console.log(event.data);
var data = JSON.parse(event.data);
output = output + '<h3>'+ data.msg +'</h3>';
$("#output").html(output);
}
$('form').submit(function(e){
e.preventDefault();
var currentText = $("#text").val();
socket.send(currentText);
});
});
</script>
</body>
</html>

@ -1,61 +0,0 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<h1>Chat</h1>
<div id="inbox">
{% for message in messages %}
<h1>{{ message["body"] }}</h1>
<h3>{{ message["time"] }} </h3>
{% end%}
</div>
<form method="post" id="messageform">
<textarea id="message" name="message"></textarea>
<input type="submit" />
</form>
<script type="text/javascript">
window.onload = function(){
var socket = new SocketHandler();
var form = document.getElementById('messageform');
form.onsubmit = function(e){
e.preventDefault();
console.log('submit click');
socket.send_message(form);
}
};
var SocketHandler = function(){
var url = 'ws://' + location.host + '/chatsocket/main/';
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);
message = JSON.parse(event.data);
var inbox = document.getElementById('inbox');
inbox.innerHTML += '<h2>' + message.message + '</h2>';
};
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));
}
}
</script>
</body>
</html>

@ -1,33 +0,0 @@
{% extends 'partials/base.html' %}
{% block content %}
<h1>Test page </h1>
{% endblock %}
{% block js_block %}
<script type="text/javascript">
$(function () {
$.ajax({
url: '/api/stages/4/',
type: 'PUT',
beforeSend: function (xhr) {
xhr.setRequestHeader("X-CSRFToken", getCookie('csrftoken'))
},
data: {
name: 'Test name.HA HA HA nnnnnn ',
cost: 100,
result: 'Результат',
order: 1,
},
dataType: 'json',
success: function (json) {
console.log(json);
},
error: function(e){
console.log(e);
}
});
});
</script>
{% endblock %}

@ -2,12 +2,10 @@ from django.conf import urls
from .views import ( from .views import (
ChatUserView, ChatUserView,
test,
) )
app_name = 'chat' app_name = 'chat'
urlpatterns = [ urlpatterns = [
urls.url(r'^$', ChatUserView.as_view(), name='chat-user'), urls.url(r'^$', ChatUserView.as_view(), name='chat-user'),
urls.url(r'^test/$', test),
] ]

@ -57,5 +57,5 @@ class ChatUserView(View):
}) })
def test(request):
return render(request, 'test1.html')

@ -79,3 +79,4 @@ class PrintDocuments(models.Model):
class Meta: class Meta:
verbose_name = 'Документы на распечатку' verbose_name = 'Документы на распечатку'
verbose_name_plural = 'Документы на распечатку' verbose_name_plural = 'Документы на распечатку'

@ -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'),
),
]

@ -1,22 +1,25 @@
import json
import pydash as _; _.map = _.map_; _.filter = _.filter_
import re
from django.conf import settings from django.conf import settings
from django.contrib import messages from django.contrib import messages
from django.contrib.auth.mixins import PermissionRequiredMixin, LoginRequiredMixin from django.contrib.auth.mixins import PermissionRequiredMixin, LoginRequiredMixin
from django.core.paginator import Paginator, EmptyPage, PageNotAnInteger from django.core.paginator import Paginator, EmptyPage, PageNotAnInteger
from django.core.urlresolvers import reverse, reverse_lazy from django.core.urlresolvers import reverse, reverse_lazy
from django.core.files.base import ContentFile
from django.db.models import Q from django.db.models import Q
from django.http import HttpResponseForbidden, HttpResponseRedirect, HttpResponse, Http404 from django.http import HttpResponseForbidden, HttpResponseRedirect, HttpResponse, Http404
from django.shortcuts import render, get_object_or_404, redirect 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 import ListView, DetailView, CreateView, View, UpdateView, TemplateView, FormView
from django.views.generic.base import ContextMixin from django.views.generic.base import ContextMixin
from pprint import pprint, pformat from pprint import pprint, pformat
import json
import pydash as _; _.map = _.map_; _.filter = _.filter_
import re
from .mixins import LastAccessMixin 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 archilance.mixins import BaseMixin
from users.models import User from users.models import User
from work_sell.models import Picture
from .forms import ( from .forms import (
ContractorProjectAnswerForm, ContractorProjectAnswerForm,
@ -361,6 +364,10 @@ class ContractorProjectAnswerView(BaseMixin, View):
class PortfolioTrashView(View):
pass
class CustomerProjectTrashView(View): class CustomerProjectTrashView(View):
form_class = CustomerProjectTrashForm form_class = CustomerProjectTrashForm
@ -461,9 +468,19 @@ class OfferOrderView(View):
def contractor_portfolio_create(request): def contractor_portfolio_create(request):
if request.is_ajax(): if request.is_ajax():
form = PortfolioForm(data=request.POST) form = PortfolioForm(data=request.POST)
# import code; code.interact(local=dict(globals(), **locals()))
if form.is_valid(): if form.is_valid():
instance = form.save(commit=False) instance = form.save(commit=False)
instance.save() 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'} data = {'status': 'ok'}
else: else:
data = {'status': 'no', 'form_errors': form.errors} data = {'status': 'no', 'form_errors': form.errors}

@ -0,0 +1,5 @@
from django.contrib import admin
from .models import SpecializationRating, HistoryRating
admin.site.register(SpecializationRating)
admin.site.register(HistoryRating)

@ -0,0 +1,5 @@
from django.apps import AppConfig
class RatingsConfig(AppConfig):
name = 'ratings'

@ -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': 'Рейтинги специализаций',
},
),
]

@ -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 = 'Рейтинги специализаций'

@ -0,0 +1,3 @@
from django.test import TestCase
# Create your tests here.

@ -0,0 +1,3 @@
from django.shortcuts import render
# Create your views here.

@ -72,8 +72,8 @@
{% endblock %} {% endblock %}
<script type="text/javascript"> <script type="text/javascript">
var userId = '{{ request.user.pk }}';
var SocketHandlerMain = function () { var SocketHandlerMain = function (userId) {
var url = 'ws://127.0.0.1:8888/chat/' + userId + '/'; var url = 'ws://127.0.0.1:8888/chat/' + userId + '/';
var sock = new WebSocket(url); var sock = new WebSocket(url);
var intervalId; var intervalId;
@ -83,15 +83,18 @@
sock.send('{"dummy": 1}'); sock.send('{"dummy": 1}');
}, 150000); }, 150000);
}; };
sock.onmessage = function (event) { sock.onmessage = function (event) {
var notificationData = JSON.parse(event.data); var notificationData = JSON.parse(event.data);
$.jGrowl("Вам пришло новое сообщение!" + notificationData.msg, {sticky: true}); $.jGrowl("Вам пришло новое сообщение!" + notificationData.msg, {sticky: true});
}; };
} }
$(function () { $(function () {
var socketMain = new SocketHandlerMain(); var userId = '{{ request.user.pk }}';
if (userId) {
var socketMain = new SocketHandlerMain(userId);
}
}); });
</script> </script>
</body> </body>

@ -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),
),
]

@ -25,8 +25,9 @@ class UserManager(BaseUserManager):
user.save(using=self._db) user.save(using=self._db)
return user return user
def create_superuser(self, username, password): def create_superuser(self, email, password):
user = self.create_user(username, 'admin@exampletest.com', password) username = email
user = self.create_user(username, email, password)
user.is_superuser = True user.is_superuser = True
user.save(using=self._db) user.save(using=self._db)
return user return user
@ -122,6 +123,7 @@ class User(AbstractBaseUser, PermissionsMixin):
contractor_resume = models.OneToOneField(ContractorResume, related_name='contractor', blank=True, null=True) contractor_resume = models.OneToOneField(ContractorResume, related_name='contractor', blank=True, null=True)
contractor_specializations = TreeManyToManyField(Specialization, related_name='contractors', blank=True) contractor_specializations = TreeManyToManyField(Specialization, related_name='contractors', blank=True)
contractor_status = models.CharField(default='free', max_length=20, choices=STATUSES) contractor_status = models.CharField(default='free', max_length=20, choices=STATUSES)
contractor_rating = models.FloatField(default=0.0)
created = models.DateTimeField(default=timezone.now) created = models.DateTimeField(default=timezone.now)
cro = models.BooleanField(default=False) cro = models.BooleanField(default=False)
date_joined = models.DateTimeField(default=timezone.now) date_joined = models.DateTimeField(default=timezone.now)
@ -197,3 +199,6 @@ class Team(models.Model):
class Meta: class Meta:
verbose_name = 'Команда' verbose_name = 'Команда'
verbose_name_plural = 'Команды' verbose_name_plural = 'Команды'

@ -465,13 +465,19 @@
dataType: 'json', dataType: 'json',
success: function (data) { success: function (data) {
if (data.status == 'ok') { if (data.status == 'ok') {
$('#portfolio-add-form').each(function(){
this.reset();
});
location.reload(); location.reload();
}else if(data.status == 'no'){
$.each(data.form_errors, function(k,v){
$('.error-'+ k).html(v).show();
});
} }
}, },
error: function (jqXHR, exception) { error: function (jqXHR, exception) {
console.log(jqXHR.statusCode); console.log(jqXHR.statusCode);
} }
}); });
}); });
var url = '/work_sell/basic/'; var url = '/work_sell/basic/';
@ -481,7 +487,7 @@
url: url, url: url,
crossDomain: false, crossDomain: false,
beforeSend: function (xhr, settings) { beforeSend: function (xhr, settings) {
$('#progress .progress-bar').css( $('#progress-portfolio .progress-bar').css(
'width', 'width',
'0%' '0%'
); );
@ -504,7 +510,42 @@
progressall: function (e, data) { progressall: function (e, data) {
var progress = parseInt(data.loaded / data.total * 100, 10); var progress = parseInt(data.loaded / data.total * 100, 10);
console.log(progress); 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 = $('<img style="width:200px;height:200px;margin:10px;">').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', 'width',
progress + '%' progress + '%'
); );

@ -3,13 +3,13 @@
<form method="post" id="portfolio-add-form">{% csrf_token %} <form method="post" id="portfolio-add-form">{% csrf_token %}
<div class="textAreaBlock2 text-nn box-sizing disTab"> <div class="textAreaBlock2 text-nn box-sizing disTab">
<p>Название<span style="color: red">{{ portfolio_form.name.errors.as_text }}</span></p> <p>Название<span style="color: red" class="error-{{ portfolio_form.name.html_name }}">{{ portfolio_form.name.errors.as_text }}</span></p>
<input type="text" class="box-sizing" name="{{ portfolio_form.name.html_name }}" <input type="text" class="box-sizing" name="{{ portfolio_form.name.html_name }}"
value="{{ portfolio_form.name.value }}"> value="{{ portfolio_form.name.value }}">
</div> </div>
<div class="textAreaBlock2 text-nn box-sizing disTab"> <div class="textAreaBlock2 text-nn box-sizing disTab">
<p>Описание<span style="color: red">{{ portfolio_form.description.errors.as_text }}</span></p> <p>Описание<span style="color: red" class="error-{{ portfolio_form.description.html_name }}">{{ portfolio_form.description.errors.as_text }}</span></p>
<textarea name="{{ portfolio_form.description.html_name }}" id="text-new">{{ portfolio_form.description.value }}</textarea> <textarea name="{{ portfolio_form.description.html_name }}" id="text-new">{{ portfolio_form.description.value }}</textarea>
</div> </div>
@ -77,24 +77,21 @@
</div> </div>
<div class="polsF1 polsF2 disTab"> <div class="polsF1 polsF2 disTab">
<input type="hidden" name="" id="upload-files-pk" value="" /> <input type="hidden" name="images-ids" id="upload-files-pk" />
</div> </div>
<!-- The fileinput-button span is used to style the file input field as button --> <!-- The fileinput-button span is used to style the file input field as button -->
{# <span class="btn btn-success fileinput-button">#} <span class="btn btn-success fileinput-button">
{# <i class="glyphicon glyphicon-plus"></i>#} <i class="glyphicon glyphicon-plus"></i>
{# <span>Выберите файлы</span>#} <span>Выберите файлы</span>
{# <!-- The file input field used as target for the file upload widget -->#}
{# <input id="fileupload" type="file" name="file" multiple>#}
{# </span>#}
<input id="fileupload" type="file" name="file" multiple> <input id="fileupload" type="file" name="file" multiple>
</span>
<br> <br>
<br> <br>
<!-- The global progress bar --> <!-- The global progress bar -->
<div id="progress" class="progress"> <div id="progress-portfolio" class="progress">
<div class="progress-bar progress-bar-success"></div> <div class="progress-bar progress-bar-success"></div>
</div> </div>
<!-- The container for the uploaded files --> <!-- The container for the uploaded files -->

@ -75,26 +75,25 @@
<input type="hidden" name="{{ worksell_form.contractor.html_name }}" value="{{ request.user.pk }}" /> <input type="hidden" name="{{ worksell_form.contractor.html_name }}" value="{{ request.user.pk }}" />
</div> </div>
{# <div class="polsF1 polsF2 disTab">#} <div class="polsF1 polsF2 disTab">
{# <input type="file" name="{{ worksell_form.img.html_name }}" >#} <input type="text" name="" id="upload-files-worksell-pk" />
{# </div>#} </div>
<!-- The fileinput-button span is used to style the file input field as button --> <!-- The fileinput-button span is used to style the file input field as button -->
<span class="btn btn-success fileinput-button"> <span class="btn btn-success fileinput-button">
<i class="glyphicon glyphicon-plus"></i> <i class="glyphicon glyphicon-plus"></i>
<span>Выберите файлы</span> <span>Выберите файлы</span>
<!-- The file input field used as target for the file upload widget --> <!-- The file input field used as target for the file upload widget -->
<input id="fileupload" type="file" name="file" multiple> <input id="fileupload-worksell" type="file" name="file" multiple>
</span> </span>
<br> <br>
<br> <br>
<!-- The global progress bar --> <!-- The global progress bar -->
<div id="progress" class="progress"> <div id="progress-worksell" class="progress">
<div class="progress-bar progress-bar-success"></div> <div class="progress-bar progress-bar-success"></div>
</div> </div>
<!-- The container for the uploaded files --> <!-- The container for the uploaded files -->
<div id="files" class="files"></div> <div id="files-worksell" class="files"></div>
<br> <br>
<div class="searchF1 polsF1 polsFF links-filter"> <div class="searchF1 polsF1 polsFF links-filter">

Loading…
Cancel
Save