From a44a7e4da981a5b41b795cf20a1b903ca7050781 Mon Sep 17 00:00:00 2001 From: Mukhtar Date: Fri, 12 Aug 2016 12:11:38 +0300 Subject: [PATCH 1/3] #ARC-27 make migrate --- users/migrations/0008_auto_20160812_1151.py | 25 +++++++++++++ users/templates/contractor_profile.html | 36 +++++++++++++++++-- users/templates/worksell_create_form.html | 2 +- work_sell/forms.py | 23 ++++++++---- .../migrations/0003_auto_20160812_1151.py | 21 +++++++++++ work_sell/urls.py | 4 +-- 6 files changed, 100 insertions(+), 11 deletions(-) create mode 100644 users/migrations/0008_auto_20160812_1151.py create mode 100644 work_sell/migrations/0003_auto_20160812_1151.py diff --git a/users/migrations/0008_auto_20160812_1151.py b/users/migrations/0008_auto_20160812_1151.py new file mode 100644 index 0000000..26fda63 --- /dev/null +++ b/users/migrations/0008_auto_20160812_1151.py @@ -0,0 +1,25 @@ +# -*- coding: utf-8 -*- +# Generated by Django 1.9.7 on 2016-08-12 08:51 +from __future__ import unicode_literals + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('users', '0007_auto_20160808_1557'), + ] + + operations = [ + migrations.AlterField( + model_name='contractorresumefiles', + name='title', + field=models.CharField(blank=True, max_length=255), + ), + migrations.AlterField( + model_name='contractorresumefiles', + name='type', + field=models.CharField(choices=[('diplom', 'Дипломы/Сертификаты'), ('cro', 'Допуск CPO')], default='diplom', max_length=50), + ), + ] diff --git a/users/templates/contractor_profile.html b/users/templates/contractor_profile.html index 29b7f5e..b77f72a 100644 --- a/users/templates/contractor_profile.html +++ b/users/templates/contractor_profile.html @@ -249,10 +249,14 @@
+
+
- + +

Загрузить резюме

+
{#w#}
@@ -504,7 +508,7 @@ e.preventDefault(); var dataSerializer = $(this).serialize(); $.ajax({ - url: '/work_sell/test/', + url: '/work_sell/create/', method: 'POST', data: dataSerializer, dataType: 'json', @@ -512,9 +516,11 @@ if (data.status == 'ok') { location.reload(); } + }, error: function (jqXHR, exception) { console.log(jqXHR.statusCode); + console.log(jqXHR); } }) @@ -524,6 +530,7 @@ $('#portfolio-add-form').on('submit', function (e) { e.preventDefault(); var dataSerializer = $(this).serialize(); + $.ajax({ url: '/projects/portfolio/create/', method: 'POST', @@ -549,6 +556,31 @@ var url = '/work_sell/basic/'; var csrftoken = $.cookie('csrftoken'); + $("#upload-resume").on('change',function(e){ + var formData = new FormData($(this).closest("form")); + formData.append('resume_file', e.target.files[0]); + console.log(formData); + console.log(e.target.files[0]); + $.ajax({ + url:'/api/contractorresume/{{ contractor.contractor_resume.pk }}/', + method:'PUT', + beforeSend: function (xhr) { + xhr.setRequestHeader("X-CSRFToken", getCookie('csrftoken')); + }, + data: formData, + cache: false, + dataType: 'json', + processData: false, + contentType: false, + success: function(data){ + console.log(data); + }, + error: function(jqXHR){ + console.log(jqXHR); + } + }); + }); + $('#fileupload').fileupload({ url: url, crossDomain: false, diff --git a/users/templates/worksell_create_form.html b/users/templates/worksell_create_form.html index bfd400d..ac4cf2f 100644 --- a/users/templates/worksell_create_form.html +++ b/users/templates/worksell_create_form.html @@ -76,7 +76,7 @@
- +
diff --git a/work_sell/forms.py b/work_sell/forms.py index 57a4012..40887ca 100644 --- a/work_sell/forms.py +++ b/work_sell/forms.py @@ -15,16 +15,27 @@ class ContractorWorkSellTrashForm(forms.Form): class WorkSellForm(forms.ModelForm): - class Meta: model = WorkSell - fields = '__all__' + fields = ( + 'budget', + 'building_classification', + 'construction_type', + 'contractor', + 'currency', + 'description', + 'location', + 'name', + 'specialization', + 'term', + 'term_type', + ) widgets = { - 'construction_type': forms.Select(attrs={'class':'selectpicker'}), - 'building_classification': forms.Select(attrs={'class':'selectpicker'}), - 'currency': forms.Select(attrs={'class':'selectpicker'}), - 'term_type': forms.Select(attrs={'class':'selectpicker'}), + 'construction_type': forms.Select(attrs={'class': 'selectpicker'}), + 'building_classification': forms.Select(attrs={'class': 'selectpicker'}), + 'currency': forms.Select(attrs={'class': 'selectpicker'}), + 'term_type': forms.Select(attrs={'class': 'selectpicker'}), } def __init__(self, *args, **kwargs): diff --git a/work_sell/migrations/0003_auto_20160812_1151.py b/work_sell/migrations/0003_auto_20160812_1151.py new file mode 100644 index 0000000..b59345e --- /dev/null +++ b/work_sell/migrations/0003_auto_20160812_1151.py @@ -0,0 +1,21 @@ +# -*- coding: utf-8 -*- +# Generated by Django 1.9.7 on 2016-08-12 08:51 +from __future__ import unicode_literals + +from django.db import migrations, models +import django.utils.timezone + + +class Migration(migrations.Migration): + + dependencies = [ + ('work_sell', '0002_auto_20160805_1736'), + ] + + operations = [ + migrations.AlterField( + model_name='worksell', + name='created', + field=models.DateTimeField(default=django.utils.timezone.now), + ), + ] diff --git a/work_sell/urls.py b/work_sell/urls.py index b6ecdb8..90a7d6d 100644 --- a/work_sell/urls.py +++ b/work_sell/urls.py @@ -18,12 +18,12 @@ app_name = 'work_sell' urlpatterns = [ urls.url(r'^$', WorkSellsView.as_view(), name='list'), - urls.url(r'^create/$', WorkSellCreateView.as_view(), name='create'), + # urls.url(r'^create/$', WorkSellCreateView.as_view(), name='create'), urls.url(r'^upload/$', UploadView.as_view(), name='upload'), urls.url(r'^(?P\d+)/edit/$',WorkSellUpdateView.as_view(), name='edit'), urls.url(r'^(?P\d+)/delete/$',WorkSellDeleteView.as_view(), name='delete'), urls.url(r'^(?P\d+)/trash/$', ContractorWorkSellTrashView.as_view(), name='contractor-worksell-trash'), - urls.url(r'^test/$', work_sell_create, name='test'), + urls.url(r'^create/$', work_sell_create, name='create'), urls.url(r'^basic/$', BasicCreateView.as_view(), name='upload-basic'), urls.url(r'^new/$', PictureCreateView.as_view(), name='upload-new'), urls.url(r'^(?P\d+)/$', WorkSellDetail.as_view(), name='detail'), From 04e72a96a74305ede2ab65e266dad710d719e28f Mon Sep 17 00:00:00 2001 From: Mukhtar Date: Fri, 12 Aug 2016 15:13:42 +0300 Subject: [PATCH 2/3] #ARC-15 add position for candidate table --- archilance/settings/base.py | 2 +- chat/migrations/0005_message_is_new.py | 20 +++++ chat/models.py | 1 + chat/views.py | 2 + .../migrations/0002_candidate_position.py | 20 +++++ .../migrations/0003_auto_20160812_1512.py | 20 +++++ projects/models.py | 1 + templates/partials/base.html | 76 ++++++++++--------- templates/registration/registration_form.html | 10 +-- users/pipeline.py | 23 +++++- users/templates/contractor_office.html | 3 +- users/templates/contractor_profile.html | 8 +- users/templates/register_social_mail.html | 2 + users/templates/register_social_mail.txt | 2 + 14 files changed, 145 insertions(+), 45 deletions(-) create mode 100644 chat/migrations/0005_message_is_new.py create mode 100644 projects/migrations/0002_candidate_position.py create mode 100644 projects/migrations/0003_auto_20160812_1512.py create mode 100644 users/templates/register_social_mail.html create mode 100644 users/templates/register_social_mail.txt diff --git a/archilance/settings/base.py b/archilance/settings/base.py index 2c76934..eb857a0 100644 --- a/archilance/settings/base.py +++ b/archilance/settings/base.py @@ -188,7 +188,7 @@ SOCIAL_AUTH_PIPELINE = ( 'social.pipeline.social_auth.associate_user', 'social.pipeline.social_auth.load_extra_data', 'social.pipeline.user.user_details', - 'users.pipeline.test_contractor', + 'users.pipeline.success_social_register', ) FIELDS_STORED_IN_SESSION = ['user_type'] diff --git a/chat/migrations/0005_message_is_new.py b/chat/migrations/0005_message_is_new.py new file mode 100644 index 0000000..16ff70b --- /dev/null +++ b/chat/migrations/0005_message_is_new.py @@ -0,0 +1,20 @@ +# -*- coding: utf-8 -*- +# Generated by Django 1.9.7 on 2016-08-12 12:08 +from __future__ import unicode_literals + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('chat', '0004_auto_20160804_1806'), + ] + + operations = [ + migrations.AddField( + model_name='message', + name='is_new', + field=models.BooleanField(default=True), + ), + ] diff --git a/chat/models.py b/chat/models.py index 4a52622..dbd9eb2 100644 --- a/chat/models.py +++ b/chat/models.py @@ -13,6 +13,7 @@ class Message(models.Model): recipent = models.ForeignKey(User, related_name='recipent_messages') private_type = models.BooleanField(default=False) team = models.ForeignKey(Team, related_name='messages', null=True, blank=True) + is_new = models.BooleanField(default=True) def __str__(self): return self.text diff --git a/chat/views.py b/chat/views.py index 5edab5e..7dfb274 100644 --- a/chat/views.py +++ b/chat/views.py @@ -56,6 +56,8 @@ class ChatUserView(View): if request.user.is_owner_team(): team_orders = request.user.team.orders.all() + else: + team_orders = [] self.template_name = 'chat_contractor.html' return render(request, self.template_name, {'orders': orders, diff --git a/projects/migrations/0002_candidate_position.py b/projects/migrations/0002_candidate_position.py new file mode 100644 index 0000000..974aa8a --- /dev/null +++ b/projects/migrations/0002_candidate_position.py @@ -0,0 +1,20 @@ +# -*- coding: utf-8 -*- +# Generated by Django 1.9.7 on 2016-08-12 12:11 +from __future__ import unicode_literals + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('projects', '0001_squashed_0015_merge'), + ] + + operations = [ + migrations.AddField( + model_name='candidate', + name='position', + field=models.PositiveIntegerField(default=0, max_length=10), + ), + ] diff --git a/projects/migrations/0003_auto_20160812_1512.py b/projects/migrations/0003_auto_20160812_1512.py new file mode 100644 index 0000000..b7bd915 --- /dev/null +++ b/projects/migrations/0003_auto_20160812_1512.py @@ -0,0 +1,20 @@ +# -*- coding: utf-8 -*- +# Generated by Django 1.9.7 on 2016-08-12 12:12 +from __future__ import unicode_literals + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('projects', '0002_candidate_position'), + ] + + operations = [ + migrations.AlterField( + model_name='candidate', + name='position', + field=models.PositiveIntegerField(default=0), + ), + ] diff --git a/projects/models.py b/projects/models.py index dd83ce5..1364903 100644 --- a/projects/models.py +++ b/projects/models.py @@ -203,6 +203,7 @@ class Candidate(models.Model): answer = models.ForeignKey(Answer, related_name='candidates') project = models.ForeignKey(Project, related_name='candidates') status = models.BooleanField(default=False) + position = models.PositiveIntegerField(default=0) def __str__(self): return self.answer.user.get_full_name() diff --git a/templates/partials/base.html b/templates/partials/base.html index d2f8708..546267c 100644 --- a/templates/partials/base.html +++ b/templates/partials/base.html @@ -3,41 +3,43 @@ - - - - - -Archilance -{% load compress %} - -{% compress css %} - - - - - - - - - - - - - -{% endcompress %} + + + + + + Archilance + {% load compress %} + + {% compress css %} + + + + + + + + + + + + + + {% endcompress %} {% if messages %} {% for message in messages %} -
{{ message|safe }}
+
{{ message|safe }}
{% endfor %} {% endif %}
{{ request.user }}
- + {% if request.user.is_authenticated %} PK: {{ request.user.pk }}
Groups: {{ request.user.groups.all }} @@ -73,8 +75,14 @@ {% endblock %} diff --git a/templates/registration/registration_form.html b/templates/registration/registration_form.html index dc7dfbb..373df04 100644 --- a/templates/registration/registration_form.html +++ b/templates/registration/registration_form.html @@ -17,7 +17,7 @@ {% else %}
@@ -25,12 +25,12 @@ {% endif %}
-
+ value="{{ form.email.value }}" placeholder="Электронная почта">
diff --git a/users/pipeline.py b/users/pipeline.py index e181e8b..ddd79c6 100644 --- a/users/pipeline.py +++ b/users/pipeline.py @@ -1,18 +1,37 @@ from django.shortcuts import redirect, render_to_response +from django.core.mail import EmailMultiAlternatives +from django.template.loader import get_template, render_to_string from social.pipeline.partial import partial from django.contrib.auth.models import Group from users.models import ContractorResume + +def send_user_mail(user): + ctx_dict = { + 'user': user, + } + subject, from_email, to = 'Регистрация черз социальные сети', 'mukhtar@mukhtar', user.email + text_content = render_to_string('register_social_mail.txt', ctx_dict) + html_content = get_template('register_social_mail.html').render(ctx_dict) + msg = EmailMultiAlternatives(subject, text_content, from_email, [to]) + msg.attach_alternative(html_content, "text/html") + msg.send() + + @partial -def test_contractor(backend, details, response, user,is_new=False, *args, **kwargs): +def success_social_register(backend, details, response, user,is_new=False, *args, **kwargs): if is_new: - group_name = 'Исполнители' + group_name = backend.strategy.session_get('user_type') + # group_name = 'Исполнители' g = Group.objects.get(name=group_name) g.user_set.add(user) if group_name == 'Исполнители': resume = ContractorResume.objects.create(text='Здесь должна быть описание вашего резюме') user.contractor_resume = resume user.save() + #Отправка письма на почту + send_user_mail(user) + @partial def add_email_for_user(backend, details, response, is_new=False, *args, **kwargs): diff --git a/users/templates/contractor_office.html b/users/templates/contractor_office.html index 4b495d7..22a8955 100644 --- a/users/templates/contractor_office.html +++ b/users/templates/contractor_office.html @@ -89,7 +89,7 @@
- +{% if contractor.is_owner_team %}
@@ -276,6 +276,7 @@
+ {% endif %} {% include 'partials/footer.html' %}
diff --git a/users/templates/contractor_profile.html b/users/templates/contractor_profile.html index b77f72a..1b2d16a 100644 --- a/users/templates/contractor_profile.html +++ b/users/templates/contractor_profile.html @@ -271,12 +271,13 @@

{{ user.get_full_name }}

+
{% if contractor.contractor_resume.resume_file %} - скачать резюме {% endif %}

- {# Мужчина, 24 года, {{ user.date_of_birth }}#} + Мужчина, 24 года, {{ user.date_of_birth }}#}

@@ -557,6 +558,7 @@ var csrftoken = $.cookie('csrftoken'); $("#upload-resume").on('change',function(e){ + $("#resume-success").html(""); var formData = new FormData($(this).closest("form")); formData.append('resume_file', e.target.files[0]); console.log(formData); @@ -573,6 +575,8 @@ processData: false, contentType: false, success: function(data){ + $("#resume-success").html("Файл для резюме успешно загружен!"); + $(".download-summ").css('display','block').attr('href',data.resume_file); console.log(data); }, error: function(jqXHR){ diff --git a/users/templates/register_social_mail.html b/users/templates/register_social_mail.html new file mode 100644 index 0000000..7f6b129 --- /dev/null +++ b/users/templates/register_social_mail.html @@ -0,0 +1,2 @@ +Регистрация через соцсети +{{ user.username }} diff --git a/users/templates/register_social_mail.txt b/users/templates/register_social_mail.txt new file mode 100644 index 0000000..7f6b129 --- /dev/null +++ b/users/templates/register_social_mail.txt @@ -0,0 +1,2 @@ +Регистрация через соцсети +{{ user.username }} From 0789aed6675292a2ef634b2207afbfe562efdd16 Mon Sep 17 00:00:00 2001 From: Mukhtar Date: Fri, 12 Aug 2016 16:04:57 +0300 Subject: [PATCH 3/3] #ARC-16 Fixes websocket url --- archilance/settings/base.py | 8 ++++---- chat/templates/chat_contractor.html | 8 ++++---- chat/templates/chat_customer.html | 5 ++++- projects/urls.py | 2 +- 4 files changed, 13 insertions(+), 10 deletions(-) diff --git a/archilance/settings/base.py b/archilance/settings/base.py index eb857a0..f615008 100644 --- a/archilance/settings/base.py +++ b/archilance/settings/base.py @@ -123,10 +123,10 @@ DATABASES = { # https://docs.djangoproject.com/en/1.9/ref/settings/#auth-password-validators AUTH_PASSWORD_VALIDATORS = [ - {'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator'}, - {'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator'}, - {'NAME': 'django.contrib.auth.password_validation.CommonPasswordValidator'}, - {'NAME': 'django.contrib.auth.password_validation.NumericPasswordValidator'}, + # {'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator'}, + # {'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator'}, + # {'NAME': 'django.contrib.auth.password_validation.CommonPasswordValidator'}, + # {'NAME': 'django.contrib.auth.password_validation.NumericPasswordValidator'}, ] AUTHENTICATION_BACKENDS = ( diff --git a/chat/templates/chat_contractor.html b/chat/templates/chat_contractor.html index 35e5215..79fbf73 100644 --- a/chat/templates/chat_contractor.html +++ b/chat/templates/chat_contractor.html @@ -253,7 +253,10 @@ var SocketHandler = function () { var userId = {{ request.user.pk }}; - var url = 'ws://127.0.0.1:8888/chat/' + userId + '/'; + var domain = '{{ request.META.HTTP_HOST }}'; + var port = '{{ request.META.SERVER_PORT }}'; + domain = domain.replace(':' + port, ''); + var url = 'ws://' + domain +':8888/chat/' + userId + '/'; var sock = new WebSocket(url); var intervalId; sock.onopen = function () { @@ -581,7 +584,6 @@ }); - //Добавить сообщение для исполнителей в группе $("#add-team-chat-message").on('click', function(){ @@ -607,8 +609,6 @@ } }); - - $("#team-chat-form #chatText").val(""); }); diff --git a/chat/templates/chat_customer.html b/chat/templates/chat_customer.html index 865a822..e7f4089 100644 --- a/chat/templates/chat_customer.html +++ b/chat/templates/chat_customer.html @@ -523,7 +523,10 @@ var userId = '{{ request.user.pk }}'; var SocketHandler = function () { - var url = 'ws://127.0.0.1:8888/chat/' + userId + '/'; + var domain = '{{ request.META.HTTP_HOST }}'; + var port = '{{ request.META.SERVER_PORT }}'; + domain = domain.replace(':' + port, ''); + var url = 'ws://' + domain +':8888/chat/' + userId + '/'; var sock = new WebSocket(url); var intervalId; sock.onopen = function () { diff --git a/projects/urls.py b/projects/urls.py index ad497a8..7ad4a16 100644 --- a/projects/urls.py +++ b/projects/urls.py @@ -34,7 +34,7 @@ urlpatterns = [ urls.url(r'^portfolio/(?P\d+)/edit/$', ContractorPortfolioUpdateView.as_view(), name='contractor-portfolio-edit'), urls.url(r'^candidate/add/(?P(\d+))/(?P(\d+))/$', add_candidate, name='add-candidate'), - urls.url(r'^candidate/comparison/(?P\d+)$', ProjectComparisonView.as_view(), name='comparison'), + urls.url(r'^candidate/comparison/(?P\d+)/$', ProjectComparisonView.as_view(), name='comparison'), urls.url(r'^offerorder/(?P(\d+))/(?P(\d+))/$', OfferOrderView.as_view(), name='offer-order'),