#ARC-10 Add management for ratings

remotes/origin/setup
Mukhtar 10 years ago
parent ed2aabc786
commit 2cb80e7f1d
  1. 2
      archilance/settings/base.py
  2. 4
      chat/testapp.py
  3. 7
      chat/views.py
  4. 29
      common/migrations/0004_auto_20160808_1557.py
  5. 2
      common/models.py
  6. 9
      projects/forms.py
  7. 0
      projects/templatetags/__init__.py
  8. 10
      projects/templatetags/projects_tags.py
  9. 2
      projects/urls.py
  10. 24
      projects/views.py
  11. 17
      ratings/management/commands/recalculation_rating.py
  12. 41
      ratings/management/commands/recalculation_spec.py
  13. 2
      ratings/models.py
  14. 13
      ratings/templates/templatetags/ratings_widget.html
  15. 25
      ratings/templatetags/specializtions_tags.py
  16. 37
      templates/partials/header.html
  17. 11
      users/admin.py
  18. 25
      users/migrations/0007_auto_20160808_1557.py
  19. 3
      users/models.py
  20. 465
      users/templates/contractor_office.html
  21. 33
      users/templates/contractor_profile.html
  22. 4
      users/templates/user_profile_edit.html
  23. 7
      users/templates/worksell_create_form.html
  24. 2
      users/urls.py
  25. 17
      users/views.py
  26. 10
      work_sell/forms.py
  27. 4
      work_sell/models.py
  28. 8
      work_sell/templates/worksells_list.html
  29. 2
      work_sell/urls.py
  30. 46
      work_sell/views.py

@ -111,7 +111,7 @@ WSGI_APPLICATION = 'archilance.wsgi.application'
DATABASES = { DATABASES = {
'default': { 'default': {
'ENGINE': 'django.db.backends.postgresql_psycopg2', 'ENGINE': 'django.db.backends.postgresql_psycopg2',
'NAME': 'archilance', 'NAME': 'archilance2',
'USER': 'postgres', 'USER': 'postgres',
'PASSWORD': 'postgres', 'PASSWORD': 'postgres',
'HOST': 'localhost', 'HOST': 'localhost',

@ -66,7 +66,7 @@ class ChatHandler(websocket.WebSocketHandler):
order_value = "NULL" if order_id is None else order_id 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) " \ 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) yield self.db.execute(insert_sql)
waiters = tuple(w for c, w in self.waiters if c == recipent_id or c == sender_id) 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() ioloop = IOLoop.instance()
application.db = momoko.Pool( application.db = momoko.Pool(
dsn='dbname=archilance user=postgres password=postgres host=localhost', dsn='dbname=archilance2 user=postgres password=postgres host=localhost',
size=1, size=1,
ioloop=ioloop, ioloop=ioloop,
) )

@ -12,6 +12,8 @@ class ChatUserView(View):
template_name = '' template_name = ''
def get(self, request, *args, **kwargs): 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(): if request.user.is_authenticated() and request.user.is_customer():
customer_contacts = Message.objects.values_list('sender_id', 'recipent_id'). \ 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() 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) users_ids.append(a)
if b != request.user.pk: if b != request.user.pk:
users_ids.append(b) 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) contacts_users = User.objects.filter(pk__in=users_ids)
chat_messages = Message.objects.filter(Q(sender=request.user.pk) | Q(recipent=request.user.pk)) 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) users_ids.append(a)
if b != request.user.pk: if b != request.user.pk:
users_ids.append(b) users_ids.append(b)
if user_id:
users_ids.append(int(user_id))
contacts_users = User.objects.filter(pk__in=users_ids) 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( chat_messages = Message.objects.filter(Q(sender=request.user.pk) | Q(recipent=request.user.pk)).order_by(
'created') 'created')

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

@ -40,6 +40,8 @@ class Settings(models.Model):
document_send_email = models.EmailField(max_length=100, default="muhtarzubanchi05@gmail.com") document_send_email = models.EmailField(max_length=100, default="muhtarzubanchi05@gmail.com")
document_send_description = models.TextField(blank=True) document_send_description = models.TextField(blank=True)
document_send_time_remove = models.IntegerField(default=14) document_send_time_remove = models.IntegerField(default=14)
recalculation_spec_time = models.TimeField()
recalculation_rating_time = models.TimeField()
def __str__(self): def __str__(self):
return 'Настройки сайта' return 'Настройки сайта'

@ -235,6 +235,15 @@ class CustomerProjectTrashForm(forms.Form):
self.fields['pk'].queryset = self.req.user.projects.filter(state='active') 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): class CustomerProjectRestoreForm(forms.Form):
pk = forms.ModelChoiceField(queryset=Project.objects.none()) pk = forms.ModelChoiceField(queryset=Project.objects.none())

@ -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,
}

@ -14,6 +14,7 @@ from .views import (
ProjectComparisonView, ProjectComparisonView,
ProjectFilterView, ProjectFilterView,
ProjectDetailWithContractorAnswerView, ProjectDetailWithContractorAnswerView,
ContractorPortfolioTrashView,
) )
app_name = 'projects' app_name = 'projects'
@ -25,6 +26,7 @@ urlpatterns = [
urls.url(r'^create/$', CustomerProjectCreateView.as_view(), name='customer-project-create'), urls.url(r'^create/$', CustomerProjectCreateView.as_view(), name='customer-project-create'),
urls.url(r'^(?P<pk>\d+)/edit/$', CustomerProjectEditView.as_view(), name='customer-project-edit'), urls.url(r'^(?P<pk>\d+)/edit/$', CustomerProjectEditView.as_view(), name='customer-project-edit'),
urls.url(r'^(?P<pk>\d+)/trash/$', CustomerProjectTrashView.as_view(), name='customer-project-trash'), urls.url(r'^(?P<pk>\d+)/trash/$', CustomerProjectTrashView.as_view(), name='customer-project-trash'),
urls.url(r'^portfolio/(?P<pk>\d+)/trash/$', ContractorPortfolioTrashView.as_view(), name='contractor-portfolio-trash'),
urls.url(r'^(?P<pk>\d+)/restore/$', CustomerProjectRestoreView.as_view(), name='customer-project-restore'), urls.url(r'^(?P<pk>\d+)/restore/$', CustomerProjectRestoreView.as_view(), name='customer-project-restore'),
urls.url(r'^(?P<pk>\d+)/delete/$', CustomerProjectDeleteView.as_view(), name='customer-project-delete'), urls.url(r'^(?P<pk>\d+)/delete/$', CustomerProjectDeleteView.as_view(), name='customer-project-delete'),

@ -15,7 +15,7 @@ import pydash as _; _.map = _.map_; _.filter = _.filter_
import re import re
from .mixins import LastAccessMixin 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 archilance.mixins import BaseMixin
from users.models import User from users.models import User
from work_sell.models import Picture from work_sell.models import Picture
@ -31,6 +31,7 @@ from .forms import (
ProjectFilterForm, ProjectFilterForm,
ProjectFilterRealtyForm, ProjectFilterRealtyForm,
RealtyForm, RealtyForm,
ContractorPortfolioTrashForm,
) )
@ -353,6 +354,21 @@ class CustomerProjectEditView(BaseMixin, View):
return render(request, self.template_name, context) 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, 'Произошла ошибка: <pre>{msg}</pre>'.format(msg=pformat(form.errors)))
redirect_to = request.POST.get('next')
return redirect(redirect_to)
class CustomerProjectTrashView(View): class CustomerProjectTrashView(View):
form_class = CustomerProjectTrashForm form_class = CustomerProjectTrashForm
@ -483,4 +499,10 @@ class ContractorPortfolioUpdateView(UpdateView):
return reverse('proje') 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())) # import code; code.interact(local=dict(globals(), **locals()))

@ -1,10 +1,23 @@
from django.core.management import BaseCommand from django.core.management import BaseCommand
from django.db.models import Sum
from specializations.models import Specialization from specializations.models import Specialization
from ratings.models import HistoryRating from ratings.models import HistoryRating
from users.models import User from users.models import User,Team
class Command(BaseCommand): class Command(BaseCommand):
def handle(self, *args, **options): 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()

@ -1,24 +1,35 @@
from django.core.management import BaseCommand from django.core.management import BaseCommand
from specializations.models import Specialization from specializations.models import Specialization
from ratings.models import SpecializationRating from ratings.models import SpecializationRating
from users.models import User from users.models import User, Team
class Command(BaseCommand): class Command(BaseCommand):
def handle(self, *args, **options): def handle(self, *args, **options):
SpecializationRating.objects.all().delete() users = User.objects.values('pk', 'rating').filter(is_superuser=False).order_by('-rating')
contractors = User.contractor_objects.order_by('-contractor_rating') teams = Team.objects.values('pk', 'rating').order_by('-rating')
specializations = Specialization.objects.all() result_list = []
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') 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')

@ -12,7 +12,7 @@ class HistoryRating(models.Model):
description = models.TextField(blank=True) description = models.TextField(blank=True)
def __str__(self): def __str__(self):
return self.rating return '{0}'.format(self.rating)
class Meta: class Meta:
verbose_name = 'История рейтинга' verbose_name = 'История рейтинга'

@ -10,16 +10,3 @@
</a> </a>
</li> </li>
</ul> </ul>
{#<ul class="rettList restList2">#}
{# <li>Рейтинг: <span> 1245</span></li>#}
{# <li>Безопасные сделки: <span> 5</span></li>#}
{# <li>#}
{# <a href="javascript:void(0)">Отзывы:#}
{# <span> + 385</span>#}
{# <small> 0</small>#}
{# <mark> - 0</mark>#}
{# </a>#}
{# </li>#}
{# </ul>#}

@ -1,7 +1,7 @@
from django import template from django import template
from archilance import util from archilance import util
from users.models import User from users.models import User, Team
from ratings.models import SpecializationRating from ratings.models import SpecializationRating
register = template.Library() register = template.Library()
@ -14,3 +14,26 @@ def specialization_widget(context, user_id):
'specializations': specializations, 'specializations': specializations,
'user_id': user_id, '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,
}

@ -7,7 +7,7 @@
<div class="col-lg-3"> <div class="col-lg-3">
<div class="logo" onClick="window.location='/'"></div> <div class="logo" onClick="window.location='/'"></div>
</div> </div>
{% if request.user.is_authenticated %} {% if request.user.is_authenticated %}
<div class="col-lg-7"> <div class="col-lg-7">
<ul class="mainMenu"> <ul class="mainMenu">
@ -15,13 +15,13 @@
<a href="{% url 'projects:project-filter' %}">Биржа проектов</a> <a href="{% url 'projects:project-filter' %}">Биржа проектов</a>
<span></span> <span></span>
</li> </li>
{% if request.user.is_contractor %} {% if request.user.is_contractor %}
<li class="officeList icon_tml"> <li class="officeList icon_tml">
<a href="{% url 'users:contractor-office' pk=request.user.pk %}">Мой офис</a> <a href="{% url 'users:contractor-office' pk=request.user.pk %}">Мой офис</a>
<span></span> <span></span>
</li> </li>
{% endif%} {% endif %}
{% if request.user.is_customer %} {% if request.user.is_customer %}
<li class="icon_tm2"> <li class="icon_tm2">
@ -29,7 +29,7 @@
<span></span> <span></span>
</li> </li>
<li class="icon_tm3"> <li class="icon_tm3">
<a href="#">Работы на продажу</a> <a href="{% url 'work_sell:list' %}">Работы на продажу</a>
<span></span> <span></span>
</li> </li>
{% endif %} {% endif %}
@ -53,28 +53,37 @@
</ul> </ul>
</div> </div>
{% endif %} {% endif %}
{% if request.user.is_authenticated %} {% if request.user.is_authenticated %}
<div class="col-lg-2"> <div class="col-lg-2">
<div class="imgProfile"> <div class="imgProfile">
{% if request.user.is_contractor %} {% if request.user.is_contractor %}
<a href="{% url 'users:contractor-profile' pk=request.user.pk %}"> <a href="{% url 'users:contractor-profile' pk=request.user.pk %}">
{% thumbnail request.user.avatar "75x75" crop="center" as im %} {% if request.user.avatar %}
<img src="{{ im.url }}" alt="profile-image"> {% thumbnail request.user.avatar "75x75" crop="center" as im %}
{% endthumbnail %} <img src="{{ im.url }}" alt="profile-image">
{% endthumbnail %}
{% else %}
<img src="{% static 'img/profile.jpg' %}" alt="profile-image">
{% endif %}
</a> </a>
{% elif request.user.is_customer %} {% elif request.user.is_customer %}
<a href="{% url 'users:customer-profile-open-projects' pk=request.user.pk %}"> <a href="{% url 'users:customer-profile-open-projects' pk=request.user.pk %}">
{% thumbnail request.user.avatar "75x75" crop="center" as im %} {% if request.user.avatar %}
<img src="{{ im.url }}" alt="profile-image"> {% thumbnail request.user.avatar "75x75" crop="center" as im %}
{% endthumbnail %} <img src="{{ im.url }}" alt="profile-image">
{% endthumbnail %}
{% else %}
<img src="{% static 'img/profile.jpg' %}" alt="profile-image">
{% endif %}
</a> </a>
{% endif %} {% endif %}
</div> </div>
<div class="infoProfile disTab"> <div class="infoProfile disTab">
<div class="btn-group" role="group"> <div class="btn-group" role="group">
<button type="button" class="btn btn-default dropdown-toggle" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false"> <button type="button" class="btn btn-default dropdown-toggle" data-toggle="dropdown"
aria-haspopup="true" aria-expanded="false">
<span class="glyphicon glyphicon-menu-hamburger" aria-hidden="true"></span> <span class="glyphicon glyphicon-menu-hamburger" aria-hidden="true"></span>
</button> </button>
<ul class="dropdown-menu menu-drop-new"> <ul class="dropdown-menu menu-drop-new">
@ -117,7 +126,7 @@
</ul> </ul>
</div> </div>
</div> </div>
{% if request.user.is_contractor %} {% if request.user.is_contractor %}
<div class="rating"> <div class="rating">
<div class="ratingInset"></div> <div class="ratingInset"></div>

@ -5,13 +5,20 @@ from .models import User, Team, UserFinancialInfo, ContractorResume, ContractorR
class UserAdmin(admin.ModelAdmin): class UserAdmin(admin.ModelAdmin):
readonly_fields = ('pk',) 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): def get_groups(self, obj):
return ', '.join(g.name for g in obj.groups.all()) 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(User, UserAdmin)
admin.site.register(UserFinancialInfo) admin.site.register(UserFinancialInfo)
admin.site.register(Team) admin.site.register(Team, TeamAdmin)
admin.site.register(ContractorResume) admin.site.register(ContractorResume)
admin.site.register(ContractorResumeFiles) admin.site.register(ContractorResumeFiles)

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

@ -120,7 +120,7 @@ class User(AbstractBaseUser, PermissionsMixin):
avatar = models.ImageField(upload_to='users/avatars/', blank=True) avatar = models.ImageField(upload_to='users/avatars/', blank=True)
contractor_answers = GenericRelation('projects.Answer') 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_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)
@ -189,6 +189,7 @@ class Team(models.Model):
owner = models.OneToOneField(User, related_name='team', blank=True, null=True) owner = models.OneToOneField(User, related_name='team', blank=True, null=True)
specializations = TreeManyToManyField(Specialization, related_name='teams', blank=True) specializations = TreeManyToManyField(Specialization, related_name='teams', blank=True)
contractors = models.ManyToManyField(User, limit_choices_to={'groups__name': 'Исполнители'}, 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): def __str__(self):
return self.name return self.name

@ -1,87 +1,98 @@
{% extends 'partials/base.html' %} {% extends 'partials/base.html' %}
{% load staticfiles %} {% load staticfiles %}
{% load specializtions_tags %}
{% load thumbnail %} {% load thumbnail %}
{% block content %} {% block content %}
{% include 'partials/header.html' %} {% include 'partials/header.html' %}
<div class="container mainScore"> <div class="container mainScore" xmlns="http://www.w3.org/1999/html">
<div class="row"> <div class="row">
<div class="col-lg-12"> <div class="col-lg-12">
<p class="titleScore">Личный кабинет</p> <p class="titleScore">Личный кабинет</p>
</div> </div>
<div class="profileTabs"> <div class="profileTabs">
<ul class="nav nav-tabs nav-justified"> <ul class="nav nav-tabs nav-justified">
<li role="presentation"> <li role="presentation">
<a href="#">Поиск исполнителей</a> <a href="#">Поиск исполнителей</a>
</li> </li>
<li role="presentation" class="active"> <li role="presentation" class="active">
<a href="#">Мои группы</a> <a href="#">Мои группы</a>
<div class="roundsCount"> <div class="roundsCount">
<div class="countR">1</div> <div class="countR">1</div>
<div class="countG">2</div> <div class="countG">2</div>
</div> </div>
</li> </li>
<li role="presentation"> <li role="presentation">
<a href="#">Открытые проекты</a> <a href="#">Открытые проекты</a>
<span class="desPresent"> <span class="desPresent">
в процессе обсуждения в процессе обсуждения
</span> </span>
<div class="roundsCount"> <div class="roundsCount">
<div class="countR">1</div> <div class="countR">1</div>
<div class="countG">2</div> <div class="countG">2</div>
</div> </div>
</li> </li>
<li role="presentation"> <li role="presentation">
<a href="#">Проекты в работе</a> <a href="#">Проекты в работе</a>
<div class="roundsCount"> <div class="roundsCount">
<div class="countG">2</div> <div class="countG">2</div>
</div> </div>
</li> </li>
</ul> </ul>
</div> </div>
<div class="buttonGP disTab"> <div class="buttonGP disTab">
<div class="btn-group valProject2 val-pro3" role="group" aria-label="..."> <div class="btn-group valProject2 val-pro3" role="group" aria-label="...">
<button type="button" class="btn btn-default"> <button type="button" class="btn btn-default">
Группа 1 Группа 1
<span><mark>7</mark></span> <span><mark>7</mark></span>
</button> </button>
{% if contractor.is_owner_team %}
<button type="button" class="btn btn-default add-group" data-toggle="modal" data-target="#myModal"> {% if not contractor.is_owner_team %}
+ Добавить группу <button type="button" class="btn btn-default add-group" data-toggle="modal"
</button> data-target="#myModal">
+ Добавить группу
</button>
{% endif %} {% endif %}
</div> </div>
<!-- Modal --> <!-- Modal -->
<div class="modal fade" id="myModal" tabindex="-1" role="dialog" aria-labelledby="myModalLabel"> <div class="modal fade" id="myModal" tabindex="-1" role="dialog" aria-labelledby="myModalLabel">
<div class="modal-dialog" role="document"> <div class="modal-dialog" role="document">
<div class="modal-content"> <div class="modal-content">
<div class="modal-header"> <div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">&times;</span></button> <button type="button" class="close" data-dismiss="modal" aria-label="Close"><span
<h4 class="modal-title" id="myModalLabel">Добавление новой группы</h4> aria-hidden="true">&times;</span></button>
</div> <h4 class="modal-title" id="myModalLabel">Добавление новой группы</h4>
<div class="modal-body"> </div>
{{ form_team }} <div class="modal-body">
</div> <form method="post" action="{% url 'users:team-create' %}">{% csrf_token %}
<div class="modal-footer"> <div class="textAreaBlock2 text-nn box-sizing disTab">
<button type="button" class="btn btn-default" data-dismiss="modal">Закрыть</button> <p>Название <span style="color: red">{{ form_team.name.errors.as_text }}</span></p>
<button type="button" class="btn btn-primary">Сохранить</button> <input type="text" class="box-sizing" name="{{ form_team.name.html_name }}">
</div> </div>
</div>
</div> </div>
</div> <div class="modal-footer">
</div> <button type="button" class="btn btn-default" data-dismiss="modal">Закрыть</button>
<button type="submit" class="btn btn-primary">Сохранить</button>
<div class="projectsBlock disTab">
<div class="col-lg-12"> </div>
<div class="col-lg-3 divCol3"> </form>
</div>
</div>
</div>
</div>
<div class="projectsBlock disTab">
<div class="col-lg-12">
<div class="col-lg-3 divCol3">
<div class="avatar"> <div class="avatar">
<div class="avatarInset"> <div class="avatarInset">
{% thumbnail contractor.avatar "265x264" crop="center" as im %} {% thumbnail contractor.avatar "265x264" crop="center" as im %}
@ -89,219 +100,183 @@
{% endthumbnail %} {% endthumbnail %}
</div> </div>
</div> </div>
<div class="menuUser disTab"> <div class="menuUser disTab">
<a href="javascript:void(0)" class="add-man"> <a href="javascript:void(0)" class="add-man">
добавить участника добавить участника
</a> </a>
<div class="block-users"> <div class="block-users">
<p>Состав группы</p> <p>Состав группы</p>
{% for p in participants %} {% for p in participants %}
<div class="message-new">
<div class="imgMess"> <div class="message-new">
{% thumbnail p.avatar "60x60" crop="center" as im %}
<img src="{{ im.url }}" alt="mess-image">
{% endthumbnail %}
</div>
<p class="nameMess"> <div class="imgMess">
<a href="#">{{ p.get_full_name }}</a> {% thumbnail p.avatar "60x60" crop="center" as im %}
</p> <img src="{{ im.url }}" alt="mess-image">
{% endthumbnail %}
<span>Программист</span> </div>
</div>
<p class="nameMess">
<a href="#">{{ p.get_full_name }}</a>
</p>
<span>Программист</span>
</div>
{% endfor %} {% endfor %}
</div> </div>
</div> </div>
</div> </div>
<div class="col-lg-9 divCol9"> <div class="col-lg-9 divCol9">
<div class="col-lg-4">
<p class="nameUser">
{{ contractor.team }}
</p>
<p class="cityUser">Россия, Москва</p>
{# <p class="navv">На сайте 8 лет и 3 месяца</p>#}
<p class="navv">На сайте {{ contractor.team.created }}</p>
<p class="navv">
Кол-во человек: <span>{{participants_count}}</span>
</p>
<p class="navv">
Выполненных проектов: <span>0</span>
</p>
<div class="statusUser st-new">Свободен</div>
<a href="javascript:void(0)" class="new-prop new-prop2 new-prop3">написать сообщение</a>
</div>
<div class="col-lg-4">
<div class="dashedCol4">
<p class="specUser">
Специализации:
</p>
<div class="insetSpec">
<span>Интерьеры</span>
<span>2-й</span>
</div>
<div class="insetSpec">
<span>Визуализация/3D</span>
<span>45-й</span>
</div>
<div class="insetSpec">
<span>Экстерьеры</span>
<span>10-й</span>
</div>
<div class="insetSpec">
<span>Архитектура</span>
<span>3-й</span>
</div>
<div class="insetSpec">
<span>3D Моделирование</span>
<span>100-й</span>
</div>
</div>
</div>
<div class="col-lg-4">
<ul class="rettList">
<li><a href="javascript:void(0)">Рейтинг: <span> 1245</span></a></li>
<li><a href="javascript:void(0)">Безопасные сделки: <span> 5</span></a></li>
<li>
<a href="javascript:void(0)">
Отзывы:
<span> + 385</span>
<small> 0</small>
<mark> - 0</mark>
</a>
</li>
</ul>
<div class="sroUser">
<div class="iconSRO"></div>
<p>Есть допуск СРО</p>
</div>
</div>
</div>
<div class="col-lg-9">
<div class="profileTabs2">
<ul class="nav nav-tabs nav-justified">
<li role="presentation" class="active">
<a href="#tab11" data-toggle="tab">Портфолио</a>
</li>
<li role="presentation">
<a href="#tab12" data-toggle="tab">Готовые проекты</a>
</li>
<li role="presentation">
<a href="#tab13" data-toggle="tab">Отзывы</a>
</li>
</ul>
</div>
</div>
<div class="tab-content">
<div id="tab11" class="tab-pane fade in active">
<div class="galleryWork2 disTab">
{% for p in portfolios %}
<div class="col-lg-4"> <div class="col-lg-4">
<div class="insetCol box-sizing disTab"> <p class="nameUser">
<div class="imgGal" {{ contractor.team }}
style="background:rgba(0, 0, 0, 0) url('{{ p.get_cover }}') no-repeat scroll center center / cover ;"> </p>
<div class="imgFigure"></div> <p class="cityUser">Россия, Москва</p>
</div> {# <p class="navv">На сайте 8 лет и 3 месяца</p>#}
</div> <p class="navv">На сайте {{ contractor.team.created }}</p>
<div class="insetCol2 box-sizing disTab"> <p class="navv">
<p>{{ p.name }}</p> Кол-во человек: <span>{{ participants_count }}</span>
<div class="buttonsImg" disTab> </p>
<a href="{% url 'projects:contractor-portfolio-edit' p.pk %}"> <p class="navv">
<div class="insetBI insetBI1"> Выполненных проектов: <span>0</span>
<i class="fa fa-pencil"></i> </p>
</div> <div class="statusUser st-new">Свободен</div>
</a> <a href="javascript:void(0)" class="new-prop new-prop2 new-prop3">написать сообщение</a>
<div class="insetBI insetBI2">
<i class="fa fa-times"></i>
</div>
</div>
</div>
</div> </div>
{% endfor %}
<div class="col-lg-4">
{% specialization_widget contractor.pk %}
</div> </div>
<div class="col-lg-9 col-lg-offset-3"> <div class="col-lg-4">
<div class="linkElse"> {% if contractor.team %}
<a href="javascript:void(0)" class="showElse">показать еще</a> {% ratings_team_widget contractor.team.pk %}
{% endif %}
<div class="sroUser">
<div class="iconSRO"></div>
<p>Есть допуск СРО</p>
</div> </div>
</div> </div>
</div> </div>
<div id="tab12" class="tab-pane fade">
<div class="galleryWork2 disTab"> <div class="col-lg-9">
{% for ws in work_sells %} <div class="profileTabs2">
<div class="col-lg-4"> <ul class="nav nav-tabs nav-justified">
<div class="insetCol box-sizing disTab"> <li role="presentation" class="active">
<div class="imgGal" <a href="#tab11" data-toggle="tab">Портфолио</a>
style="background:rgba(0, 0, 0, 0) url('/media/{{ ws.img }}') no-repeat scroll center center / cover ;"> </li>
<div class="imgFigure"></div> <li role="presentation">
<a href="#tab12" data-toggle="tab">Готовые проекты</a>
</li>
<li role="presentation">
<a href="#tab13" data-toggle="tab">Отзывы</a>
</li>
</ul>
</div>
</div>
<div class="tab-content">
<div id="tab11" class="tab-pane fade in active">
<div class="galleryWork2 disTab">
{% for p in portfolios %}
<div class="col-lg-4">
<div class="insetCol box-sizing disTab">
<div class="imgGal"
style="background:rgba(0, 0, 0, 0) url('{{ p.get_cover }}') no-repeat scroll center center / cover ;">
<div class="imgFigure"></div>
</div>
</div> </div>
<div class="cenaImg box-sizing"> <div class="insetCol2 box-sizing disTab">
<div class="cenaImgInset"> <p>{{ p.name }}</p>
{{ ws.budget }} <i class="fa fa-rub"></i> <div class="buttonsImg" disTab>
<a href="{% url 'projects:contractor-portfolio-edit' p.pk %}">
<div class="insetBI insetBI1">
<i class="fa fa-pencil"></i>
</div>
</a>
<div class="insetBI insetBI2">
<i class="fa fa-times"></i>
</div>
</div> </div>
</div> </div>
</div> </div>
<div class="insetCol2 box-sizing disTab"> {% endfor %}
<p>{{ ws }}</p>
</div> </div>
<div class="col-lg-9 col-lg-offset-3">
<div class="linkElse">
<a href="javascript:void(0)" class="showElse">показать еще</a>
</div> </div>
{% endfor %} </div>
</div> </div>
<div class="col-lg-9 col-lg-offset-3">
<div class="linkElse"> <div id="tab12" class="tab-pane fade">
<a href="javascript:void(0)" class="showElse">показать еще</a>
<div class="galleryWork2 disTab">
{% for ws in work_sells %}
<div class="col-lg-4">
<div class="insetCol box-sizing disTab">
<div class="imgGal"
style="background:rgba(0, 0, 0, 0) url('/media/{{ ws.img }}') no-repeat scroll center center / cover ;">
<div class="imgFigure"></div>
</div>
<div class="cenaImg box-sizing">
<div class="cenaImgInset">
{{ ws.budget }} <i class="fa fa-rub"></i>
</div>
</div>
</div>
<div class="insetCol2 box-sizing disTab">
<p>{{ ws }}</p>
</div>
</div>
{% endfor %}
</div>
<div class="col-lg-9 col-lg-offset-3">
<div class="linkElse">
<a href="javascript:void(0)" class="showElse">показать еще</a>
</div>
</div> </div>
</div> </div>
</div>
<div id="tab13" class="tab-pane fade"> <div id="tab13" class="tab-pane fade">
<div class="new-comm-44"> <div class="new-comm-44">
<div class="col-lg-12"> <div class="col-lg-12">
<p class="nameComm"> <p class="nameComm">
<a href="#">Иванов Петр Иванович</a> <a href="#">Иванов Петр Иванович</a>
</p> </p>
<span class="dateComm44"> <span class="dateComm44">
Безопасная сделка Безопасная сделка
</span> </span>
<div class="stars box-sizing"> <div class="stars box-sizing">
<span class="glyphicon glyphicon-star starAct" aria-hidden="true"></span> <span class="glyphicon glyphicon-star starAct" aria-hidden="true"></span>
<span class="glyphicon glyphicon-star starAct" aria-hidden="true"></span> <span class="glyphicon glyphicon-star starAct" aria-hidden="true"></span>
<span class="glyphicon glyphicon-star starAct" aria-hidden="true"></span> <span class="glyphicon glyphicon-star starAct" aria-hidden="true"></span>
<span class="glyphicon glyphicon-star" aria-hidden="true"></span> <span class="glyphicon glyphicon-star" aria-hidden="true"></span>
<span class="glyphicon glyphicon-star" aria-hidden="true"></span> <span class="glyphicon glyphicon-star" aria-hidden="true"></span>
<a href="#">положительный отзыв</a> <a href="#">положительный отзыв</a>
</div> </div>
<p class="textComm44"> <p class="textComm44">
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Aenean euismod bibendum Lorem ipsum dolor sit amet, consectetur adipiscing elit. Aenean euismod bibendum
</p> </p>
</div>
</div> </div>
</div> </div>
</div> </div>
</div> </div>
</div> </div>
</div>
{% include 'partials/footer.html' %}
{% include 'partials/footer.html' %} </div>
</div> </div>
</div>
{% endblock %} {% endblock %}

@ -1,6 +1,5 @@
{% extends 'partials/base.html' %} {% extends 'partials/base.html' %}
{% load projects_tags %}
{% load specializtions_tags %} {% load specializtions_tags %}
{% load thumbnail %} {% load thumbnail %}
@ -29,7 +28,7 @@
<span></span> <span></span>
</li> </li>
{% endif %} {% endif %}
{% if contractor.pk != user.id %} {% if contractor.pk != request.user.pk and request.user.is_contractor %}
<li class="icon_um2"> <li class="icon_um2">
<a href="javascript:void(0)"> <a href="javascript:void(0)">
@ -37,22 +36,26 @@
</a> </a>
<span></span> <span></span>
</li> </li>
{% endif %}
{% if contractor.pk != request.user.pk %}
<li class="icon_um3"> <li class="icon_um3">
<a href="javascript:void(0)"> <a href="{% url 'chat:chat-user' %}?user_id={{ contractor.pk }}">
написать сообщение написать сообщение
</a> </a>
<span></span> <span></span>
</li> </li>
{% endif %}
{% if request.user.is_customer %}
<li class="icon_um4"> <li class="icon_um4">
<a href="javascript:void(0)"> <a href="javascript:void(0)">
предложить заказ предложить заказ
</a> </a>
<span></span> <span></span>
</li> </li>
{% endif %} {% endif %}
</ul> </ul>
</div> </div>
</div> </div>
@ -147,7 +150,12 @@
</div> </div>
</a> </a>
<div class="insetBI insetBI2"> <div class="insetBI insetBI2">
<i class="fa fa-times"></i> <form action="{% url 'projects:contractor-portfolio-trash' pk=p.pk %}" method="POST" novalidate>
{% csrf_token %}
<input type="hidden" name="next" value="{{ request.path }}">
<a href="#" onclick="$(this).closest('form').submit(); return false"><i class="fa fa-times"></i></a>
</form>
</div> </div>
</div> </div>
</div> </div>
@ -188,13 +196,17 @@
{% for ws in user.work_sell.all %} {% for ws in user.work_sell.all %}
<div class="col-lg-4"> <div class="col-lg-4">
<div class="insetCol box-sizing disTab"> <div class="insetCol box-sizing disTab">
<div class="imgGal"
style="background:rgba(0, 0, 0, 0) url('/media/{{ ws.img }}') no-repeat scroll center center / cover ;"> {% thumbnail ws.get_cover "224x224" crop="center" as im %}
<div class="imgGal" style="background:rgba(0, 0, 0, 0) url('{{ im.url }}') no-repeat scroll center center / cover ;">
<div class="imgFigure"></div> <div class="imgFigure"></div>
</div> </div>
{% endthumbnail %}
<div class="cenaImg box-sizing"> <div class="cenaImg box-sizing">
<div class="cenaImgInset"> <div class="cenaImgInset">
{{ ws.budget }} <i class="fa fa-rub"></i> {{ ws.budget }} <i class="fa fa-rub"></i>
</div> </div>
</div> </div>
</div> </div>
@ -207,7 +219,12 @@
</a> </a>
</div> </div>
<div class="insetBI insetBI2"> <div class="insetBI insetBI2">
<i class="fa fa-times"></i> <form action="{% url 'work_sell:contractor-worksell-trash' pk=ws.pk %}" method="POST" novalidate>
{% csrf_token %}
<input type="hidden" name="next" value="{{ request.path }}">
<a href="#" onclick="$(this).closest('form').submit(); return false"><i class="fa fa-times"></i></a>
</form>
</div> </div>
</div> </div>
</div> </div>

@ -22,7 +22,9 @@
<div class="col-lg-3 divCol3"> <div class="col-lg-3 divCol3">
<div class="avatar"> <div class="avatar">
<div class="avatarInset"> <div class="avatarInset">
<img src="{{ form.avatar.value.url }}" alt="profile-image"> {% if form.avatar.value %}
<img src="{{ form.avatar.value.url }}" alt="profile-image">
{% endif %}
</div> </div>
</div> </div>
<div class="menuUser upload-img disTab"> <div class="menuUser upload-img disTab">

@ -41,7 +41,7 @@
<p>Бюджет{{ worksell_form.budget.errors.as_text }}</p> <p>Бюджет{{ worksell_form.budget.errors.as_text }}</p>
<div class="row"> <div class="row">
<div class="col-lg-8"> <div class="col-lg-8">
<input type="text" class="box-sizing" name="{{ form.budget.html_name }}" value="{{ form.budget.value }}"> <input type="text" class="box-sizing" name="{{ worksell_form.budget.html_name }}" value="{{ worksell_form.budget.value }}">
</div> </div>
<div class="col-lg-4"> <div class="col-lg-4">
{{ worksell_form.currency}} {{ worksell_form.currency}}
@ -53,7 +53,7 @@
<p>Срок выполнения{{ worksell_form.budget.errors.as_text }}</p> <p>Срок выполнения{{ worksell_form.budget.errors.as_text }}</p>
<div class="row"> <div class="row">
<div class="col-lg-8"> <div class="col-lg-8">
<input type="text" class="box-sizing" name="{{ form.budget.html_name }}" value="{{ form.budget.value }}"> <input type="text" class="box-sizing" name="{{ worksell_form.term.html_name }}" value="{{ worksell_form.term.value }}">
</div> </div>
<div class="col-lg-4"> <div class="col-lg-4">
{{ worksell_form.term_type }} {{ worksell_form.term_type }}
@ -76,7 +76,8 @@
</div> </div>
<div class="polsF1 polsF2 disTab"> <div class="polsF1 polsF2 disTab">
<input type="text" name="" id="upload-files-worksell-pk" /> <input type="text" name="images-ids" 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 -->

@ -14,6 +14,7 @@ from .views import (
UserFinancialInfoEditView, UserFinancialInfoEditView,
UserListView, UserListView,
UserProfileEditView, UserProfileEditView,
TeamCreateView,
) )
@ -31,6 +32,7 @@ urlpatterns = [
urls.url(r'^customers/(?P<pk>\d+)/reviews/$', CustomerProfileReviewsView.as_view(), name='customer-profile-reviews'), urls.url(r'^customers/(?P<pk>\d+)/reviews/$', CustomerProfileReviewsView.as_view(), name='customer-profile-reviews'),
urls.url(r'^contractors/$', ContractorFilterView.as_view(), name='contractor-filter'), urls.url(r'^contractors/$', ContractorFilterView.as_view(), name='contractor-filter'),
urls.url(r'^contractors/team/create/$', TeamCreateView.as_view(), name='team-create'),
urls.url(r'^contractors/(?P<pk>\d+)/$', ContractorProfileDetailView.as_view(), name='contractor-profile'), urls.url(r'^contractors/(?P<pk>\d+)/$', ContractorProfileDetailView.as_view(), name='contractor-profile'),
urls.url(r'^contractor-office/(?P<pk>\d+)/$', ContractorOfficeDetailView.as_view(), name='contractor-office'), urls.url(r'^contractor-office/(?P<pk>\d+)/$', ContractorOfficeDetailView.as_view(), name='contractor-office'),

@ -365,8 +365,9 @@ class ContractorOfficeDetailView(DetailView):
def get_context_data(self, **kwargs): def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs) context = super().get_context_data(**kwargs)
context['form_team'] = TeamForm context['form_team'] = TeamForm
participants = []
if self.object.is_owner_team(): if self.object.is_owner_team():
participants = self.object.team.users.all() participants = self.object.team.contractors.all()
user_ids = [p.pk for p in participants] user_ids = [p.pk for p in participants]
context['participants'] = participants context['participants'] = participants
context['participants_count'] = len(participants) context['participants_count'] = len(participants)
@ -484,6 +485,20 @@ class CustomerProfileCurrentProjectsView(BaseMixin, DetailView):
context_object_name = 'customer' context_object_name = 'customer'
class TeamCreateView(View):
form_class = TeamForm
def post(self, request, *args, **kwargs):
form = self.form_class(request.POST)
# import code; code.interact(local=dict(globals(), **locals()))
if form.is_valid():
instance = form.save(commit=False)
instance.owner = request.user
instance.save()
return redirect('users:contractor-office', pk=request.user.pk)
class CustomerProfileReviewsView(BaseMixin, View): class CustomerProfileReviewsView(BaseMixin, View):
template_name = 'customer_profile_reviews.html' template_name = 'customer_profile_reviews.html'

@ -4,6 +4,16 @@ from common.models import Location
from .models import WorkSell from .models import WorkSell
class ContractorWorkSellTrashForm(forms.Form):
pk = forms.ModelChoiceField(queryset=WorkSell.objects.none())
def __init__(self, *args, **kwargs):
self.request = kwargs.pop('request')
super().__init__(*args, **kwargs)
self.fields['pk'].queryset = self.request.user.work_sell.all()
class WorkSellForm(forms.ModelForm): class WorkSellForm(forms.ModelForm):
class Meta: class Meta:

@ -31,6 +31,10 @@ class WorkSell(models.Model):
def is_author_for_work(self): def is_author_for_work(self):
pass pass
def get_cover(self):
photo = self.photos.first()
return photo and photo.img
class Meta: class Meta:
ordering = ['-created'] ordering = ['-created']
verbose_name = 'Готовая работа' verbose_name = 'Готовая работа'

@ -118,7 +118,7 @@
<div class="col-lg-3"> <div class="col-lg-3">
<div class="insetCol box-sizing disTab"> <div class="insetCol box-sizing disTab">
<a href="{% url 'work_sell:detail' work.pk %}"> <a href="{% url 'work_sell:detail' work.pk %}">
{% thumbnail work.img "265x265" crop="center" as im %} {% thumbnail work.get_cover "265x265" crop="center" as im %}
<div class="imgGal" style="background: url('{{ im.url }}') no-repeat center;"> <div class="imgGal" style="background: url('{{ im.url }}') no-repeat center;">
<div class="imgFigure"></div> <div class="imgFigure"></div>
</div> </div>
@ -126,13 +126,14 @@
</a> </a>
<div class="cenaImg box-sizing"> <div class="cenaImg box-sizing">
<div class="cenaImgInset"> <div class="cenaImgInset">
{{ work.budget }} <i class="fa fa-rub"></i> {{ work.budget }}<i class="fa fa-rub"></i>
</div> </div>
</div> </div>
</div> </div>
<div class="insetCol2 box-sizing disTab"> <div class="insetCol2 box-sizing disTab">
<p>{{ work }}</p> <p>{{ work }}</p>
{% if request.user.pk == work.contractor.pk %}
<div class="buttonsImg" disTab> <div class="buttonsImg" disTab>
<a href="{% url 'work_sell:edit' work.pk %}"> <a href="{% url 'work_sell:edit' work.pk %}">
<div class="insetBI insetBI1"> <div class="insetBI insetBI1">
@ -145,6 +146,7 @@
</div> </div>
</a> </a>
</div> </div>
{% endif %}
</div> </div>
</div> </div>
{% endfor %} {% endfor %}

@ -10,6 +10,7 @@ from .views import (
work_sell_create, work_sell_create,
BasicCreateView, BasicCreateView,
PictureCreateView, PictureCreateView,
ContractorWorkSellTrashView,
) )
@ -21,6 +22,7 @@ urlpatterns = [
urls.url(r'^upload/$', UploadView.as_view(), name='upload'), urls.url(r'^upload/$', UploadView.as_view(), name='upload'),
urls.url(r'^(?P<pk>\d+)/edit/$',WorkSellUpdateView.as_view(), name='edit'), urls.url(r'^(?P<pk>\d+)/edit/$',WorkSellUpdateView.as_view(), name='edit'),
urls.url(r'^(?P<pk>\d+)/delete/$',WorkSellDeleteView.as_view(), name='delete'), urls.url(r'^(?P<pk>\d+)/delete/$',WorkSellDeleteView.as_view(), name='delete'),
urls.url(r'^(?P<pk>\d+)/trash/$', ContractorWorkSellTrashView.as_view(), name='contractor-worksell-trash'),
urls.url(r'^test/$', work_sell_create, name='test'), urls.url(r'^test/$', work_sell_create, name='test'),
urls.url(r'^basic/$', BasicCreateView.as_view(), name='upload-basic'), urls.url(r'^basic/$', BasicCreateView.as_view(), name='upload-basic'),
urls.url(r'^new/$', PictureCreateView.as_view(), name='upload-new'), urls.url(r'^new/$', PictureCreateView.as_view(), name='upload-new'),

@ -1,13 +1,20 @@
import json import json
from django.shortcuts import render import pydash as _;
_.map = _.map_;
_.filter = _.filter_
from pprint import pprint, pformat
from django.shortcuts import render, redirect
from django.contrib import messages
from django.core.urlresolvers import reverse from django.core.urlresolvers import reverse
from django.http import JsonResponse, HttpResponse from django.http import JsonResponse, HttpResponse
from django.views.generic import ListView, DetailView, CreateView, View,\ from django.core.files.base import ContentFile
from django.views.generic import ListView, DetailView, CreateView, View, \
UpdateView, DeleteView, TemplateView UpdateView, DeleteView, TemplateView
from projects.models import BuildingClassfication, ConstructionType from projects.models import BuildingClassfication, ConstructionType
from .models import WorkSell, Picture from .models import WorkSell, Picture, WorkSellPhoto
from .forms import WorkSellForm from .forms import WorkSellForm, ContractorWorkSellTrashForm
from .serialize import serialize from .serialize import serialize
from .response import JSONResponse, response_mimetype from .response import JSONResponse, response_mimetype
@ -37,7 +44,7 @@ class WorkSellsView(ListView):
model = WorkSell model = WorkSell
template_name = 'worksells_list.html' template_name = 'worksells_list.html'
# paginate_by = 20 # paginate_by = 20
paginate_by = 1 paginate_by = 18
def get_form_kwargs(self, **kwargs): def get_form_kwargs(self, **kwargs):
kwargs = super().get_form_kwargs kwargs = super().get_form_kwargs
@ -72,6 +79,15 @@ def work_sell_create(request):
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
w_photo = WorkSellPhoto()
w_photo.img = temp_file
w_photo.worksell = instance
w_photo.save()
data = {'status': 'ok'} data = {'status': 'ok'}
else: else:
data = {'status': 'no', 'form_errors': form.errors} data = {'status': 'no', 'form_errors': form.errors}
@ -101,13 +117,27 @@ class WorkSellDeleteView(DeleteView):
return reverse('work_sell:list') return reverse('work_sell:list')
class ContractorWorkSellTrashView(View):
form_class = ContractorWorkSellTrashForm
def post(self, request, *args, **kwargs):
form = self.form_class(_.merge({}, request.POST, kwargs), request=request)
if form.is_valid():
worksell = form.cleaned_data.get('pk')
worksell.delete()
messages.info(request, 'Готовая работа удалена')
else:
messages.info(request, 'Произошла ошибка: <pre>{msg}</pre>'.format(msg=pformat(form.errors)))
redirect_to = request.POST.get('next')
return redirect(redirect_to)
class UploadView(View): class UploadView(View):
template_name = 'upload.html' template_name = 'upload.html'
def get(self, request, *args, **kwargs): def get(self, request, *args, **kwargs):
return render(request,self.template_name) return render(request, self.template_name)
class JSONResponseMixin(object): class JSONResponseMixin(object):
@ -125,5 +155,3 @@ class JSONResponseMixin(object):
class JSONView(JSONResponseMixin, TemplateView): class JSONView(JSONResponseMixin, TemplateView):
def render_to_response(self, context, **response_kwargs): def render_to_response(self, context, **response_kwargs):
return self.render_to_json_response(context, **response_kwargs) return self.render_to_json_response(context, **response_kwargs)

Loading…
Cancel
Save