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.
 
 
 
 
 
 

1022 lines
37 KiB

import json
from abc import ABC
from pprint import pformat
import pydash as _
from django.conf import settings
from django.contrib import messages
from django.contrib.auth.mixins import LoginRequiredMixin
from django.core.exceptions import PermissionDenied
from django.core.files.base import ContentFile
from django.core.paginator import Paginator, EmptyPage, PageNotAnInteger
from django.core.urlresolvers import reverse, reverse_lazy
from django.db.models import Q, Count, Sum
from django.http import HttpResponseForbidden, JsonResponse, HttpResponseRedirect, HttpResponse, Http404
from django.shortcuts import render, get_object_or_404, redirect
from django.views.generic import DetailView, CreateView, DeleteView, View, UpdateView, TemplateView
from hitcount.models import HitCount
from hitcount.views import HitCountMixin
import re
from archilance import util
from archilance.mixins import BaseMixin
from common.mixins import NoCsrfMixin
from users.models import User, Team
from work_sell.models import Picture, WorkSell, WorkSellPhoto
from ratings.models import HistoryRating
from .models import (
Answer,
AnswerFile,
AnswerMessage,
Arbitration,
BuildingClassfication,
Candidate,
Order,
Portfolio,
PortfolioPhoto,
Project,
ProjectFile,
TERM_TYPE_MORPHS,
Realty
)
from .forms import (
ContractorPortfolioTrashForm,
CustomerProjectDeleteForm,
CustomerProjectEditForm,
CustomerProjectEditFormNew,
CustomerProjectRestoreForm,
CustomerProjectTrashForm,
PortfolioEditForm,
PortfolioForm,
ProjectAnswerForm,
ProjectAnswerMessageForm,
ProjectWorkTypeSuggestionForm,
RealtyForm,
RealtyFormNew
)
from specializations.models import Specialization
from common.models import Location
from common.forms import CustomRegistrationForm
_.map = _.map_
_.filter = _.filter_
class ProjectDetailWithAnswerView(BaseMixin, View):
form_class = ProjectAnswerForm
template_name = 'project_detail.html'
def get(self, request, *args, **kwargs):
context = self.get_context_data(**_.merge({}, request.GET, kwargs))
context.update({'TERM_TYPE_MORPHS': TERM_TYPE_MORPHS})
project = get_object_or_404(Project, pk=kwargs.get('pk'))
context.update({'project': project})
hit_count = HitCount.objects.get_for_object(project)
HitCountMixin.hit_count(request, hit_count)
if request.user.is_authenticated() and request.user.is_contractor():
project_answers = project.answers.filter(rejected=False)
contractor = request.user
answer = _.first(_.filter(project_answers, lambda a: a.author == contractor))
if not answer:
team = util.get_related_or_none(contractor, 'team')
if team:
answer = _.first(_.filter(project_answers, lambda a: a.author == team))
context.update({'answer': answer})
# answer.messages.update()
if not answer:
team = util.get_related_or_none(contractor, 'team')
if team:
context.update({'can_answer_as_team': True})
if request.GET.get('answer_as_team') == 'on':
context.update({'answer_as_team': True})
form = self.form_class(request=request, answer_as_team=True, project=project)
else:
form = self.form_class(request=request, project=project)
context.update({'form': form})
return render(request, self.template_name, context)
def post(self, request, *args, **kwargs):
# @Отклик на Проект(Project)
if request.user.is_authenticated() and request.user.is_contractor():
context = self.get_context_data(**kwargs)
answer_as_team = None
project = get_object_or_404(Project, pk=kwargs.get('pk')) # TODO: Does this work?
if request.POST.get('answer_as_team') == 'on':
answer_as_team = True
# Check for duplicate answers:
if answer_as_team and util.has_related(request.user, 'team'):
if project.answers.filter(object_id=request.user.team.pk, content_type__model='team').exists():
raise PermissionDenied('Повторный отклик')
else:
if project.answers.filter(object_id=request.user.pk, content_type__model='user').exists():
raise PermissionDenied('Повторный отклик')
if answer_as_team:
form = self.form_class(request.POST, request=request, answer_as_team=True, project=project)
else:
form = self.form_class(request.POST, request=request, project=project)
# FIXME: еще раз находим проект?
project = get_object_or_404(Project, pk=kwargs.get('pk'))
context.update({'project': project})
if form.is_valid():
answer = form.save(commit=False)
answer.project = project
answer.author = request.user.team if answer_as_team else request.user
answer.save()
form.save_m2m()
for file in request.FILES.getlist('new_files'):
if len(file.name) <= 255:
AnswerFile.objects.create(file=file, name=file.name, answer=answer)
message = AnswerMessage(text=form.cleaned_data.get('text'), is_sender_customer=False)
message.answer = answer
message.contractor_or_team = answer.author
message.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)))
context.update({'form': form})
return render(request, self.template_name, context)
else:
raise PermissionDenied
class ProjectAnswerCreateMessageView(BaseMixin, View):
form_class = ProjectAnswerMessageForm
def dispatch(self, request, *args, **kwargs):
if request.user.is_authenticated():
return super().dispatch(request, *args, **kwargs)
else:
raise PermissionDenied
def post(self, request, *args, **kwargs):
form = self.form_class(request.POST, request=request)
answer = get_object_or_404(Answer, pk=kwargs.get('pk'))
if form.is_valid():
message = form.save(commit=False)
if request.user.is_contractor():
message.answer = answer
message.is_sender_customer = False
if isinstance(answer.author, User) and answer.author == request.user:
message.contractor_or_team = request.user
elif isinstance(answer.author, Team):
team = util.get_related_or_none(request.user, 'team')
if team and answer.author == team:
message.contractor_or_team = team
elif request.user.is_customer():
message.answer = answer
message.is_sender_customer = True
message.save()
form.save_m2m()
messages.info(request, 'Сообщение успешно размещено')
else:
if form.errors:
messages.info(request, (
'<p>Произошла ошибка (form)</p>'
'<pre>{form}</pre>'
).format(form=pformat(form.errors)))
redirect_to = request.POST.get('next')
return redirect(redirect_to)
class RejectProjectAnswerView(NoCsrfMixin, LoginRequiredMixin, BaseMixin, View):
def post(self, request, *args, **kwargs):
if request.user.is_contractor():
answer = None
contractor_answer = util.get_or_none(request.user.contractor_answers, pk=kwargs.get('pk'))
if contractor_answer:
answer = contractor_answer
elif request.user.team:
answer = util.get_or_none(request.user.team.answers, pk=kwargs.get('pk'))
if not answer:
raise Http404
elif request.user.is_customer():
project = get_object_or_404(request.user.customer_projects, answers__pk=kwargs.get('pk'))
answer = get_object_or_404(project.answers, pk=kwargs.get('pk'))
answer.rejected = True
answer.save()
candidate = Candidate.objects.filter(answer=answer)
if candidate:
candidate.delete()
messages.info(request, 'Успешный отказ от проекта')
redirect_to = request.POST.get('next')
return redirect(redirect_to)
class RestoreProjectAnswerView(NoCsrfMixin, LoginRequiredMixin, BaseMixin, View):
def post(self, request, *args, **kwargs):
if request.user.is_contractor():
answer = None
contractor_answer = util.get_or_none(request.user.contractor_answers, pk=kwargs.get('pk'))
if contractor_answer:
answer = contractor_answer
elif request.user.team:
answer = util.get_or_none(request.user.team.answers, pk=kwargs.get('pk'))
if not answer:
raise Http404
elif request.user.is_customer():
project = get_object_or_404(request.user.customer_projects, answers__pk=kwargs.get('pk'))
answer = get_object_or_404(project.answers, pk=kwargs.get('pk'))
answer.rejected = False
answer.save()
messages.info(request, 'Проект успешно восстановлен')
redirect_to = request.POST.get('next')
return redirect(redirect_to)
def build_query(id_str, _class, *args):
query = Q()
id_list = tuple(filter(None, re.split(r'\s|,|;', id_str)))
for id in id_list:
obj = _class.objects.get(id=id)
kwargs = dict(zip(args, (obj.lft, obj.rght)))
query |= Q(**kwargs)
return query
class ProjectFilterView(BaseMixin, View):
template_name = 'project_filter.html'
# form_class = ProjectFilterForm
# renderer_classes = (TemplateHTMLRenderer,)
PROJECT_ORDER_CHOICES = ( # "Упорядочить по"...
('name', 'названию'),
('budget', 'цене'),
('created', 'дате размещения'),
('views', 'просмотрам'),
)
def filter(self, projects, data):
# print("filter data = ", data)
specialization = data.get('specialization')
keywords = data.get('keywords')
building_classification = data.get('building_classification')
construction_type = data.get('construction_type')
location = data.get('location')
cro = data.get('cro')
if keywords:
# print("keywords = ", keywords)
keywords = tuple(filter(None, re.split(r'\s|,|;', keywords)))
for k in keywords:
projects = projects.filter(Q(name__icontains=k.lower()) | Q(text__icontains=k.lower()))
if specialization:
query = build_query(specialization, Specialization,
'specialization__lft__gte', 'specialization__rght__lte')
projects = projects.filter(query)
if building_classification:
query = build_query(building_classification, BuildingClassfication,
'realty__building_classification__lft__gte',
'realty__building_classification__rght__lte')
projects = projects.filter(query)
if construction_type:
projects = projects.filter(realty__construction_type__in=
tuple(filter(None, re.split(r'\s|,|;', construction_type))))
if location:
query = build_query(location, Location,
'realty__location__lft__gte',
'realty__location__rght__lte')
projects = projects.filter(query)
if cro:
projects = projects.filter(cro=True)
return projects
def sort_by(self, projects):
# order_by = request.GET.get('order_by')
# last_order_by = request.GET.get('last_order_by')
# reverse_order = request.GET.get('reverse_order')
# ord = None
# manual_sort = None
#
# # ORDERS
# 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 and ord == 'views':
# projects = natsort.natsorted(projects.all(), key=lambda p: p.hit_count.hits, reverse=reverse_order)
# manual_sort = True
# elif ord:
# projects = projects.order_by('-%s' % ord if reverse_order else ord)
return projects
def pagination(self, projects, page):
paginator = Paginator(projects, settings.PAGE_SIZE)
# print("pag page = ", page)
try:
projects = paginator.page(page)
except PageNotAnInteger:
projects = paginator.page(1)
except EmptyPage:
projects = paginator.page(paginator.num_pages)
return projects
def get_context(self, request):
context = request.dict()
projects = Project.objects.filter(state='active')
projects = self.filter(projects, request)
num_results = projects.count()
projects = self.sort_by(projects)
projects = self.pagination(projects, request.get("page"))
has_additional_fields = bool(context.get("building_classification") or context.get(
"construction_type") or context.get("location") or context.get("cro"))
context.update({
'choices': self.PROJECT_ORDER_CHOICES,
'projects': projects,
'is_paginated': True,
'page_obj': projects,
'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, 'partials/inc-projects-results.html', self.get_context(request.POST))
class SortRealtyBy(View):
def get_context(self):
print("request.POST = ", self.request.POST)
user_id = self.request.POST.get('user_id')
sort_by = self.request.POST.get('sortBy')
state = self.request.POST.get('state')
objects = Realty.objects.filter(user__id=user_id, state=state, is_virtual=False)
if sort_by == 'num_orders':
objects = objects.annotate(num_orders=Count('projects'))
return {"objects": objects.order_by('{}'.format(sort_by))}
def post(self, *args, **kwargs):
return render(self.request, 'partials/inc-objects.html', self.get_context())
class CustomerProjectCreateView(BaseMixin, View):
form_class = CustomerProjectEditFormNew
realty_form = RealtyFormNew
work_type_suggestion_form = ProjectWorkTypeSuggestionForm
template_name = 'customer_project_create.html'
def get_context_data(self, **kwargs):
ctx = super().get_context_data()
# ctx['hide_user_type'] = False
user_form = CustomRegistrationForm()
ctx['user_form'] = user_form
return ctx
def get(self, request, *args, **kwargs):
context = self.get_context_data(**_.merge({}, request.GET, kwargs))
form = self.form_class(request=request)
realty_form = self.realty_form(request=request, prefix='realty_form')
work_type_suggestion_form = self.work_type_suggestion_form(request=request, prefix='work_type_suggestion')
context.update({
'form': form,
'realty_form': realty_form,
'work_type_suggestion_form': work_type_suggestion_form,
})
return render(request, self.template_name, context)
def post(self, request, *args, **kwargs):
form = self.form_class(request.POST, request=request) # Passing `request.FILES` seems unnecessary here. Files are added manually below
print('POST = ', request.POST)
form.is_valid()
realty = form.cleaned_data.get('realty')
if realty:
print("Has Realty")
realty_form = self.realty_form(request.POST, instance=realty, request=request, prefix='realty_form')
else:
print("Create new Realty")
realty_form = self.realty_form(request.POST, request=request, prefix='realty_form')
if form.is_valid() and realty_form.is_valid():
project = form.save(commit=False)
unregister_user = request.POST.get('not_auth_user_id')
if unregister_user:
user = get_object_or_404(User, pk=unregister_user)
else:
user = request.user
project.customer = user
project.save()
form.save_m2m()
Order.objects.create(project=project, secure=project.deal_type == 'secure_deal')
for file in request.FILES.getlist('new_files'):
ProjectFile.objects.create(file=file, project=project)
if not realty:
realty = realty_form.save(commit=False)
realty.user = user
if not request.POST.get('new_realty_name'):
print("Virtual!")
realty.is_virtual = True
print("Set realty name -->", request.POST.get('new_realty_name'))
realty.name = request.POST.get('new_realty_name')
realty.save()
realty_form.save_m2m()
project.realty = realty # Connect a realty with a project
project.save()
messages.info(request, 'Проект успешно создан')
redirect_to = reverse('projects:detail', kwargs={'pk': project.pk})
return redirect(redirect_to)
else:
if form.errors:
messages.info(request, (
'<p>Произошла ошибка (form)</p>'
'<pre>{form}</pre>'
).format(form=pformat(form.errors)))
if realty_form and realty_form.errors:
messages.info(request, (
'<p>Произошла ошибка (realty_form)</p>'
'<pre>{realty_form}</pre>'
).format(realty_form=pformat(realty_form.errors)))
context = self.get_context_data(**kwargs)
context.update({'form': form, 'realty_form': realty_form})
unregister_user = request.POST.get('not_auth_user_id')
if unregister_user:
context.update({'unregister_user': unregister_user})
return render(request, self.template_name, context)
class CustomerProjectEditView(BaseMixin, View):
form_class = CustomerProjectEditForm
realty_form = RealtyForm
work_type_suggestion_form = ProjectWorkTypeSuggestionForm
template_name = 'customer_project_edit.html'
def dispatch(self, request, *args, **kwargs):
if request.user.is_authenticated() and request.user.is_customer():
# Prevent editing when project's taken:
project = get_object_or_404(request.user.customer_projects, pk=kwargs.get('pk'))
if project.order.contractor or project.order.team:
raise PermissionDenied('Заказ уже находится в работе. Вы не можете его редактировать.')
else:
return super().dispatch(request, *args, **kwargs)
raise PermissionDenied
def get(self, request, *args, **kwargs):
project = get_object_or_404(request.user.customer_projects, pk=kwargs.get('pk'))
form = self.form_class(instance=project, request=request)
work_type_suggestion_form = self.work_type_suggestion_form(request=request, prefix='work_type_suggestion')
realty = project.realty
if realty:
realty_form = self.realty_form(instance=project.realty, request=request, prefix='realty_form')
else:
realty_form = self.realty_form(request=request, prefix='realty_form')
context = self.get_context_data(**_.merge({}, request.GET, kwargs))
context.update({
'form': form,
'realty_form': realty_form,
'work_type_suggestion_form': work_type_suggestion_form,
})
return render(request, self.template_name, context)
def post(self, request, *args, **kwargs):
project = get_object_or_404(request.user.customer_projects, pk=kwargs.get('pk'))
form = self.form_class(request.POST, request.FILES, request=request, instance=project)
form.is_valid()
realty = form.cleaned_data.get('realty')
if realty:
realty_form = self.realty_form(request.POST, instance=realty, request=request, prefix='realty_form')
else:
realty_form = self.realty_form(request.POST, request=request, prefix='realty_form')
if form.is_valid() and realty_form.is_valid():
project = form.save(commit=False)
project.customer = request.user
project.files = form.cleaned_data.get(
'files') # TODO: Should we somehow get rid of this explicit assignment?
project.save()
form.save_m2m()
for file in request.FILES.getlist('new_files'):
proj_file = ProjectFile.objects.create(file=file, project=project)
proj_file.save()
if realty:
realty_form.save()
else:
realty = realty_form.save(commit=False)
realty.user = request.user
realty.save()
realty_form.save_m2m()
project.realty = realty # Connect a realty with a project
project.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 realty_form and realty_form.errors:
messages.info(request, (
'<p>Произошла ошибка (realty_form)</p>'
'<pre>{realty_form}</pre>'
).format(realty_form=pformat(realty_form.errors)))
context = self.get_context_data(**kwargs)
context.update({'form': form, 'realty_form': realty_form})
return render(request, self.template_name, context)
class ContractorAnswerArchiveView(View):
def post(self, request, *args, **kwargs):
project_pk = request.POST.get('project_pk')
user_pk = request.POST.get('user_pk')
answer = Answer.objects.filter(project_id=project_pk, object_id=user_pk, content_type__model='user').first()
answer.is_archive = True
answer.save()
redirect_to = request.POST.get('next')
return redirect(redirect_to)
class ContractorPortfolioTrashView(View):
form_class = ContractorPortfolioTrashForm
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):
form_class = CustomerProjectTrashForm
def dispatch(self, request, *args, **kwargs):
if request.user.is_authenticated() and request.user.is_customer():
# Prevent editing when project's taken:
project = get_object_or_404(request.user.customer_projects, pk=kwargs.get('pk'))
if project.order.contractor or project.order.team:
raise PermissionDenied('Заказ уже находится в работе. Вы не можете его переместить в корзину.')
else:
return super().dispatch(request, *args, **kwargs)
raise PermissionDenied
def post(self, req, *args, **kwargs):
form = self.form_class(_.merge({}, req.POST, kwargs), req=req)
if form.is_valid():
project = form.cleaned_data.get('pk')
project.state = 'trashed'
project.save()
messages.info(req, 'Проект перемещён в корзину')
else:
messages.info(req, 'Произошла ошибка: <pre>{msg}</pre>'.format(msg=pformat(form.errors)))
redirect_to = req.POST.get('next')
return redirect(redirect_to)
class AbcCustomerRealityChangeState(ABC, View):
new_state = ''
message_part = ''
def __init__(self, **kwargs):
if self.new_state not in [el[0] for el in Realty.STATES]:
raise AttributeError('new_state must be in {}'.format([el[0] for el in Realty.STATES]))
super().__init__(**kwargs)
# TODO: dispatch вынести в ABC класс
# def dispatch(self, request, *args, **kwargs):
def post(self, request, *args, **kwargs):
realty = get_object_or_404(Realty, pk=kwargs.get("pk"))
realty.state = self.new_state
realty.save()
realty.projects.all().update(state=self.new_state)
messages.info(request, 'Объект и все, связанные с ним проекты, {}'.format(self.message_part))
redirect_to = request.POST.get('next')
return redirect(redirect_to)
class CustomerRealtyTrashView(AbcCustomerRealityChangeState):
new_state = 'trashed'
message_part = 'перемещёны в корзину'
def dispatch(self, request, *args, **kwargs):
if request.user.is_authenticated() and request.user.is_customer():
num_project_in_process = Project.objects.filter(realty__id=kwargs.get('pk')).filter(order__status="process").count()
if num_project_in_process:
raise PermissionDenied('Один или более Заказ, данного Объекта, уже находятся в работе. '
'Вы не можете переместить его в корзину.')
else:
return super().dispatch(request, *args, **kwargs)
raise PermissionDenied
class CustomerRealtyDeleteView(AbcCustomerRealityChangeState):
new_state = 'deleted'
message_part = 'удалены'
def dispatch(self, request, *args, **kwargs):
if request.user.is_authenticated() and request.user.is_customer():
return super().dispatch(request, *args, **kwargs)
else:
raise PermissionDenied
class CustomerRealtyRestoreView(AbcCustomerRealityChangeState):
new_state = 'active'
message_part = 'восстановлены'
def dispatch(self, request, *args, **kwargs):
if request.user.is_authenticated() and request.user.is_customer():
return super().dispatch(request, *args, **kwargs)
else:
raise PermissionDenied
class CustomerProjectRestoreView(View):
form_class = CustomerProjectRestoreForm
def dispatch(self, request, *args, **kwargs):
if request.user.is_authenticated() and request.user.is_customer():
return super().dispatch(request, *args, **kwargs)
else:
raise PermissionDenied
def post(self, req, *args, **kwargs):
form = self.form_class(_.merge({}, req.POST, kwargs), req=req)
if form.is_valid():
project = form.cleaned_data.get('pk')
project.state = 'active'
project.save()
messages.info(req, 'Проект восстановлен из корзины')
else:
messages.info(req, 'Произошла ошибка: <pre>{msg}</pre>'.format(msg=pformat(form.errors)))
redirect_to = req.POST.get('next')
return redirect(redirect_to)
class CustomerProjectDeleteView(View):
form_class = CustomerProjectDeleteForm
def dispatch(self, request, *args, **kwargs):
if request.user.is_authenticated() and request.user.is_customer():
return super().dispatch(request, *args, **kwargs)
else:
raise PermissionDenied
def post(self, req, *args, **kwargs):
form = self.form_class(_.merge({}, req.POST, kwargs), req=req)
if form.is_valid():
project = form.cleaned_data.get('pk')
project.state = 'deleted'
project.save()
messages.info(req, 'Проект удалён навсегда')
else:
messages.info(req, 'Произошла ошибка: <pre>{msg}</pre>'.format(msg=pformat(form.errors)))
redirect_to = req.POST.get('next')
return redirect(redirect_to)
class ProjectComparisonView(DetailView):
model = Project
template_name = 'comparison.html'
def get_context_data(self, **kwargs):
c = super().get_context_data(**kwargs)
c['TERM_TYPE_MORPHS'] = TERM_TYPE_MORPHS
return c
def add_candidate(request, answer_id, project_id):
answer = Answer.objects.get(pk=answer_id)
project = Project.objects.get(pk=project_id)
count_answers = Candidate.objects.filter(project=project).count()
count_answers += 1
candidate = Candidate.objects.filter(answer=answer).first()
if not candidate:
Candidate.objects.create(answer=answer, project=project, position=count_answers)
redirect_to = '%s%s' % (reverse('projects:detail', kwargs={'pk': project_id}), '#answers')
return redirect(redirect_to)
class CandidateDeleteView(DeleteView):
model = Candidate
def get_success_url(self):
return reverse('projects:comparison', kwargs={'pk': self.object.project_id})
def get(self, *args, **kwargs):
return self.post(*args, **kwargs)
def sort_candidates(request):
if request.is_ajax():
items = request.POST.getlist('items[]')
i = 1
for item in items:
candidate = Candidate.objects.get(pk=item)
candidate.position = i
candidate.save()
i += 1
data = {
'success': 'ok',
}
return HttpResponse(json.dumps(data), content_type='application/json')
class CustomerOfferOrderView(View):
template_name = 'chattest.html'
def post(self, request, *args, **kwargs):
# @ Утверждение Исполнителя
project_id = kwargs.get('project_id')
answer_id = kwargs.get('answer_id')
try:
project = Project.objects.get(pk=project_id)
except Project.DoesNotExist:
project = None
try:
answer = Answer.objects.get(pk=answer_id)
except Answer.DoesNotExist:
answer = None
order = project.order
status = None
if not order.contractor and not order.team:
if isinstance(answer.author, User):
order.contractor = answer.author
# order.status = 'process'
# order.save()
# status = True
elif isinstance(answer.author, Team):
order.team = answer.author
order.status = 'process'
order.save()
status = True
if status:
hs_rating = HistoryRating()
hs_rating.user = request.user
hs_rating.rating = 1
hs_rating.type = 'choice_contractor'
hs_rating.description = 'Заказчик выбрал исполнителя'
hs_rating.save()
redirect_url = reverse('chat:chat-user') + '#order' + str(order.pk)
return HttpResponseRedirect(redirect_url)
def contractor_portfolio_create(request): # TODO: pekopt: shit. rewrite using generic
if request.is_ajax():
form = PortfolioForm(data=request.POST)
# import code; code.interact(local=dict(globals(), **locals()))
if form.is_valid():
duplicate = form.cleaned_data.get('duplicate')
instance = form.save(commit=False)
instance.user = request.user
instance.save()
if duplicate:
work_sell = WorkSell()
work_sell.name = instance.name
work_sell.budget = instance.budget
work_sell.building_classification = instance.building_classification
work_sell.construction_type = instance.construction_type
work_sell.currency = instance.currency
work_sell.description = instance.description
work_sell.term = instance.term
work_sell.term_type = instance.term_type
work_sell.contractor = instance.user
work_sell.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
p_photo = PortfolioPhoto()
p_photo.img = temp_file
p_photo.portfolio = instance
p_photo.save()
if duplicate:
w_photo = WorkSellPhoto()
w_photo.img = temp_file
w_photo.worksell = work_sell
w_photo.save()
data = {'status': 'ok'}
else:
data = {'status': 'no', 'form_errors': form.errors}
return HttpResponse(json.dumps(data), content_type='application/json')
else:
raise Http404
class ContractorPortfolioUpdateView(BaseMixin, UpdateView):
model = Portfolio
form_class = PortfolioEditForm
template_name = 'contractor_portfolio_edit.html'
def get_success_url(self):
return reverse('projects:contractor-portfolio-detail', kwargs={'pk': self.object.pk})
def form_valid(self, form):
portfolio = form.instance
photos = form.cleaned_data['photos']
# # Doesn't work:
#
# portfolio.photos = photos
# portfolio.save()
PortfolioPhoto.objects.filter(portfolio=portfolio).delete()
for photo in photos:
PortfolioPhoto.objects.create(img=photo.img, portfolio=portfolio)
live_images = form.cleaned_data['live_images']
for live_image in live_images:
new_image = ContentFile(live_image.file.read())
new_image.name = live_image.file.name
PortfolioPhoto.objects.create(img=new_image, portfolio=portfolio)
live_image.file.delete()
live_image.delete()
return super().form_valid(form)
class PortfolioDelete(DeleteView):
model = Portfolio
success_url = reverse_lazy('users:contractor-profile')
class PortfolioDetail(DetailView):
model = Portfolio
template_name = 'portfolio_detail.html'
def dispatch(self, request, *args, **kwargs):
if not self.get_object().user:
return HttpResponseForbidden('404 Not Found')
return super().dispatch(request, *args, **kwargs)
class ArbitrationCreateView(CreateView):
model = Arbitration
fields = (
'order',
'user',
'text',
)
def form_valid(self, form):
if self.request.is_ajax():
self.object = form.save()
data = {
'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 ProjectWorkTypeSuggestionView(View):
form_class = ProjectWorkTypeSuggestionForm
template_name = 'customer_project_work_type_suggestion.html'
# def get(self, request, *args, **kwargs):
# form = self.form_class(request=request, prefix='work_type_suggestion')
# context = {'form': form}
# return render(request, self.template_name, context)
def post(self, request, *args, **kwargs):
form = self.form_class(request.POST, request=request, prefix='work_type_suggestion')
if form.is_valid():
form.save()
return JsonResponse({'status': 'success'})
else:
form_errors = {'.-error-%s' % bfield.html_name: bfield.errors for bfield in form}
return JsonResponse({
'status': 'error',
'form_errors': form_errors,
})
# import code; code.interact(local=dict(globals(), **locals()))