diff --git a/assets/js/chat.js b/assets/js/chat.js index 1375c1f..c4478b4 100644 --- a/assets/js/chat.js +++ b/assets/js/chat.js @@ -1,6 +1,6 @@ var SocketHandler = function () { domain = domain.replace(':' + port, ''); - var url = 'ws://' + domain + ':8888/chat/' + userId + '/'; + var url = 'ws://' + domain + '/chat/' + userId + '/'; var sock = new WebSocket(url); var intervalId; sock.onopen = function () { diff --git a/chat/templates/chat_contractor.html b/chat/templates/chat_contractor.html index 48081e4..edc5f95 100644 --- a/chat/templates/chat_contractor.html +++ b/chat/templates/chat_contractor.html @@ -47,7 +47,13 @@ {% endthumbnail %}
-
+ {% if contact.is_contractor %} + {% url "users:contractor-profile" pk=contact.pk as contact_url %} + {% else %} + {% url "users:customer-profile-open-projects" pk=contact.pk as contact_url %} + {% endif %} + + Контакты diff --git a/chat/templates/chat_customer.html b/chat/templates/chat_customer.html index a3db522..ac5c268 100644 --- a/chat/templates/chat_customer.html +++ b/chat/templates/chat_customer.html @@ -41,7 +41,12 @@ {% endif %}-
+ {% if contact.is_contractor %} + {% url "users:contractor-profile" pk=contact.pk as contact_url %} + {% else %} + {% url "users:customer-profile-open-projects" pk=contact.pk as contact_url %} + {% endif %} + - +{{ object }}
+ + {% if object.get_prev %} +{{ object.budget }}
#} + {#Описание:
++ {{ object.text }} +
+Похожие работы
#} +{#Произошла ошибка (form)
' '{form}'
).format(form=pformat(form.errors)))
-
+
context.update({'form': form})
return render(request, self.template_name, context)
else:
@@ -133,41 +133,41 @@ class ProjectDetailWithAnswerView(BaseMixin, View):
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:
return HttpResponseForbidden('403 Forbidden')
-
+
def post(self, request, *args, **kwargs):
form = self.form_class(request.POST, request=request)
-
+
if form.is_valid():
message = form.save(commit=False)
-
+
if request.user.is_contractor():
answer = get_object_or_404(Answer, pk=kwargs.get('pk'))
-
+
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):
try: team = request.user.team
except Team.DoesNotExist: team = None
-
+
if team and answer.author == team:
message.contractor_or_team = team
elif request.user.is_customer():
answer = get_object_or_404(Answer, pk=kwargs.get('pk')) # TODO: Perform additional checks
message.answer = answer
message.is_sender_customer = True
-
+
message.save()
form.save_m2m()
-
+
messages.info(request, 'Сообщение успешно размещено')
else:
if form.errors:
@@ -175,7 +175,7 @@ class ProjectAnswerCreateMessageView(BaseMixin, View):
'Произошла ошибка (form)
' '{form}'
).format(form=pformat(form.errors)))
-
+
redirect_to = request.POST.get('next')
return redirect(redirect_to)
@@ -186,19 +186,19 @@ class RejectProjectAnswerView(BaseMixin, View):
return super().dispatch(request, *args, **kwargs)
else:
raise PermissionDenied
-
+
def post(self, request, *args, **kwargs):
if request.user.is_contractor():
answer = get_object_or_404(request.user.contractor_answers, pk=kwargs.get('pk'))
elif request.user.is_customer():
project = get_object_or_404(request.user.projects, answers__pk=kwargs.get('pk'))
answer = get_object_or_404(project.answers, pk=kwargs.get('pk'))
-
+
answer.rejected = True
answer.save()
-
+
messages.info(request, 'Успешный отказ от проекта')
-
+
redirect_to = request.POST.get('next')
return redirect(redirect_to)
@@ -207,107 +207,107 @@ class ProjectFilterView(BaseMixin, View):
template_name = 'project_filter.html'
form_class = ProjectFilterForm
realty_form = ProjectFilterRealtyForm
-
+
def get(self, request, *args, **kwargs):
form = self.form_class(request.GET, request=request)
realty_form = self.realty_form(request.GET, request=request, prefix='realty_form')
context = self.get_context_data(**_.merge({}, request.GET, kwargs))
-
+
projects = Project.objects
-
+
if form.is_valid() and realty_form.is_valid():
ord = None
-
+
keywords = form.cleaned_data.get('keywords')
cro = form.cleaned_data.get('cro')
work_type = form.cleaned_data.get('work_type')
specialization = form.cleaned_data.get('specialization')
-
+
building_classification = realty_form.cleaned_data.get('building_classification')
construction_type = realty_form.cleaned_data.get('construction_type')
location = realty_form.cleaned_data.get('location')
-
+
if keywords:
keywords = tuple(filter(None, re.split(r'\s|,|;', keywords)))
-
+
for k in keywords:
projects = projects.filter(Q(name__icontains=k) | Q(text__icontains=k))
-
+
if cro:
projects = projects.filter(cro=cro)
-
+
if work_type:
projects = projects.filter(work_type=work_type)
-
+
if specialization:
projects = projects.filter(
specialization__lft__gte=specialization.lft,
specialization__rght__lte=specialization.rght,
)
-
+
if building_classification:
projects = projects.filter(realty__building_classification=building_classification)
-
+
if construction_type:
projects = projects.filter(realty__construction_type=construction_type)
-
+
if location:
projects = projects.filter(
realty__location__lft__gte=location.lft,
realty__location__rght__lte=location.rght,
)
-
+
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
-
+
manual_sort = None
-
+
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)
-
+
context.update({
'last_order_by': last_order_by,
'reverse_order': reverse_order,
})
-
+
project_count = len(projects) if manual_sort else projects.count()
display_msg = 'Найдено %s проектов' % project_count if project_count > 0 else 'Ничего не найдено'
else:
display_msg = 'Пожалуйста, введите корректные данные'
-
+
if form.errors:
messages.info(request, (
'Произошла ошибка (form)
' '{form}'
).format(form=pformat(form.errors)))
-
+
if realty_form and realty_form.errors:
messages.info(request, (
'Произошла ошибка (realty_form)
' '{realty_form}'
).format(realty_form=pformat(realty_form.errors)))
-
+
paginator = Paginator(projects if manual_sort else projects.all(), 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,
'realty_form': realty_form,
@@ -316,7 +316,7 @@ class ProjectFilterView(BaseMixin, View):
'page_obj': projects,
'display_msg': display_msg,
})
-
+
return render(request, self.template_name, context)
@@ -324,44 +324,44 @@ class CustomerProjectCreateView(BaseMixin, View):
form_class = CustomerProjectEditForm
realty_form = RealtyForm
template_name = 'customer_project_create.html'
-
+
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 get(self, request, *args, **kwargs):
form = self.form_class(request=request)
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})
-
+
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
-
+
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.save()
form.save_m2m()
-
+
Order.objects.create(project=project)
-
+
for file in request.FILES.getlist('new_files'):
ProjectFile.objects.create(file=file, project=project)
-
+
if realty:
realty_form.save()
else:
@@ -369,10 +369,10 @@ class CustomerProjectCreateView(BaseMixin, View):
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 = reverse('projects:detail', kwargs={'pk': project.pk})
return redirect(redirect_to)
@@ -382,13 +382,13 @@ class CustomerProjectCreateView(BaseMixin, View):
'Произошла ошибка (form)
' '{form}'
).format(form=pformat(form.errors)))
-
+
if realty_form and realty_form.errors:
messages.info(request, (
'Произошла ошибка (realty_form)
' '{realty_form}'
).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)
@@ -398,7 +398,7 @@ class CustomerProjectEditView(BaseMixin, View):
form_class = CustomerProjectEditForm
realty_form = RealtyForm
template_name = 'customer_project_edit.html'
-
+
def dispatch(self, request, *args, **kwargs):
if request.user.is_authenticated() and request.user.is_customer():
return super().dispatch(request, *args, **kwargs)
@@ -408,42 +408,42 @@ class CustomerProjectEditView(BaseMixin, View):
def get(self, request, *args, **kwargs):
project = get_object_or_404(request.user.projects, pk=kwargs.get('pk'))
form = self.form_class(instance=project, request=request)
-
+
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})
-
+
return render(request, self.template_name, context)
-
+
def post(self, request, *args, **kwargs):
project = get_object_or_404(request.user.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:
@@ -451,10 +451,10 @@ class CustomerProjectEditView(BaseMixin, View):
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)
@@ -464,13 +464,13 @@ class CustomerProjectEditView(BaseMixin, View):
'Произошла ошибка (form)
' '{form}'
).format(form=pformat(form.errors)))
-
+
if realty_form and realty_form.errors:
messages.info(request, (
'Произошла ошибка (realty_form)
' '{realty_form}'
).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)
@@ -506,41 +506,41 @@ class ContractorPortfolioTrashView(View):
class CustomerProjectTrashView(View):
form_class = CustomerProjectTrashForm
-
+
def dispatch(self, request, *args, **kwargs):
if request.user.is_authenticated() and request.user.is_customer():
return super().dispatch(request, *args, **kwargs)
else:
return HttpResponseForbidden('403 Forbidden')
-
+
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, 'Произошла ошибка: {msg}'.format(msg=pformat(form.errors)))
-
+
redirect_to = req.POST.get('next')
return redirect(redirect_to)
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:
return HttpResponseForbidden('403 Forbidden')
-
+
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'
@@ -549,23 +549,23 @@ class CustomerProjectRestoreView(View):
messages.info(req, 'Проект восстановлен из корзины')
else:
messages.info(req, 'Произошла ошибка: {msg}'.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:
return HttpResponseForbidden('403 Forbidden')
-
+
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'
@@ -573,7 +573,7 @@ class CustomerProjectDeleteView(View):
messages.info(req, 'Проект удалён навсегда')
else:
messages.info(req, 'Произошла ошибка: {msg}'.format(msg=pformat(form.errors)))
-
+
redirect_to = req.POST.get('next')
return redirect(redirect_to)
@@ -650,7 +650,7 @@ class OfferOrderView(View):
return HttpResponseRedirect(redirect_url)
-def contractor_portfolio_create(request):
+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()))
@@ -707,4 +707,11 @@ class PortfolioDelete(DeleteView):
model = Portfolio
success_url = reverse_lazy('users:contractor-profile')
+
+class PortfolioDetail(DetailView):
+ model = Portfolio
+ template_name = 'portfolio_detail.html'
+
+
+
# import code; code.interact(local=dict(globals(), **locals()))
diff --git a/templates/partials/header.html b/templates/partials/header.html
index 4624e77..34bd116 100644
--- a/templates/partials/header.html
+++ b/templates/partials/header.html
@@ -107,12 +107,12 @@
Счет
- {{ team.name }} + {{ team.name }} {# TODO #}
{{ p.name }}
- + {{ p }} {% if request.user.pk == contractor.pk %}{{ ws }}
- + {{ ws }} {% if request.user.pk == contractor.pk %}