diff --git a/archilance/settings/base.py b/archilance/settings/base.py index 9b25660..0600cb5 100644 --- a/archilance/settings/base.py +++ b/archilance/settings/base.py @@ -111,7 +111,7 @@ WSGI_APPLICATION = 'archilance.wsgi.application' DATABASES = { 'default': { 'ENGINE': 'django.db.backends.postgresql_psycopg2', - 'NAME': 'archilance', + 'NAME': 'archilance2', 'USER': 'postgres', 'PASSWORD': 'postgres', 'HOST': 'localhost', diff --git a/chat/testapp.py b/chat/testapp.py index 8d245d3..0922d45 100644 --- a/chat/testapp.py +++ b/chat/testapp.py @@ -66,7 +66,7 @@ class ChatHandler(websocket.WebSocketHandler): order_value = "NULL" if order_id is None else order_id insert_sql = "INSERT INTO chat_message (id,text,created, sender_id,recipent_id, private_type,team_id, order_id) " \ - "VALUES (DEFAULT,'{0}',NOW(),{1},{2},{3},{4},{5})".format(message, sender_id, recipent_id, private_type, team_value,order_value) + "VALUES (DEFAULT,'{0}',NOW(),{1},{2},{3},{4},{5})".format(message, sender_id, recipent_id, private_type, team_value,order_value) yield self.db.execute(insert_sql) waiters = tuple(w for c, w in self.waiters if c == recipent_id or c == sender_id) @@ -92,7 +92,7 @@ if __name__ == '__main__': ioloop = IOLoop.instance() application.db = momoko.Pool( - dsn='dbname=archilance user=postgres password=postgres host=localhost', + dsn='dbname=archilance2 user=postgres password=postgres host=localhost', size=1, ioloop=ioloop, ) diff --git a/chat/views.py b/chat/views.py index 6c1d6d5..5c1aba6 100644 --- a/chat/views.py +++ b/chat/views.py @@ -12,6 +12,8 @@ class ChatUserView(View): template_name = '' def get(self, request, *args, **kwargs): + # import code; code.interact(local=dict(globals(), **locals())) + user_id = request.GET.get('user_id',None) if request.user.is_authenticated() and request.user.is_customer(): customer_contacts = Message.objects.values_list('sender_id', 'recipent_id'). \ filter(Q(recipent_id=request.user.pk) | Q(sender_id=request.user.pk)).filter(Q(team_id=None)).distinct() @@ -23,6 +25,9 @@ class ChatUserView(View): users_ids.append(a) if b != request.user.pk: users_ids.append(b) + if user_id: + users_ids.append(int(user_id)) + # import code; code.interact(local=dict(globals(), **locals())) contacts_users = User.objects.filter(pk__in=users_ids) chat_messages = Message.objects.filter(Q(sender=request.user.pk) | Q(recipent=request.user.pk)) @@ -42,6 +47,8 @@ class ChatUserView(View): users_ids.append(a) if b != request.user.pk: users_ids.append(b) + if user_id: + users_ids.append(int(user_id)) contacts_users = User.objects.filter(pk__in=users_ids) chat_messages = Message.objects.filter(Q(sender=request.user.pk) | Q(recipent=request.user.pk)).order_by( 'created') diff --git a/common/migrations/0004_auto_20160808_1557.py b/common/migrations/0004_auto_20160808_1557.py new file mode 100644 index 0000000..7475fcd --- /dev/null +++ b/common/migrations/0004_auto_20160808_1557.py @@ -0,0 +1,29 @@ +# -*- coding: utf-8 -*- +# Generated by Django 1.9.7 on 2016-08-08 12:57 +from __future__ import unicode_literals + +import datetime +from django.db import migrations, models +from django.utils.timezone import utc + + +class Migration(migrations.Migration): + + dependencies = [ + ('common', '0003_auto_20160729_1747'), + ] + + operations = [ + migrations.AddField( + model_name='settings', + name='recalculation_rating_time', + field=models.TimeField(default=datetime.datetime(2016, 8, 8, 12, 57, 41, 160156, tzinfo=utc)), + preserve_default=False, + ), + migrations.AddField( + model_name='settings', + name='recalculation_spec_time', + field=models.TimeField(default=datetime.datetime(2016, 8, 8, 12, 57, 52, 905906, tzinfo=utc)), + preserve_default=False, + ), + ] diff --git a/common/models.py b/common/models.py index 95ca414..6557b55 100644 --- a/common/models.py +++ b/common/models.py @@ -40,6 +40,8 @@ class Settings(models.Model): document_send_email = models.EmailField(max_length=100, default="muhtarzubanchi05@gmail.com") document_send_description = models.TextField(blank=True) document_send_time_remove = models.IntegerField(default=14) + recalculation_spec_time = models.TimeField() + recalculation_rating_time = models.TimeField() def __str__(self): return 'Настройки сайта' diff --git a/projects/forms.py b/projects/forms.py index b678c56..2f2bfb0 100644 --- a/projects/forms.py +++ b/projects/forms.py @@ -235,6 +235,15 @@ class CustomerProjectTrashForm(forms.Form): self.fields['pk'].queryset = self.req.user.projects.filter(state='active') +class ContractorPortfolioTrashForm(forms.Form): + pk = forms.ModelChoiceField(queryset=Portfolio.objects.none()) + + def __init__(self, *args, **kwargs): + self.request = kwargs.pop('request') + super().__init__(*args, **kwargs) + self.fields['pk'].queryset = self.request.user.portfolios.all() + + class CustomerProjectRestoreForm(forms.Form): pk = forms.ModelChoiceField(queryset=Project.objects.none()) diff --git a/projects/templatetags/__init__.py b/projects/templatetags/__init__.py deleted file mode 100644 index e69de29..0000000 diff --git a/projects/templatetags/projects_tags.py b/projects/templatetags/projects_tags.py deleted file mode 100644 index b82c290..0000000 --- a/projects/templatetags/projects_tags.py +++ /dev/null @@ -1,10 +0,0 @@ -from django import template - -register = template.Library() - -@register.inclusion_tag("templatetags/ratings_widget.html", takes_context=True) -def ratings_widget(context, user_id, class_name=None): - ratings = user_id - return { - 'ratings': ratings, - } diff --git a/projects/urls.py b/projects/urls.py index 4e3a9b1..c16f654 100644 --- a/projects/urls.py +++ b/projects/urls.py @@ -14,6 +14,7 @@ from .views import ( ProjectComparisonView, ProjectFilterView, ProjectDetailWithContractorAnswerView, + ContractorPortfolioTrashView, ) app_name = 'projects' @@ -25,6 +26,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'^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 d7cecf1..5849bf0 100644 --- a/projects/views.py +++ b/projects/views.py @@ -15,7 +15,7 @@ import pydash as _; _.map = _.map_; _.filter = _.filter_ import re from .mixins import LastAccessMixin -from .models import Project, ProjectFile, Portfolio, Candidate, Answer, AnswerFile, Realty, Order +from .models import Project, ProjectFile, Portfolio, PortfolioPhoto,Candidate, Answer, AnswerFile, Realty, Order from archilance.mixins import BaseMixin from users.models import User from work_sell.models import Picture @@ -31,6 +31,7 @@ from .forms import ( ProjectFilterForm, ProjectFilterRealtyForm, RealtyForm, + ContractorPortfolioTrashForm, ) @@ -353,6 +354,21 @@ class CustomerProjectEditView(BaseMixin, View): return render(request, self.template_name, context) +class ContractorPortfolioTrashView(View): + form_class = ContractorPortfolioTrashForm + + def post(self,request, *args, **kwargs): + form = self.form_class(_.merge({}, request.POST, kwargs), request=request) + if form.is_valid(): + portfolio = form.cleaned_data.get('pk') + portfolio.delete() + messages.info(request, 'Портфолио удален') + else: + messages.info(request, 'Произошла ошибка:
{msg}
'.format(msg=pformat(form.errors))) + + redirect_to = request.POST.get('next') + return redirect(redirect_to) + class CustomerProjectTrashView(View): form_class = CustomerProjectTrashForm @@ -483,4 +499,10 @@ class ContractorPortfolioUpdateView(UpdateView): return reverse('proje') +from django.views.generic import DeleteView +class PortfolioDelete(DeleteView): + model = Portfolio + success_url = reverse_lazy('users:contractor-profile') + + # import code; code.interact(local=dict(globals(), **locals())) diff --git a/ratings/management/commands/recalculation_rating.py b/ratings/management/commands/recalculation_rating.py index b1a6e00..d9383eb 100644 --- a/ratings/management/commands/recalculation_rating.py +++ b/ratings/management/commands/recalculation_rating.py @@ -1,10 +1,23 @@ from django.core.management import BaseCommand +from django.db.models import Sum from specializations.models import Specialization from ratings.models import HistoryRating -from users.models import User +from users.models import User,Team class Command(BaseCommand): + def handle(self, *args, **options): - contractors = User.contractor_objects.all() + users = User.objects.filter(is_superuser=False) + for user in users: + current_rating_info = HistoryRating.objects.filter(user_id=user.pk).aggregate(Sum('rating')) + current_rating = current_rating_info['rating__sum'] or 0 + user.rating = current_rating + user.save() + teams = Team.objects.all() + for team in teams: + current_rating_info = HistoryRating.objects.filter(team_id=team.pk).aggregate(Sum('rating')) + current_rating = current_rating_info['rating__sum'] or 0 + team.rating = current_rating + team.save() diff --git a/ratings/management/commands/recalculation_spec.py b/ratings/management/commands/recalculation_spec.py index d3fcf81..518ffa2 100644 --- a/ratings/management/commands/recalculation_spec.py +++ b/ratings/management/commands/recalculation_spec.py @@ -1,24 +1,35 @@ from django.core.management import BaseCommand from specializations.models import Specialization from ratings.models import SpecializationRating -from users.models import User +from users.models import User, Team class Command(BaseCommand): def handle(self, *args, **options): - SpecializationRating.objects.all().delete() - contractors = User.contractor_objects.order_by('-contractor_rating') - specializations = Specialization.objects.all() - for spec in specializations: - i = 0 - for contractor in contractors: - if spec in contractor.contractor_specializations.all(): - i += 1 - spec_rating = SpecializationRating() - spec_rating.position = i - spec_rating.user = contractor - spec_rating.specialization = spec - spec_rating.save() + users = User.objects.values('pk', 'rating').filter(is_superuser=False).order_by('-rating') + teams = Team.objects.values('pk', 'rating').order_by('-rating') + result_list = [] - print('The End') + for user in users: + result_list.append([user['rating'], 'user', user['pk']]) + + for team in teams: + result_list.append([team['rating'], 'team',team['pk'] ]) + + print(sorted(result_list)) + # SpecializationRating.objects.all().delete() + # contractors = User.contractor_objects.order_by('-rating') + # specializations = Specialization.objects.all() + # for spec in specializations: + # i = 0 + # for contractor in contractors: + # if spec in contractor.contractor_specializations.all(): + # i += 1 + # spec_rating = SpecializationRating() + # spec_rating.position = i + # spec_rating.user = contractor + # spec_rating.specialization = spec + # spec_rating.save() + # + # print('The End') diff --git a/ratings/models.py b/ratings/models.py index e5dd042..375907b 100644 --- a/ratings/models.py +++ b/ratings/models.py @@ -12,7 +12,7 @@ class HistoryRating(models.Model): description = models.TextField(blank=True) def __str__(self): - return self.rating + return '{0}'.format(self.rating) class Meta: verbose_name = 'История рейтинга' diff --git a/projects/templates/templatetags/ratings_widget.html b/ratings/templates/templatetags/ratings_widget.html similarity index 52% rename from projects/templates/templatetags/ratings_widget.html rename to ratings/templates/templatetags/ratings_widget.html index e689a34..fe7f745 100644 --- a/projects/templates/templatetags/ratings_widget.html +++ b/ratings/templates/templatetags/ratings_widget.html @@ -10,16 +10,3 @@ - -{##} - diff --git a/ratings/templatetags/specializtions_tags.py b/ratings/templatetags/specializtions_tags.py index f446cb7..65649b0 100644 --- a/ratings/templatetags/specializtions_tags.py +++ b/ratings/templatetags/specializtions_tags.py @@ -1,7 +1,7 @@ from django import template from archilance import util -from users.models import User +from users.models import User, Team from ratings.models import SpecializationRating register = template.Library() @@ -14,3 +14,26 @@ def specialization_widget(context, user_id): 'specializations': specializations, 'user_id': user_id, } + +def specialization_team_widget(context, team_id): + team_id = int(team_id) + specializations = [] + return { + 'specializations': specializations, + } + + + +@register.inclusion_tag("templatetags/ratings_widget.html", takes_context=True) +def ratings_widget(context, user_id, class_name=None): + ratings = User.objects.get(pk=user_id).rating + return { + 'ratings': ratings, + } + +@register.inclusion_tag("templatetags/ratings_widget.html", takes_context=True) +def ratings_team_widget(context, team_id): + ratings = Team.objects.get(pk=team_id).rating + return { + 'ratings': ratings, + } diff --git a/templates/partials/header.html b/templates/partials/header.html index 63a2064..253d922 100644 --- a/templates/partials/header.html +++ b/templates/partials/header.html @@ -7,7 +7,7 @@
- + {% if request.user.is_authenticated %}
{% endif %} - + {% if request.user.is_authenticated %}
- +
-
- + {% if request.user.is_contractor %}
diff --git a/users/admin.py b/users/admin.py index 1890f01..ca8f03e 100644 --- a/users/admin.py +++ b/users/admin.py @@ -5,13 +5,20 @@ from .models import User, Team, UserFinancialInfo, ContractorResume, ContractorR class UserAdmin(admin.ModelAdmin): readonly_fields = ('pk',) - list_display = ('username', 'email', 'get_groups', 'cro', 'is_active',) + list_display = ('username', 'email', 'get_groups', 'cro', 'is_active', 'rating',) + ordering = ('-rating',) def get_groups(self, obj): return ', '.join(g.name for g in obj.groups.all()) + +class TeamAdmin(admin.ModelAdmin): + list_display = ('name', 'rating', 'owner',) + ordering = ('-rating',) + + admin.site.register(User, UserAdmin) admin.site.register(UserFinancialInfo) -admin.site.register(Team) +admin.site.register(Team, TeamAdmin) admin.site.register(ContractorResume) admin.site.register(ContractorResumeFiles) diff --git a/users/migrations/0007_auto_20160808_1557.py b/users/migrations/0007_auto_20160808_1557.py new file mode 100644 index 0000000..95cf4cc --- /dev/null +++ b/users/migrations/0007_auto_20160808_1557.py @@ -0,0 +1,25 @@ +# -*- coding: utf-8 -*- +# Generated by Django 1.9.7 on 2016-08-08 12:57 +from __future__ import unicode_literals + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('users', '0006_auto_20160805_1442'), + ] + + operations = [ + migrations.RenameField( + model_name='user', + old_name='contractor_rating', + new_name='rating', + ), + migrations.AddField( + model_name='team', + name='rating', + field=models.FloatField(default=0.0), + ), + ] diff --git a/users/models.py b/users/models.py index 9dd7cd0..a3d995c 100644 --- a/users/models.py +++ b/users/models.py @@ -120,7 +120,7 @@ class User(AbstractBaseUser, PermissionsMixin): avatar = models.ImageField(upload_to='users/avatars/', blank=True) contractor_answers = GenericRelation('projects.Answer') - contractor_rating = models.FloatField(default=0.0) + rating = models.FloatField(default=0.0) 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) @@ -189,6 +189,7 @@ class Team(models.Model): owner = models.OneToOneField(User, related_name='team', blank=True, null=True) specializations = TreeManyToManyField(Specialization, related_name='teams', blank=True) contractors = models.ManyToManyField(User, limit_choices_to={'groups__name': 'Исполнители'}, related_name ='teams', blank=True) + rating = models.FloatField(default=0.0) def __str__(self): return self.name diff --git a/users/templates/contractor_office.html b/users/templates/contractor_office.html index debb866..803aac4 100644 --- a/users/templates/contractor_office.html +++ b/users/templates/contractor_office.html @@ -1,87 +1,98 @@ {% extends 'partials/base.html' %} {% load staticfiles %} +{% load specializtions_tags %} {% load thumbnail %} {% block content %} {% include 'partials/header.html' %} - -
-
-
-

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

-
- -
- +
+ +
+
+ + + {% if not contractor.is_owner_team %} + {% endif %} -
- - - -
- -
-
-
+
+ + + +
+ +
+
+
{% thumbnail contractor.avatar "265x264" crop="center" as im %} @@ -89,219 +100,183 @@ {% endthumbnail %}
- +
- -
-
-

- {{ contractor.team }} -

-

Россия, Москва

-{# #} - - - -
Свободен
- написать сообщение -
- -
-
-

- Специализации: -

-
- Интерьеры - 2-й -
-
- Визуализация/3D - 45-й -
-
- Экстерьеры - 10-й -
-
- Архитектура - 3-й -
-
- 3D Моделирование - 100-й -
-
-
- - -
- - - - - - -
-
- -
- {% for p in portfolios %} + +
-
-
-
-
-
-
-

{{ p.name }}

-
- -
- -
-
-
- -
-
-
+

+ {{ contractor.team }} +

+

Россия, Москва

+ {# #} + + + +
Свободен
+ написать сообщение
- {% endfor %} +
+ {% specialization_widget contractor.pk %}
-
-
- показать еще +
+ {% if contractor.team %} + {% ratings_team_widget contractor.team.pk %} + {% endif %} +
+
+

Есть допуск СРО

-
-
- {% for ws in work_sells %} -
-
-
-
+ + +
+
+ +
+ {% for p in portfolios %} +
+
+
+
+
-
-
- {{ ws.budget }} +
+

{{ p.name }}

+
+ +
+ +
+
+
+ +
-
-

{{ ws }}

+ {% endfor %} -
+
+ +
+ - {% endfor %} +
-
-
- показать еще + +
+ +
+ {% for ws in work_sells %} +
+
+
+
+
+
+
+ {{ ws.budget }} +
+
+
+
+

{{ ws }}

+ +
+
+ {% endfor %} +
+
-
-
-
-
-

- Иванов Петр Иванович -

+
+
+
+

+ Иванов Петр Иванович +

Безопасная сделка - -

- Lorem ipsum dolor sit amet, consectetur adipiscing elit. Aenean euismod bibendum +

+

+ Lorem ipsum dolor sit amet, consectetur adipiscing elit. Aenean euismod bibendum -

+

+
-
-
- - {% include 'partials/footer.html' %} -
-
+
+ + {% include 'partials/footer.html' %} +
+
{% endblock %} diff --git a/users/templates/contractor_profile.html b/users/templates/contractor_profile.html index bdae073..38d52e8 100644 --- a/users/templates/contractor_profile.html +++ b/users/templates/contractor_profile.html @@ -1,6 +1,5 @@ {% extends 'partials/base.html' %} -{% load projects_tags %} {% load specializtions_tags %} {% load thumbnail %} @@ -29,7 +28,7 @@ {% endif %} - {% if contractor.pk != user.id %} + {% if contractor.pk != request.user.pk and request.user.is_contractor %}
  • @@ -37,22 +36,26 @@
  • + {% endif %} + {% if contractor.pk != request.user.pk %}
  • - + написать сообщение
  • + {% endif %} + {% if request.user.is_customer %}
  • предложить заказ
  • - {% endif %} +
    @@ -147,7 +150,12 @@
    - +
    + {% csrf_token %} + + +
    +
    @@ -188,13 +196,17 @@ {% for ws in user.work_sell.all %}
    -
    + + {% thumbnail ws.get_cover "224x224" crop="center" as im %} +
    + {% endthumbnail %} +
    {{ ws.budget }} +
    @@ -207,7 +219,12 @@
    - +
    + {% csrf_token %} + + +
    +
    diff --git a/users/templates/user_profile_edit.html b/users/templates/user_profile_edit.html index c3ec3e0..7086ada 100644 --- a/users/templates/user_profile_edit.html +++ b/users/templates/user_profile_edit.html @@ -22,7 +22,9 @@
    - profile-image + {% if form.avatar.value %} + profile-image + {% endif %}