You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

1133 lines
45 KiB

import itertools
import json
import re
from pprint import pformat
from .signals import *
import natsort
import pydash as _;
from django.conf import settings
from django.contrib import messages
from django.core.exceptions import PermissionDenied
from django.core.files.base import ContentFile
from django.core.paginator import Paginator, EmptyPage, PageNotAnInteger
from django.db.models import Q
from django.http import HttpResponse, JsonResponse, Http404
from django.shortcuts import render, get_object_or_404, redirect
from django.views.generic import DetailView, View, UpdateView, CreateView, TemplateView
_.map = _.map_;
_.filter = _.filter_
from .forms import TeamForm, ContractorResumeFilesForm, ContractorResumeForm, CustomerProfileForm
from .models import User, Team, ContractorResume, ContractorResumeFiles, TeamInvitation
from archilance import util
from archilance.mixins import BaseMixin
from common.mixins import ContractorRequiredMixin, NoCsrfMixin
from common.models import Location
from projects.forms import PortfolioForm
from projects.models import Order, Realty, Project, BuildingClassfication, ConstructionType
from reviews.models import Review
from work_sell.forms import WorkSellForm
from work_sell.models import Picture
from specializations.models import Specialization
from .helpers import get_projects_grouped
from .forms import (
ContractorFilterForm,
CustomerProfileProjectRealtyForm,
UserFinancialInfoEditForm,
UserProfileBasicInfoEditForm,
UserProfileEditForm,
UserProfileEditFullForm,
UserProfileExperienceEditForm,
)
class UserProfileEditView(BaseMixin, View):
form_class = UserProfileEditForm
template_name = 'user_profile_edit.html'
def dispatch(self, request, *args, **kwargs):
if request.resolver_match.url_name == 'user-experience-edit':
if not request.user.is_contractor():
raise PermissionDenied
self.form_class = UserProfileExperienceEditForm
request.experience_edit = True
if request.user.is_authenticated() and request.user.pk == int(kwargs.get('pk')):
return super().dispatch(request, *args, **kwargs)
else:
raise PermissionDenied
def get(self, request, *args, **kwargs):
context = self.get_context_data(**_.merge({}, request.GET, kwargs))
form = self.form_class(request=request, instance=request.user)
context.update({'form': form})
return render(request, self.template_name, context)
def post(self, request, *args, **kwargs):
context = self.get_context_data(**kwargs)
specs = request.POST.getlist('contractor_specializations')
request.POST.setlist('contractor_specializations', _.compact(specs)) # Ignore empty input values
form = self.form_class(request.POST, request=request, instance=request.user)
if form.is_valid():
user = form.save()
live_image = form.cleaned_data.get('live_image')
if live_image:
new_image = ContentFile(live_image.file.read())
new_image.name = live_image.file.name
user.avatar = new_image
user.save()
live_image.file.delete()
live_image.delete()
messages.info(request, 'Пользователь успешно отредактирован')
redirect_to = request.POST.get('next')
return redirect(redirect_to)
else:
if form.errors:
messages.info(request, (
'<p>Произошла ошибка (form)</p>'
'<pre>{form}</pre>'
).format(form=pformat(form.errors)))
context.update({'form': form})
return render(request, self.template_name, context)
class UserProfileEditViewFull(BaseMixin, View):
form_class = UserProfileEditFullForm
template_name = 'user_profile_edit.html'
def dispatch(self, request, *args, **kwargs):
# if request.resolver_match.url_name == 'user-experience-edit':
# if not request.user.is_contractor():
# raise PermissionDenied
# self.form_class = UserProfileExperienceEditForm
# request.experience_edit = True
if request.user.is_authenticated() and request.user.pk == int(kwargs.get('pk')):
return super().dispatch(request, *args, **kwargs)
else:
raise PermissionDenied
def get(self, request, *args, **kwargs):
context = self.get_context_data(**_.merge({}, request.GET, kwargs))
form = self.form_class(instance=request.user)
# import code
# code.interact(local=dict(globals(), **locals()))
context.update({'form': form})
return render(request, self.template_name, context)
def post(self, request, *args, **kwargs):
context = self.get_context_data(**kwargs)
specs = tuple(filter(None, re.split(r'\s|,|;', request.POST.get('contractor_specializations', ''))))
request.POST.setlist('contractor_specializations', specs)
builds = tuple(filter(None, re.split(r'\s|,|;', request.POST.get('contractor_building_classifications', ''))))
request.POST.setlist('contractor_building_classifications', builds)
constructs = tuple(filter(None, re.split(r'\s|,|;', request.POST.get('contractor_construction_types', ''))))
request.POST.setlist('contractor_construction_types', constructs)
form = self.form_class(request.POST, request=request, instance=request.user)
if form.is_valid():
user = form.save()
live_image = form.cleaned_data.get('live_image')
if live_image:
new_image = ContentFile(live_image.file.read())
new_image.name = live_image.file.name
user.avatar = new_image
user.save()
live_image.file.delete()
live_image.delete()
messages.info(request, 'Пользователь успешно отредактирован')
redirect_to = request.POST.get('next')
return redirect(redirect_to)
else:
if form.errors:
messages.info(request, (
'<p>Произошла ошибка (form)</p>'
'<pre>{form}</pre>'
).format(form=pformat(form.errors)))
context.update({'form': form})
return render(request, self.template_name, context)
class UserFinancialInfoEditView(BaseMixin, View):
form_class = UserProfileBasicInfoEditForm
fin_info_form_class = UserFinancialInfoEditForm
template_name = 'user_financial_info_edit.html'
def dispatch(self, request, *args, **kwargs):
if request.user.is_authenticated() and request.user.pk == int(kwargs.get('pk')):
return super().dispatch(request, *args, **kwargs)
else:
raise PermissionDenied
def get(self, request, *args, **kwargs):
context = self.get_context_data(**_.merge({}, request.GET, kwargs))
form = self.form_class(request=request, instance=request.user)
fin_info_form = self.fin_info_form_class(request=request, instance=request.user.financial_info,
prefix='fin_info')
context.update({
'form': form,
'fin_info_form': fin_info_form,
})
return render(request, self.template_name, context)
def post(self, request, *args, **kwargs):
context = self.get_context_data(**kwargs)
specs = request.POST.getlist('contractor_specializations')
request.POST.setlist('contractor_specializations', _.compact(specs)) # Ignore empty input values
form = self.form_class(request.POST, request.FILES, request=request, instance=request.user)
fin_info_form = self.fin_info_form_class(request.POST, request.FILES, request=request,
instance=request.user.financial_info, prefix='fin_info')
if form.is_valid() and fin_info_form.is_valid():
user = form.save()
fin_info = fin_info_form.save()
live_image = form.cleaned_data.get('live_image')
if live_image:
new_image = ContentFile(live_image.file.read())
new_image.name = live_image.file.name
user.avatar = new_image
live_image.file.delete()
live_image.delete()
user.financial_info = fin_info
user.save()
messages.info(request, 'Финансовая информация успешно отредактирована')
redirect_to = request.POST.get('next')
return redirect(redirect_to)
else:
if form.errors:
messages.info(request, (
'<p>Произошла ошибка (form)</p>'
'<pre>{form}</pre>'
).format(form=pformat(form.errors)))
if fin_info_form.errors:
messages.info(request, (
'<p>Произошла ошибка (fin_info_form)</p>'
'<pre>{form}</pre>'
).format(form=pformat(fin_info_form.errors)))
context.update({
'form': form,
'fin_info_form': fin_info_form,
})
return render(request, self.template_name, context)
# class ContractorFilterViewOld(BaseMixin, View):
# template_name = 'contractor_filter.html'
# form_class = ContractorFilterForm
#
# def get(self, request, *args, **kwargs):
# form = self.form_class(request.GET, request=request)
# context = self.get_context_data(**_.merge({}, request.GET, kwargs))
# coll = []
#
# if form.is_valid():
# contractors = teams = None
# contr_count = team_count = None
# get_contractors = get_teams = None
# ord = None
#
# cro = form.cleaned_data.get('cro')
# specialization = form.cleaned_data.get('specialization')
# location = form.cleaned_data.get('location')
# work_type = form.cleaned_data.get('work_type')
# build_classif = form.cleaned_data.get('building_classification')
# constr_type = form.cleaned_data.get('construction_type')
#
# party_types = form.cleaned_data.get('party_types')
# last_party_types = form.cleaned_data.get('last_party_types')
#
# if party_types == 'all':
# get_contractors = get_teams = True
# elif party_types == 'contractors':
# get_contractors = True
# elif party_types == 'teams':
# get_teams = True
# elif not party_types:
# if last_party_types == 'contractors':
# get_contractors = True
# elif last_party_types == 'teams':
# get_teams = True
# else:
# get_contractors = get_teams = True
#
# if party_types:
# last_party_types = party_types
#
# context.update({'last_party_types': last_party_types})
#
# if get_contractors:
# contractors = User.contractor_objects.all()
#
# if cro:
# contractors = contractors.filter(cro=cro)
#
# if specialization:
# contractors = contractors.filter(
# contractor_specializations__lft__gte=specialization.lft,
# contractor_specializations__rght__lte=specialization.rght,
# )
#
# if location:
# contractors = contractors.filter(
# location__lft__gte=location.lft,
# location__rght__lte=location.rght,
# )
#
# if work_type:
# contractors = contractors.filter(orders__project__work_type=work_type)
#
# if build_classif:
# contractors = contractors.filter(Q(orders__project__realty__building_classification=build_classif) |
# Q(contractor_building_classifications=build_classif))
#
# if constr_type:
# contractors = contractors.filter(Q(orders__project__realty__construction_type=constr_type) |
# Q(contractor_construction_types=constr_type))
#
# if get_teams:
# teams = Team.objects.all()
#
# if cro:
# teams = teams.filter(Q(contractors__cro=cro) | Q(owner__cro=cro))
#
# if specialization:
# teams = teams.filter(
# (
# Q(contractors__contractor_specializations__lft__gte=specialization.lft)
# & Q(contractors__contractor_specializations__rght__lte=specialization.rght)
# ) | (
# Q(owner__contractor_specializations__lft__gte=specialization.lft)
# & Q(owner__contractor_specializations__rght__lte=specialization.rght)
# ),
# )
#
# if location:
# teams = teams.filter(
# (
# Q(contractors__location__lft__gte=location.lft)
# & Q(contractors__location__rght__lte=location.rght)
# ) | (
# Q(owner__location__lft__gte=location.lft)
# & Q(owner__location__rght__lte=location.rght)
# ),
# )
#
# if work_type:
# teams = teams.filter(
# Q(contractors__orders__project__work_type=work_type)
# | Q(owner__orders__project__work_type=work_type),
# )
#
# if build_classif:
# teams = teams.filter(
# Q(contractors__orders__project__realty__building_classification=build_classif)
# | Q(owner__orders__project__realty__building_classification=build_classif),
# )
#
# if constr_type:
# teams = teams.filter(
# Q(contractors__orders__project__realty__construction_type=constr_type)
# | Q(owner__orders__project__realty__construction_type=constr_type),
# )
#
# if get_contractors and get_teams:
# coll = tuple(itertools.chain(contractors.distinct(), teams.distinct()))
# count = len(coll)
# display_msg = 'Найдено %s элементов' % count if count > 0 else 'Ничего не найдено'
# elif get_contractors:
# coll = contractors.distinct()
# count = coll.count()
# display_msg = 'Найдено %s исполнителей' % count if count > 0 else 'Ничего не найдено'
# elif get_teams:
# coll = teams.distinct()
# count = coll.count()
# display_msg = 'Найдено %s групп' % count if count > 0 else 'Ничего не найдено'
#
# order_by = form.cleaned_data.get('order_by')
# last_order_by = form.cleaned_data.get('last_order_by')
# reverse_order = form.cleaned_data.get('reverse_order')
#
# if order_by:
# reverse_order = not reverse_order if order_by == last_order_by else False
# ord = order_by
# last_order_by = ord
# elif last_order_by:
# ord = last_order_by
#
# if ord:
# if ord == 'name':
# coll = natsort.natsorted(coll, key=lambda obj: getattr(obj, 'username', None) or obj.name,
# reverse=reverse_order)
# elif ord == 'created':
# coll = natsort.natsorted(coll, key=lambda obj: obj.created, reverse=reverse_order)
#
# context.update({
# 'last_order_by': last_order_by,
# 'reverse_order': reverse_order,
# })
# else:
# display_msg = 'Пожалуйста, введите корректные данные'
#
# if form.errors:
# messages.info(request, (
# '<p>Произошла ошибка (form)</p>'
# '<pre>{form}</pre>'
# ).format(form=pformat(form.errors)))
#
# paginator = Paginator(coll, settings.PAGE_SIZE)
# page = request.GET.get('page')
#
# try:
# coll = paginator.page(page)
# except PageNotAnInteger:
# coll = paginator.page(1)
# except EmptyPage:
# coll = paginator.page(paginator.num_pages)
#
# context.update({
# 'form': form,
# 'coll': coll,
# 'is_paginated': True,
# 'page_obj': coll,
# 'display_msg': display_msg,
# })
#
# return render(request, self.template_name, context)
# TODO: не работает сортировка по reviews(не получилось создать отзывы) и views(не нашел счетчик просмотров)
class ContractorFilterView(BaseMixin, View):
template_name = 'contractor_filter.html'
include_template = 'partials/inc-contractors-results.html'
form_class = ContractorFilterForm
PROJECT_ORDER_CHOICES = ( # "Упорядочить по"...
('name', 'названию'),
('created', 'дате размещения'),
('views', 'просмотрам'),
('reviews', 'Отзывам'),
('rating', 'Рейтингу'),
)
def set_teams_filter(self, objects, request_data):
specialization = request_data.get('specialization')
building_classification = request_data.get('building_classification')
construction_type = request_data.get('construction_type')
location = request_data.get('location')
cro = request_data.get('cro')
if specialization:
query_contractors = util.build_query(specialization, Specialization,
'contractors__contractor_specializations__lft__gte',
'contractors__contractor_specializations__rght__lte')
query_owner = util.build_query(specialization, Specialization,
'owner__contractor_specializations__lft__gte',
'owner__contractor_specializations__rght__lte')
objects = objects.filter(query_contractors | query_owner)
if building_classification:
query_contractors = util.build_query(building_classification, BuildingClassfication,
'contractors__contractor_building_classifications')
query_owner = util.build_query(building_classification, BuildingClassfication,
'owner__contractor_building_classifications')
objects = objects.filter(query_contractors | query_owner)
if construction_type:
query_contractors = util.build_query(construction_type, ConstructionType,
'contractors__contractor_construction_types')
query_owner = util.build_query(construction_type, ConstructionType,
'owner__contractor_construction_types')
objects = objects.filter(query_contractors | query_owner)
if location:
query_contractors = util.build_query(location, Location,
'contractors__location__lft__gte',
'contractors__location__rght__lte')
query_owner = util.build_query(construction_type, Location,
'owner__location__lft__gte',
'owner__location__rght__lte',)
objects = objects.filter(query_contractors | query_owner)
if cro:
objects = objects.filter(Q(contractors__cro=cro) | Q(owner__cro=cro))
return objects
def set_contractors_filter(self, objects, request_data):
specialization = request_data.get('specialization')
building_classification = request_data.get('building_classification')
construction_type = request_data.get('construction_type')
location = request_data.get('location')
cro = request_data.get('cro')
if specialization:
query = util.build_query(specialization, Specialization,
'contractor_specializations__lft__gte', 'contractor_specializations__rght__lte')
objects = objects.filter(query)
if building_classification:
query = util.build_query(building_classification, BuildingClassfication,
'contractor_building_classifications__lft__gte',
'contractor_building_classifications__rght__lte')
objects = objects.filter(query)
if construction_type:
objects = objects.filter(contractor_construction_types__in=
tuple(filter(None, re.split(r'\s|,|;', construction_type))))
if location:
query = util.build_query(location, Location,
'location__lft__gte',
'location__rght__lte')
objects = objects.filter(query)
if cro:
objects = objects.filter(cro=True)
return objects
def contractors_sort_by(self, contractors, order_by):
if order_by == 'name':
contractors = contractors.order_by('username')
if order_by == 'created':
contractors = contractors.order_by('created')
if order_by == 'views':
pass
if order_by == 'reviews':
pass
if order_by == 'rating':
contractors = contractors.order_by('rating')
return contractors
def teams_sort_by(self, teams, order_by):
if order_by == 'name':
teams = teams.order_by('name')
if order_by == 'created':
teams = teams.order_by('created')
if order_by == 'views':
pass
if order_by == 'reviews':
pass
if order_by == 'rating':
teams = teams.order_by('rating')
return teams
def pagination(self, objects, page):
paginator = Paginator(objects, settings.PAGE_SIZE)
# print("pag page = ", page)
try:
objects = paginator.page(page)
except PageNotAnInteger:
objects = paginator.page(1)
except EmptyPage:
objects = paginator.page(paginator.num_pages)
return objects
def get_context(self, request_data):
context = request_data.dict()
contractors = User.contractor_objects.all()
teams = Team.objects.all()
print(request_data)
party_types = request_data.get("party_types")
order_by = request_data.get("order_by")
print("order_by = ", order_by)
if party_types == 'teams':
objects = self.set_teams_filter(teams, request_data).distinct()
objects = self.teams_sort_by(objects, order_by)
count = objects.count()
display_msg = 'Найдено %s групп' % count if count > 0 else 'Ничего не найдено'
elif party_types == 'contractors':
objects = self.set_contractors_filter(contractors, request_data).distinct()
objects = self.contractors_sort_by(objects, order_by)
count = objects.count()
display_msg = 'Найдено %s исполнителей' % count if count > 0 else 'Ничего не найдено'
else:
teams = self.set_teams_filter(teams, request_data)
teams = self.teams_sort_by(teams, order_by)
contractors = self.set_contractors_filter(contractors, request_data)
contractors = self.contractors_sort_by(contractors, order_by)
objects = tuple(itertools.chain(contractors.distinct(), teams.distinct()))
count = len(objects)
display_msg = 'Найдено %s элементов' % count if count > 0 else 'Ничего не найдено'
# objects = self.sort_by(objects, order_by)
objects = self.pagination(objects, request_data.get("page"))
context.update({
'choices': self.PROJECT_ORDER_CHOICES,
'objects': objects,
'is_paginated': True,
'display_msg': display_msg,
'page_obj': objects,
# 'num_results': num_results,
# 'has_additional_fields': has_additional_fields
})
return context
def get(self, request):
return render(request, self.template_name, self.get_context(request.GET))
def post(self, request):
return render(request, self.include_template, self.get_context(request.POST))
class ContractorProfileView(BaseMixin, DetailView):
model = User
worksell_form_class = WorkSellForm
portfolio_form_class = PortfolioForm
template_name = 'contractor_profile.html'
context_object_name = 'contractor'
queryset = User.contractor_objects
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
request_user = self.request.user
contractor = self.object
context['worksell_form'] = self.worksell_form_class
context['portfolio_form'] = self.portfolio_form_class
display_team_invitation_button = \
request_user.is_authenticated() and \
request_user.is_contractor() and \
contractor != request_user and \
request_user.has_team() and \
contractor not in request_user.team.contractors.all()
context['display_team_invitation_button'] = display_team_invitation_button
resume = self.object.contractor_resume
if resume:
context['resume_diploms'] = resume.resume_files.filter(type='diplom')
context['resume_cro'] = resume.resume_files.filter(type='cro')
else:
resume = ContractorResume()
resume.save()
self.object.contractor_resume = resume
self.object.save()
return context
class ContractorOfficeView(BaseMixin, DetailView):
model = User
template_name = 'contractor_office.html'
context_object_name = 'contractor'
form_class = TeamForm
def dispatch(self, request, *args, **kwargs):
if request.user.is_authenticated() and request.user.is_contractor():
return super().dispatch(request, *args, **kwargs)
else:
raise PermissionDenied
def get_object(self, queryset=None):
return self.request.user
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
contractor = self.object
if util.get_related_or_none(contractor, 'team'):
team = contractor.team
# compl_proj = []
# compl_proj.extend(tuple(o.project for o in contractor.orders.filter(status='completed')))
#
# for c in members:
# compl_proj.extend(tuple(o.project for o in c.orders.filter(status='completed')))
grouped_projects = get_projects_grouped(contractor)
private_open_projects = grouped_projects['private_open_projects']
team_open_projects = grouped_projects['team_open_projects']
private_archived_projects = grouped_projects['private_archived_projects']
team_archived_projects = grouped_projects['team_archived_projects']
context['open_project_count'] = len(private_open_projects) + len(team_open_projects)
context['archived_project_count'] = len(private_archived_projects) + len(team_archived_projects)
compl_proj = tuple(o.project for o in team.orders.filter(status='completed'))
team_invitation_exclude_contractor_ids = tuple(
itertools.chain((contractor.pk,), tuple(c.pk for c in contractor.team.contractors.all())))
context['team_invitation_exclude_contractor_ids'] = team_invitation_exclude_contractor_ids
context['completed_project_count'] = len(compl_proj)
context['reviews'] = Review.objects.filter(target_contractor=contractor)
context['form_team'] = self.form_class
return context
class TeamProfileView(BaseMixin, DetailView):
model = Team
template_name = 'team_profile.html'
context_object_name = 'team'
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
team = self.object
compl_proj = tuple(o.project for o in team.orders.filter(status='completed'))
context['completed_project_count'] = len(compl_proj)
context['reviews'] = Review.objects.filter(target_team=team)
return context
class ContractorChatProjectsView(View):
template_name = 'contractor_office_chat_projects.html'
def get(self, request, *args, **kwargs):
context = {}
contractor = request.user
context['contractor'] = contractor
grouped_projects = get_projects_grouped(contractor)
private_open_projects = grouped_projects['private_open_projects']
team_open_projects = grouped_projects['team_open_projects']
private_archived_projects = grouped_projects['private_archived_projects']
team_archived_projects = grouped_projects['team_archived_projects']
context['open_project_count'] = len(private_open_projects) + len(team_open_projects)
context['archived_project_count'] = len(private_archived_projects) + len(team_archived_projects)
team_ids = []
if request.user.is_owner_team():
team_ids.append(request.user.team.pk)
orders = Order.objects.filter(Q(contractor=request.user) | Q(team_id__in=team_ids)).all()
context['orders'] = orders
return render(request, self.template_name, context)
class ContractorOfficeProjectsView(BaseMixin, View):
template_name = 'contractor_office_open_projects.html'
def dispatch(self, request, *args, **kwargs):
if request.user.is_authenticated() and request.user.is_contractor():
return super().dispatch(request, *args, **kwargs)
else:
raise PermissionDenied
def get(self, request, *args, **kwargs):
context = self.get_context_data(**kwargs)
contractor = request.user
context['contractor'] = contractor
grouped_projects = get_projects_grouped(contractor)
private_open_projects = grouped_projects['private_open_projects']
team_open_projects = grouped_projects['team_open_projects']
private_archived_projects = grouped_projects['private_archived_projects']
team_archived_projects = grouped_projects['team_archived_projects']
context['open_project_count'] = len(private_open_projects) + len(team_open_projects)
context['archived_project_count'] = len(private_archived_projects) + len(team_archived_projects)
if request.GET.get('owner') == 'private':
if request.GET.get('archived') == 'on':
projects = private_archived_projects
else:
projects = private_open_projects
elif request.GET.get('owner') == 'teams':
if request.GET.get('archived') == 'on':
projects = team_archived_projects
else:
projects = team_open_projects
else:
if request.GET.get('archived') == 'on':
projects = itertools.chain(private_archived_projects, team_archived_projects)
else:
projects = itertools.chain(private_open_projects, team_open_projects)
context['projects'] = projects
return render(request, self.template_name, context)
class CustomerProfileView(BaseMixin, DetailView):
template_name = 'customer_profile.html'
model = User
context_object_name = 'customer'
def get_object(self, queryset=None):
return get_object_or_404(User, pk=self.kwargs['pk'])
def get_context_data(self, **kwargs):
context = super().get_context_data()
user_id = self.kwargs['pk']
# profile-info
context.update(
{
'ratings': User.objects.get(pk=user_id).rating,
'deals': Order.objects.filter(secure=True, contractor_id=user_id, status=1).count(),
'reviews_n': Review.objects.filter(target_contractor_id=user_id, type='neutral').count(),
'reviews_m': Review.objects.filter(target_contractor_id=user_id, type='negative').count(),
'reviews_p': Review.objects.filter(target_contractor_id=user_id, type='positive').count(),
})
# Realty
context.update({
'objects': Realty.objects.filter(user=self.kwargs['pk'], is_virtual=False, state="active"),
'trashed_objects': Realty.objects.filter(user=self.kwargs['pk'], is_virtual=False, state="trashed"),
})
customer = self.object
open_projects = customer.customer_projects.filter(state='active')
trashed_projects = customer.customer_projects.filter(state='trashed', order__contractor__isnull=True,
order__team__isnull=True)
projects_in_work = customer.customer_projects.filter(state='active').exclude(order__contractor__isnull=True,
order__team__isnull=True)
reviews = Review.objects.filter(target_customer=customer)
context.update({
'customer': customer,
'open_projects': open_projects,
'trashed_projects': trashed_projects,
'projects_in_work': projects_in_work,
'reviews': reviews,
# 'is_paginated': True,
# 'page_obj': projects,
})
return context
class CustomerProfileOpenProjectsView(BaseMixin, View):
template_name = 'customer_profile_open_projects.html'
form_class = CustomerProfileProjectRealtyForm
def get(self, request, *args, **kwargs):
context = self.get_context_data(**_.merge({}, request.GET, kwargs))
customer = get_object_or_404(User.customer_objects, pk=kwargs.get('pk'))
form = self.form_class(request.GET, request=request, customer=customer)
projects = customer.customer_projects.filter(state='active', order__contractor__isnull=True,
order__team__isnull=True)
trashed_projects = customer.customer_projects.filter(state='trashed', order__contractor__isnull=True,
order__team__isnull=True)
# @Add fast
num_current_projects = customer.customer_projects.filter(state='active').exclude(order__contractor__isnull=True,
order__team__isnull=True).count()
if form.is_valid():
realty = form.cleaned_data.get('realty')
if realty:
projects = projects.filter(realty=realty)
trashed_projects = trashed_projects.filter(realty=realty)
else:
if form.errors:
messages.info(request, (
'<p>Произошла ошибка (form)</p>'
'<pre>{form}</pre>'
).format(form=pformat(form.errors)))
paginator = Paginator(projects, settings.PAGE_SIZE)
page = request.GET.get('page')
try:
projects = paginator.page(page)
except PageNotAnInteger:
projects = paginator.page(1)
except EmptyPage:
projects = paginator.page(paginator.num_pages)
context.update({
'form': form,
'projects': projects,
'customer': customer,
'open_project_count': projects.paginator.count,
'trashed_project_count': trashed_projects.count(),
'num_current_projects': num_current_projects,
'is_paginated': True,
'page_obj': projects,
})
return render(request, self.template_name, context)
class CustomerProfileTrashedProjectsView(BaseMixin, View):
template_name = 'customer_profile_trashed_projects.html'
form_class = CustomerProfileProjectRealtyForm
def get(self, request, *args, **kwargs):
context = self.get_context_data(**_.merge({}, request.GET, kwargs))
customer = get_object_or_404(User.customer_objects, pk=kwargs.get('pk'))
form = self.form_class(request.GET, request=request, customer=customer)
projects = customer.customer_projects.filter(state='trashed', order__contractor__isnull=True,
order__team__isnull=True)
open_projects = customer.customer_projects.filter(state='active', order__contractor__isnull=True,
order__team__isnull=True)
if form.is_valid():
realty = form.cleaned_data.get('realty')
if realty:
projects = projects.filter(realty=realty)
open_projects = open_projects.filter(realty=realty)
else:
if form.errors:
messages.info(request, (
'<p>Произошла ошибка (form)</p>'
'<pre>{form}</pre>'
).format(form=pformat(form.errors)))
paginator = Paginator(projects, settings.PAGE_SIZE)
page = request.GET.get('page')
try:
projects = paginator.page(page)
except PageNotAnInteger:
projects = paginator.page(1)
except EmptyPage:
projects = paginator.page(paginator.num_pages)
context.update({
'form': form,
'projects': projects,
'customer': customer,
'open_project_count': open_projects.count(),
'trashed_project_count': projects.paginator.count,
'is_paginated': True,
'page_obj': projects,
})
return render(request, self.template_name, context)
class CustomerProfileCurrentProjectsView(BaseMixin, View):
template_name = 'customer_profile_current_projects.html'
form_class = CustomerProfileProjectRealtyForm
def dispatch(self, request, *args, **kwargs):
if request.user.is_authenticated() and request.user.is_customer():
customer = get_object_or_404(User.customer_objects, pk=kwargs.get('pk'))
if request.user == customer:
return super().dispatch(request, *args, **kwargs)
raise PermissionDenied
def get(self, request, *args, **kwargs):
context = self.get_context_data(**_.merge({}, request.GET, kwargs))
customer = get_object_or_404(User.customer_objects, pk=kwargs.get('pk'))
projects = customer.customer_projects.filter(state='active').exclude(order__contractor__isnull=True,
order__team__isnull=True)
num_current_projects = projects.count()
# trashed_projects = customer.customer_projects.filter(state='trashed')
paginator = Paginator(projects, settings.PAGE_SIZE)
page = request.GET.get('page')
try:
projects = paginator.page(page)
except PageNotAnInteger:
projects = paginator.page(1)
except EmptyPage:
projects = paginator.page(paginator.num_pages)
context.update({
'projects': projects,
'customer': customer,
'num_current_projects': num_current_projects,
# 'open_project_count': projects.paginator.count,
# 'trashed_project_count': trashed_projects.count(),
'is_paginated': True,
'page_obj': projects,
})
return render(request, self.template_name, context)
def join_user_in_team(request):
pass
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')
class ContractorResumeUpdateView(UpdateView):
model = ContractorResume
form_class = ContractorResumeForm
def form_valid(self, form):
if self.request.is_ajax():
self.object = form.save()
data = {
'text': self.object.text,
'status': 'ok',
}
return JsonResponse(data)
return super().form_valid(form)
def form_invalid(self, form):
if self.request.is_ajax():
return JsonResponse(form.errors, status=400)
return super().form_invalid(form)
class ContractorResumeFileCreateView(CreateView):
model = ContractorResumeFiles
form_class = ContractorResumeFilesForm
def form_valid(self, request, form):
if self.request.is_ajax():
img_id = request.POST.get('img_id')
picture = Picture.objects.get(pk=img_id)
temp_file = ContentFile(picture.file.read())
temp_file.name = picture.file.name
instance = form.save(commit=False)
instance.img = temp_file
instance.save()
data = {
'pk': instance.pk,
'status': 'ok',
}
return JsonResponse(data)
return super().form_valid(form)
def form_invalid(self, form):
if self.request.is_ajax():
return JsonResponse(form.errors, status=400)
return super().form_invalid(form)
def contractor_resumefile_create(request):
if request.is_ajax():
form = ContractorResumeFilesForm(data=request.POST)
# import code; code.interact(local=dict(globals(), **locals()))
if form.is_valid():
# import code; code.interact(local=dict(globals(), **locals()))
img_id = request.POST.get('img_id')
picture = Picture.objects.get(pk=img_id)
temp_file = ContentFile(picture.file.read())
temp_file.name = picture.file.name
instance = form.save(commit=False)
instance.img = temp_file
instance.save()
data = {'status': 'ok', 'pk': instance.pk}
else:
data = {'status': 'no', 'form_errors': form.errors}
return HttpResponse(json.dumps(data), content_type='application/json')
else:
raise Http404
class CustomerProfileReviewsView(BaseMixin, View):
template_name = 'customer_profile_reviews.html'
def get(self, request, *args, **kwargs):
context = self.get_context_data(**_.merge({}, self.request.GET, kwargs))
customer = get_object_or_404(User.customer_objects, pk=self.kwargs['pk'])
reviews = Review.objects.filter(target_customer=customer)
# @Add fast
num_current_projects = customer.customer_projects.filter(state='active').exclude(order__contractor__isnull=True,
order__team__isnull=True).count()
context.update({
'reviews': reviews,
'customer': customer,
'num_current_projects': num_current_projects
})
return render(request, self.template_name, context)
class CreateTeamInvitation(NoCsrfMixin, ContractorRequiredMixin, View):
def post(self, request, *args, contractor_id, **kwargs):
contractor1 = request.user
contractor2 = get_object_or_404(User.contractor_objects, pk=contractor_id)
try:
TeamInvitation.objects.create(contractor1=contractor1, contractor2=contractor2)
return JsonResponse({'status': 'success'})
except:
return JsonResponse({'status': 'error'})
class AcceptTeamInvitation(NoCsrfMixin, ContractorRequiredMixin, View):
# TODO: Users can accept invitations by clicking a link, hence the "get":
def get(self, request, *args, owner_id, **kwargs):
contractor1 = get_object_or_404(User.contractor_objects, pk=owner_id)
contractor2 = request.user
team_invitation = util.get_or_none(TeamInvitation, contractor1=contractor1, contractor2=contractor2)
team = util.get_related_or_none(contractor1, 'team')
if team_invitation and team:
team.contractors.add(contractor2)
team_invitation.delete()
messages.info(request, 'Вы успешно вступили в группу')
return redirect('users:team-profile', pk=team.pk)
else:
raise Http404
# import code; code.interact(local=dict(globals(), **locals()))