diff --git a/assets/css/extra.css b/assets/css/extra.css index c1aa855..3b50ed2 100644 --- a/assets/css/extra.css +++ b/assets/css/extra.css @@ -96,3 +96,14 @@ float: left; margin: 33px 0 0 0; } + + +.form-regestration .errorlist { + color: red; + width: 360px; + margin: 0 auto; + text-align: left; + font-family: 'Arial-MT-Regular', sans-serif; + font-size: 15px; + +} diff --git a/assets/css/main.css b/assets/css/main.css index 8f7b0c7..c27aa5a 100644 --- a/assets/css/main.css +++ b/assets/css/main.css @@ -4345,7 +4345,7 @@ input[type="checkbox"]:checked + span { width: 100%; float: left; margin: 0 0 80px 0; - padding: 67px 0 0 0; + padding: 67px 0 15px 0; background-color: #ddd; text-align: center; } diff --git a/projects/migrations/0009_project_is_archive.py b/projects/migrations/0009_project_is_archive.py new file mode 100644 index 0000000..7868920 --- /dev/null +++ b/projects/migrations/0009_project_is_archive.py @@ -0,0 +1,20 @@ +# -*- coding: utf-8 -*- +# Generated by Django 1.9.7 on 2016-08-16 13:58 +from __future__ import unicode_literals + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('projects', '0008_auto_20160815_1900'), + ] + + operations = [ + migrations.AddField( + model_name='project', + name='is_archive', + field=models.BooleanField(default=False), + ), + ] diff --git a/projects/migrations/0010_auto_20160816_1831.py b/projects/migrations/0010_auto_20160816_1831.py new file mode 100644 index 0000000..59f968e --- /dev/null +++ b/projects/migrations/0010_auto_20160816_1831.py @@ -0,0 +1,24 @@ +# -*- coding: utf-8 -*- +# Generated by Django 1.9.7 on 2016-08-16 15:31 +from __future__ import unicode_literals + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('projects', '0009_project_is_archive'), + ] + + operations = [ + migrations.RemoveField( + model_name='project', + name='is_archive', + ), + migrations.AddField( + model_name='answer', + name='is_archive', + field=models.BooleanField(default=False), + ), + ] diff --git a/projects/models.py b/projects/models.py index 24ab994..96c8551 100644 --- a/projects/models.py +++ b/projects/models.py @@ -126,6 +126,7 @@ class Answer(models.Model): secure_deal_only = models.BooleanField(default=False) term = models.IntegerField(blank=True, null=True) term_type = models.CharField(max_length=10, choices=TERMS, blank=True, null=True) + is_archive = models.BooleanField(default=False) content_type = models.ForeignKey(ContentType, limit_choices_to=Q(app_label='users', model='user') | Q(app_label='users', model='team')) object_id = models.IntegerField() diff --git a/projects/urls.py b/projects/urls.py index 6464d0d..506267e 100644 --- a/projects/urls.py +++ b/projects/urls.py @@ -16,6 +16,7 @@ from .views import ( ProjectComparisonView, ProjectDetailWithAnswerView, ProjectFilterView, + ContractorAnswerArchiveView, sort_candidates, ) @@ -28,6 +29,7 @@ urlpatterns = [ urls.url(r'^create/$', CustomerProjectCreateView.as_view(), name='customer-project-create'), urls.url(r'^(?P\d+)/edit/$', CustomerProjectEditView.as_view(), name='customer-project-edit'), urls.url(r'^(?P\d+)/trash/$', CustomerProjectTrashView.as_view(), name='customer-project-trash'), + urls.url(r'^answer/move/archive/$', ContractorAnswerArchiveView.as_view(), name='contractor-answer-archive'), urls.url(r'^portfolio/(?P\d+)/trash/$', ContractorPortfolioTrashView.as_view(), name='contractor-portfolio-trash'), urls.url(r'^(?P\d+)/restore/$', CustomerProjectRestoreView.as_view(), name='customer-project-restore'), urls.url(r'^(?P\d+)/delete/$', CustomerProjectDeleteView.as_view(), name='customer-project-delete'), diff --git a/projects/views.py b/projects/views.py index 98db86a..4a94efa 100644 --- a/projects/views.py +++ b/projects/views.py @@ -193,8 +193,9 @@ class ProjectFilterView(BaseMixin, View): for k in keywords: projects = projects.filter(Q(name__icontains=k) | Q(text__icontains=k)) - projects = projects.filter(cro=cro) - + # projects = projects.filter(cro=cro) + + if work_type: projects = projects.filter(work_type=work_type) @@ -430,6 +431,18 @@ class CustomerProjectEditView(BaseMixin, View): return render(request, self.template_name, context) +class ContractorAnswerArchiveView(View): + + def post(self, request, *args, **kwargs): + project_pk = request.POST.get('project_pk') + user_pk = request.POST.get('user_pk') + answer = Answer.objects.filter(project_id=project_pk,object_id=user_pk, content_type__model='user').first() + answer.is_archive = True + answer.save() + redirect_to = request.POST.get('next') + return redirect(redirect_to) + + class ContractorPortfolioTrashView(View): form_class = ContractorPortfolioTrashForm diff --git a/ratings/templatetags/specializtions_tags.py b/ratings/templatetags/specializtions_tags.py index ba41ca1..564e8d5 100644 --- a/ratings/templatetags/specializtions_tags.py +++ b/ratings/templatetags/specializtions_tags.py @@ -7,7 +7,7 @@ from ratings.models import SpecializationRating register = template.Library() @register.inclusion_tag('templatetags/specializations_widget.html', takes_context=True) -def specialization_widget(context, user_id): +def specialization_widget(context, user_id, class_name=None): user_id = int(user_id) specializations = SpecializationRating.objects.select_related('specialization').filter(user_id=user_id) return { diff --git a/templates/registration/login.html b/templates/registration/login.html index 1147c9f..78a046a 100644 --- a/templates/registration/login.html +++ b/templates/registration/login.html @@ -8,22 +8,63 @@

Вход на сайт

- {{ form.errors }} +
{% csrf_token %} + {{ form.non_field_errors }}
+ {{ form.username.errors }}
+ {{ form.password.errors }}
-

Запомнить

-

Забыли пароль ?

+

Запомнить

+

Забыли пароль ?

-
+
+ +
+
+
+ +
+ + fb + +
+ +
+ + tw + +
+ +
+ + gplus + +
+ +
+ + vk + +
+ +
+ + yt + +
+ +
+
+
diff --git a/templates/registration/registration_complete.html b/templates/registration/registration_complete.html index d349892..9ad6d44 100644 --- a/templates/registration/registration_complete.html +++ b/templates/registration/registration_complete.html @@ -7,6 +7,9 @@

Регистрация прошла успешно

+

Вам необходимо активировать этот аккаунт. Перейдите по ссылке в письме, + которое вам отправлено на почту +

{% include 'partials/footer.html' %} diff --git a/templates/registration/registration_form.html b/templates/registration/registration_form.html index 373df04..e6845e6 100644 --- a/templates/registration/registration_form.html +++ b/templates/registration/registration_form.html @@ -8,7 +8,7 @@
{% csrf_token %} - {{ form.errors }} + {{ form.non_field_errors }}
{% if request.GET.type == 'customer' %} @@ -27,19 +27,23 @@
+ {{ form.username.errors }}
-
+
+ {{ form.email.errors }}
+ {{ form.password1.errors }}
+ {{ form.password2.errors }}
@@ -92,7 +96,7 @@
diff --git a/users/templates/contractor_office.html b/users/templates/contractor_office.html index f780884..23b6f9d 100644 --- a/users/templates/contractor_office.html +++ b/users/templates/contractor_office.html @@ -7,46 +7,12 @@ {% block content %} {% include 'partials/header.html' %} -
+

Личный кабинет

- -
- -
- + {% include 'partials/contractor_profile_tabs.html' with contractor_pk=request.user.pk active='groups' %}
+ +
+
+
+ {% for proj in open_projects %} +
+
+ +

+ {{ proj }} +

+
+
    +
  • + Объект "{{ proj.realty.name }}" +
  • +
  • + 0 ответ от имени группы +
  • +
+

+

+
    +
  • + {{ proj.created }} +
  • +
  • + 0 +
  • +
  • + 0 +
  • +
  • + {{ proj.customer.username }} +
  • +
+
+
+

+ {{ proj.budget }} +

+ +
+
+ {% endfor %} +
+ + + {% include 'partials/footer.html' %} +
+
+{% endblock %} diff --git a/users/templates/contractor_office_open_projects_archive.html b/users/templates/contractor_office_open_projects_archive.html new file mode 100644 index 0000000..27b2fdd --- /dev/null +++ b/users/templates/contractor_office_open_projects_archive.html @@ -0,0 +1,98 @@ +{% extends 'partials/base.html' %} + +{% load staticfiles %} +{% load specializtions_tags %} +{% load thumbnail %} + +{% block content %} + {% include 'partials/header.html' %} + +
+
+
+

Личный кабинет

+
+ {% include 'partials/contractor_profile_tabs.html' with contractor_pk=request.user.pk active='open' all_project_count=projects_count %} +
+ +
+ + +
+
+
+ {% for proj in open_projects %} +
+
+ +

+ {{ proj }} +

+
+
    +
  • + Объект "{{ proj.realty.name }}" +
  • +
  • + 0 ответ от имени группы +
  • +
+

+

+
    +
  • + {{ proj.created }} +
  • +
  • + 0 +
  • +
  • + 0 +
  • +
  • + {{ proj.customer.username }} +
  • +
+
+
+

+ {{ proj.budget }} +

+ +
+
+ {% endfor %} +
+ + {% include 'partials/footer.html' %} +
+
+{% endblock %} diff --git a/users/templates/partials/contractor_profile_tabs.html b/users/templates/partials/contractor_profile_tabs.html new file mode 100644 index 0000000..81d36da --- /dev/null +++ b/users/templates/partials/contractor_profile_tabs.html @@ -0,0 +1,30 @@ +
+ +
diff --git a/users/urls.py b/users/urls.py index e65d542..acb7e85 100755 --- a/users/urls.py +++ b/users/urls.py @@ -16,6 +16,7 @@ from .views import ( UserProfileEditView, TeamCreateView, ContractorResumeUpdateView, + ContractorOfficeOpenProjectsView, contractor_resumefile_create, ) @@ -40,6 +41,7 @@ urlpatterns = [ urls.url(r'^contractorsresumefiles/create/$', contractor_resumefile_create, name='contractor-resume-file-create'), urls.url(r'^contractors/(?P\d+)/$', ContractorProfileDetailView.as_view(), name='contractor-profile'), urls.url(r'^contractor-office/(?P\d+)/$', ContractorOfficeDetailView.as_view(), name='contractor-office'), - + urls.url(r'^contractor-office/(?P\d+)/open-projects/$', ContractorOfficeOpenProjectsView.as_view(), name='contractor-office-open-projects'), + urls.url(r'^test/$', send_mail_test), ] diff --git a/users/views.py b/users/views.py index a6db9bb..15700d9 100644 --- a/users/views.py +++ b/users/views.py @@ -384,6 +384,60 @@ class ContractorOfficeDetailView(DetailView): return context +class ContractorOfficeOpenProjectsView(BaseMixin,View): + template_name = 'contractor_office_open_projects.html' + + def get(self, request, *args, **kwargs): + context = self.get_context_data(**_.merge({},request.GET, kwargs)) + contractor = get_object_or_404(User.contractor_objects,pk=kwargs.get('pk')) + owner = request.GET.get('owner') + # import code; code.interact(local=dict(globals(), **locals())) + if owner and owner == 'private': + all_project_ids = [a.project.pk for a in contractor.contractor_answers.filter(is_archive=False)] + elif owner and owner == 'teams': + all_project_ids = [a.project.pk for a in contractor.team.answers.filter(is_archive=False)] + else: + team_project_ids = [a.project.pk for a in contractor.team.answers.filter(is_archive=False)] + contractor_project_ids = [a.project.pk for a in contractor.contractor_answers.filter(is_archive=False)] + all_project_ids = contractor_project_ids + team_project_ids + + open_projects = Project.objects.filter(pk__in=all_project_ids) + archive_contractor_count = contractor.contractor_answers.filter(is_archive=True).count() + archive_team_count = contractor.team.answers.filter(is_archive=True).count() + archive_count = archive_contractor_count + archive_team_count + context.update({ + 'open_projects': open_projects, + 'projects_count': len(open_projects), + 'current_projects_count': len(open_projects), + 'archive_count': archive_count, + }) + return render(request, self.template_name, context) + + +class ContractorOfficeOpenProjectsArchiveView(BaseMixin,View): + template_name = 'contractor_office_open_projects_archive.html' + + def get(self, request, *args, **kwargs): + context = self.get_context_data(**_.merge({},request.GET, kwargs)) + contractor = get_object_or_404(User.contractor_objects,pk=kwargs.get('pk')) + owner = request.GET.get('owner') + # import code; code.interact(local=dict(globals(), **locals())) + if owner and owner == 'private': + all_project_ids = [a.project.pk for a in contractor.contractor_answers.all()] + elif owner and owner == 'teams': + all_project_ids = [a.project.pk for a in contractor.team.answers.all()] + else: + team_project_ids = [a.project.pk for a in contractor.team.answers.all()] + contractor_project_ids = [a.project.pk for a in contractor.contractor_answers.all()] + all_project_ids = contractor_project_ids + team_project_ids + + open_projects = Project.objects.filter(pk__in=all_project_ids) + context.update({ + 'open_projects': open_projects, + 'projects_count': len(open_projects), + }) + return render(request, self.template_name, context) + class CustomerProfileOpenProjectsView(BaseMixin, View): template_name = 'customer_profile_open_projects.html' @@ -491,7 +545,6 @@ class CustomerProfileCurrentProjectsView(BaseMixin, DetailView): context_object_name = 'customer' - class TeamCreateView(View): form_class = TeamForm