#ARC-26 Fixes (section 1)

remotes/origin/PR-39
ArturBaybulatov 10 years ago
parent 0a7055358d
commit 71dd79518f
  1. 2
      archilance/settings/base.py
  2. 2
      projects/models.py
  3. 13
      projects/views.py
  4. 34
      templates/message.html
  5. 5
      templates/partials/base.html
  6. 4
      templates/partials/pagination.html
  7. 5
      users/forms.py
  8. 9
      users/templates/contractor_office.html
  9. 106
      users/templates/contractor_office_open_projects.html
  10. 95
      users/templates/contractor_office_open_projects_archive.html
  11. 25
      users/templates/partials/contractor_profile_tabs.html
  12. 89
      users/views.py

@ -12,7 +12,7 @@ SECRET_KEY = 'vb6@b9zj7^f!^+x*e8=e!oundyu1!e*&0i(3gu2xwo4%fx4h&n'
# SECURITY WARNING: don't run with debug turned on in production!
DEBUG = True
TEMPLATE_DEBUG = False # Show debug info in templates. See `projects/templates/project_filter.html`
TEMPLATE_DEBUG = True # Show debug info in templates. See `projects/templates/project_filter.html`
ALLOWED_HOSTS = []

@ -84,7 +84,7 @@ class Project(models.Model, HitCountMixin):
created = models.DateTimeField(default=timezone.now)
cro = models.BooleanField(default=False)
currency = models.CharField(max_length=20, default='rur', choices=CURRENCIES)
customer = models.ForeignKey(User, related_name='projects')
customer = models.ForeignKey(User, related_name='projects') # Related name should've been "customer_projects"
deal_type = models.CharField(max_length=20, default='secure_deal', choices=DEAL_TYPES)
name = models.CharField(max_length=255)
price_and_term_required = models.BooleanField(default=False)

@ -1,5 +1,4 @@
from django.conf import settings
from django.core.exceptions import PermissionDenied
from django.contrib import messages
from django.contrib.auth.mixins import PermissionRequiredMixin, LoginRequiredMixin
from django.core.exceptions import PermissionDenied
@ -10,7 +9,6 @@ from django.db.models import Q, F
from django.http import HttpResponseForbidden, HttpResponseRedirect, HttpResponse, Http404
from django.shortcuts import render, get_object_or_404, redirect
from django.views.generic import ListView, DetailView, CreateView, DeleteView, View, UpdateView, TemplateView, FormView
from hitcount.models import HitCount
from hitcount.views import HitCountMixin
from pprint import pprint, pformat
@ -128,7 +126,7 @@ class ProjectDetailWithAnswerView(BaseMixin, View):
context.update({'form': form})
return render(request, self.template_name, context)
else:
return HttpResponseForbidden('403 Forbidden')
raise PermissionDenied
class ProjectAnswerCreateMessageView(BaseMixin, View):
@ -138,7 +136,7 @@ class ProjectAnswerCreateMessageView(BaseMixin, View):
if request.user.is_authenticated():
return super().dispatch(request, *args, **kwargs)
else:
return HttpResponseForbidden('403 Forbidden')
raise PermissionDenied
def post(self, request, *args, **kwargs):
form = self.form_class(request.POST, request=request)
@ -515,7 +513,7 @@ class CustomerProjectTrashView(View):
if request.user.is_authenticated() and request.user.is_customer():
return super().dispatch(request, *args, **kwargs)
else:
return HttpResponseForbidden('403 Forbidden')
raise PermissionDenied
def post(self, req, *args, **kwargs):
form = self.form_class(_.merge({}, req.POST, kwargs), req=req)
@ -540,7 +538,7 @@ class CustomerProjectRestoreView(View):
if request.user.is_authenticated() and request.user.is_customer():
return super().dispatch(request, *args, **kwargs)
else:
return HttpResponseForbidden('403 Forbidden')
raise PermissionDenied
def post(self, req, *args, **kwargs):
form = self.form_class(_.merge({}, req.POST, kwargs), req=req)
@ -565,7 +563,7 @@ class CustomerProjectDeleteView(View):
if request.user.is_authenticated() and request.user.is_customer():
return super().dispatch(request, *args, **kwargs)
else:
return HttpResponseForbidden('403 Forbidden')
raise PermissionDenied
def post(self, req, *args, **kwargs):
form = self.form_class(_.merge({}, req.POST, kwargs), req=req)
@ -717,5 +715,4 @@ class PortfolioDetail(DetailView):
template_name = 'portfolio_detail.html'
# import code; code.interact(local=dict(globals(), **locals()))

@ -1,11 +1,37 @@
{% extends 'partials/base.html' %}
{% block head %}
<meta http-equiv="refresh" content="15;URL='{% url 'wallets:score-detail' pk=request.user.pk %}'">
{% endblock %}
{% block content %}
<div class='container-fluid'>
<div class='row'>
<div class='col-xs-12' style='margin-top: 15px'>
<h1 style="text-align: center">{{ message }}</h1>
{% include 'partials/header.html' %}
<div class="container mainScore">
<div class="row">
<div class='col-xs-12' style='margin-top: 15px; text-align: center'>
<h1>{{ message }}</h1>
{% if request.user.is_authenticated %}
<div>
<a href="{% url 'wallets:score-detail' pk=request.user.pk %}">
Вернуться на страницу личного счёта
</a>
(автоматически через 15 секунд)
</div>
{% endif %}
</div>
{% include 'partials/footer.html' %}
</div>
</div>
{% endblock %}
{% block js_block %}
<script>
setTimeout(function() {
window.location.href = '{% url 'wallets:score-detail' pk=request.user.pk %}'
}, 15000)
</script>
{% endblock %}

@ -1,4 +1,6 @@
{% load staticfiles %}
{% load compress %}
<!doctype html>
<html>
@ -8,8 +10,9 @@
<meta name='viewport' content='width=device-width, initial-scale=1'>
<!--<meta name='viewport' content='initial-scale=1.0, user-scalable=no, maximum-scale=1'>-->
{% block head %}{% endblock %}
<title>Archilance</title>
{% load compress %}
{% compress css %}
<link rel='stylesheet' href='{% static "lib/jquery-ui/jquery-ui.css" %}'>

@ -53,9 +53,9 @@
<script>
function paginateTo(pageNum) {
var urlObj = new URI(location.href)
var urlObj = new URI(window.location.href)
urlObj.setQuery('page', pageNum)
location.href = urlObj.href()
window.location.href = urlObj.href()
}
</script>
{% endif %}

@ -9,9 +9,9 @@ from specializations.models import Specialization
class TeamForm(forms.ModelForm):
class Meta:
model = Team
fields = (
'name',
'owner',
@ -19,15 +19,14 @@ class TeamForm(forms.ModelForm):
class ContractorResumeForm(forms.ModelForm):
class Meta:
model = ContractorResume
fields = (
'text',
)
class ContractorResumeFilesForm(forms.ModelForm):
class Meta:
model = ContractorResumeFiles

@ -1,9 +1,9 @@
{% extends 'partials/base.html' %}
{% load staticfiles %}
{% load specializtions_tags %}
{% load thumbnail %}
{% block content %}
{% include 'partials/header.html' %}
@ -12,7 +12,9 @@
<div class="col-lg-12">
<p class="titleScore">Личный кабинет</p>
</div>
{% include 'partials/contractor_profile_tabs.html' with contractor_pk=request.user.pk active='groups' %}
{% include 'partials/contractor_profile_tabs.html' %}
<div class="buttonGP disTab">
<div class="btn-group valProject2 val-pro3" role="group" aria-label="...">
<button type="button" class="btn btn-default">
@ -55,6 +57,7 @@
</div>
</div>
</div>
{% if contractor.is_owner_team %}
<div class="projectsBlock disTab">
<div class="col-lg-12">
@ -255,8 +258,8 @@
</div>
</div>
</div>
{% endif %}
{% include 'partials/footer.html' %}
</div>
</div>

@ -1,9 +1,9 @@
{% extends 'partials/base.html' %}
{% load staticfiles %}
{% load specializtions_tags %}
{% load thumbnail %}
{% block content %}
{% include 'partials/header.html' %}
@ -12,85 +12,103 @@
<div class="col-lg-12">
<p class="titleScore">Личный кабинет</p>
</div>
{% include 'partials/contractor_profile_tabs.html' with contractor_pk=request.user.pk active='open' all_project_count=projects_count %}
{% include 'partials/contractor_profile_tabs.html' %}
<div class="buttonGP disTab">
<div class="btn-group valProject2" role="group" aria-label="...">
<a href="{% url 'users:contractor-office-open-projects' pk=request.user.pk %}" class="btn btn-default">Все</a>
<a href="{% url 'users:contractor-office-open-projects' pk=request.user.pk %}?owner=private" class="btn btn-default">Личные</a>
<a href="{% url 'users:contractor-office-open-projects' pk=request.user.pk %}?owner=teams" class="btn btn-default">От именни группы</a>
<div class="btn-group valProject2" role="group">
<a href="#" onclick="query('owner', ''); return false" class="btn btn-default">Все</a>
<a href="#" onclick="query('owner', 'private'); return false" class="btn btn-default">Личные</a>
<a href="#" onclick="query('owner', 'teams'); return false" class="btn btn-default">От именни группы</a>
</div>
<div class="btn-group valProject2" role="group" aria-label="...">
<button type="button" class="btn btn-default">
<div class="btn-group valProject2" role="group">
<a href="#" onclick="query('archived', ''); return false" class="btn btn-default">
Открытые проекты
<span><mark>{{ current_projects_count }}</mark> / <span>{{ projects_count }}</span></span>
</button>
<button type="button" class="btn btn-default">
<span><mark>0</mark> / <span>{{ active_project_count }}</span></span>
</a>
<a href="#" onclick="query('archived', 'on'); return false" class="btn btn-default">
Архив
<span><mark></mark><span>{{ archive_count }}</span></span>
</button>
<span><mark></mark><span>{{ archived_project_count }}</span></span>
</a>
</div>
</div>
<div class="projectsBlock disTab">
{% for proj in open_projects %}
{% for project in projects %}
<div class="projectPro clearfix">
<div class="col-lg-9 leftPro">
<a href="{% url 'projects:detail' proj.pk %}">
<p class="titlePro">
{{ proj }}
</p>
<a href="{% url 'projects:detail' project.pk %}">
<p class="titlePro">{{ project.name }}</p>
</a>
<ul class="desPro">
<li>
Объект "{{ proj.realty.name }}"
</li>
<li>Объект "{{ project.realty.name }}"</li>
</ul>
<p class="textPro">
</p>
<p class="textPro">{{ project.text|linebreaksbr|truncatechars:300 }}</p>
{% if TEMPLATE_DEBUG %}
<pre><!--
--><b>State:</b> {{ project.state }}<br><!--
--><br><!--
--><b>Specialization:</b> {{ proj.specialization }}<br><!--
--><br><!--
--><b>Realty location:</b> {{ proj.realty.location }}<br><!--
--><br><!--
--><b>Constr. type:</b> {{ proj.realty.construction_type }}<br><!--
--><br><!--
--><b>Build. classif.:</b> {{ proj.realty.building_classification }}<br><!--
--></pre>
{% endif %}
<ul class="listPro">
<li>
{{ proj.created }}
</li>
<li>
0
</li>
<li>
0
</li>
<li>
{{ proj.customer.username }}
</li>
<li>{{ project.created }}</li>
<li>{{ project.hit_count.hits }}</li>
<li>{{ project.answers.count }}</li>
<li>{{ project.customer.username }}</li>
</ul>
</div>
<div class="col-lg-3 rightPro">
<p class="cenaPro">
{{ proj.budget }} <i class="fa fa-rub"></i>
{{ project.budget }} <i class="fa fa-rub"></i>
</p>
<ul>
{% if proj.cro %}
{% if proj.secure_deal %}
<li>Безопасная сделка</li>
{% endif %}
<li>
Безопасная сделка
{{ project.specialization.name }}
</li>
{% endif %}
<li>
<form action="{% url 'projects:contractor-answer-archive' %}" method="POST" novalidate>
{% csrf_token %}
<input type="hidden" name="next" value="{{ request.path }}">
<input type="hidden" name="project_pk" value="{{ proj.pk }}">
<input type="hidden" name="user_pk" value="{{ request.user.pk }}">
<input type="hidden" name="project_pk" value="{{ project.pk }}">
<input type="hidden" name="user_pk" value="{{ contractor.pk }}">
<a href="#" onclick="$(this).closest('form').submit(); return false">Отказаться и переместить в архив</a>
</form>
</li>
</ul>
</div>
</div>
{% endfor %}
</div>
{% include 'partials/footer.html' %}
</div>
</div>
<script>
function query(paramName, paramVal) {
var urlObj = new URI(window.location.href)
paramVal === '' ? urlObj.removeQuery(paramName) : urlObj.setQuery(paramName, paramVal)
window.location.href = urlObj.href()
}
</script>
{% endblock %}

@ -1,95 +0,0 @@
{% extends 'partials/base.html' %}
{% load staticfiles %}
{% load specializtions_tags %}
{% load thumbnail %}
{% block content %}
{% include 'partials/header.html' %}
<div class="container mainScore" >
<div class="row">
<div class="col-lg-12">
<p class="titleScore">Личный кабинет</p>
</div>
{% include 'partials/contractor_profile_tabs.html' with contractor_pk=request.user.pk active='open' all_project_count=projects_count %}
<div class="buttonGP disTab">
<div class="btn-group valProject2" role="group" aria-label="...">
<a href="{% url 'users:contractor-office-open-projects' pk=request.user.pk %}" class="btn btn-default">Все</a>
<a href="{% url 'users:contractor-office-open-projects' pk=request.user.pk %}?owner=private" class="btn btn-default">Личные</a>
<a href="{% url 'users:contractor-office-open-projects' pk=request.user.pk %}?owner=teams" class="btn btn-default">От именни группы</a>
</div>
<div class="btn-group valProject2" role="group" aria-label="...">
<button type="button" class="btn btn-default">
Открытые проекты
<span><mark>{{ current_projects_count }}</mark> / <span>{{ projects_count }}</span></span>
</button>
<button type="button" class="btn btn-default">
Архив
<span><mark></mark><span>{{ archive_count }}</span></span>
</button>
</div>
</div>
<div class="projectsBlock disTab">
{% for proj in open_projects %}
<div class="projectPro clearfix">
<div class="col-lg-9 leftPro">
<a href="{% url 'projects:detail' proj.pk %}">
<p class="titlePro">
{{ proj }}
</p>
</a>
<ul class="desPro">
<li>
Объект "{{ proj.realty.name }}"
</li>
</ul>
<p class="textPro">
</p>
<ul class="listPro">
<li>
{{ proj.created }}
</li>
<li>
0
</li>
<li>
0
</li>
<li>
{{ proj.customer.username }}
</li>
</ul>
</div>
<div class="col-lg-3 rightPro">
<p class="cenaPro">
{{ proj.budget }} <i class="fa fa-rub"></i>
</p>
<ul>
{% if proj.cro %}
<li>
Безопасная сделка
</li>
{% endif %}
<li>
<form action="{% url 'projects:contractor-answer-archive' %}" method="POST" novalidate>
{% csrf_token %}
<input type="hidden" name="next" value="{{ request.path }}">
<input type="hidden" name="project_pk" value="{{ proj.pk }}">
<input type="hidden" name="user_pk" value="{{ request.user.pk }}">
<a href="#" onclick="$(this).closest('form').submit(); return false">Отказаться и переместить в архив</a>
</form>
</li>
</ul>
</div>
</div>
{% endfor %}
</div>
{% include 'partials/footer.html' %}
</div>
</div>
{% endblock %}

@ -1,27 +1,30 @@
{% url 'users:contractor-office' pk=contractor.pk as contractor_office_url %}
{% url 'users:contractor-office-open-projects' pk=contractor.pk as contractor_office_open_projects_url %}
<div class="profileTabs">
<ul class="nav nav-tabs nav-justified">
<li role="presentation">
<a href="{% url 'users:contractor-filter' %}">Поиск исполнителей</a>
</li>
<li role="presentation" {% if active == 'groups' %}class="active"{% endif %}>
<a href="{% url 'users:contractor-office' pk=contractor_pk %}" >
Мои группы
</a>
<div class="roundsCount">
</div>
<li role="presentation" {% if request.path == contractor_office_url %}class="active"{% endif %}>
<a href="{{ contractor_office_url }}">Мои группы</a>
<div class="roundsCount"></div>
</li>
<li role="presentation" {% if active == 'open' %}class="active"{% endif %}>
<a href="{% url 'users:contractor-office-open-projects' pk=contractor_pk %}" >Открытые проекты</a>
<span class="desPresent">
в процессе обсуждения
</span>
<li role="presentation" {% if request.path == contractor_office_open_projects_url %}class="active"{% endif %}>
<a href="{{ contractor_office_open_projects_url }}" >Открытые проекты</a>
<span class="desPresent">в процессе обсуждения</span>
<div class="roundsCount">
<div class="countR">0</div>
<div class="countG">{{ all_project_count }}</div>
</div>
</li>
<li role="presentation">
<a href="{% url 'chat:chat-user' %}">Проекты в работе</a>
<div class="roundsCount">
<div class="countG">0</div>
</div>

@ -1,16 +1,14 @@
from .models import ContractorResume, ContractorResumeFiles
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.mail import send_mail
from django.core.paginator import Paginator, EmptyPage, PageNotAnInteger
from django.core.urlresolvers import reverse
from django.db.models import Q
from django.http import HttpResponse, HttpResponseForbidden
from django.http import JsonResponse, Http404
from django.http import HttpResponse, HttpResponseForbidden, JsonResponse, Http404
from django.shortcuts import render, get_object_or_404, redirect
from django.views.generic import ListView, DetailView, View, UpdateView, CreateView
from django.views.generic import UpdateView
from pprint import pprint, pformat
import itertools
import json
@ -18,7 +16,7 @@ import natsort
import pydash as _; _.map = _.map_; _.filter = _.filter_
from .mixins import CheckForUserMixin
from .models import User, Team, UserFinancialInfo
from .models import User, Team, UserFinancialInfo, ContractorResume, ContractorResumeFiles
from .forms import TeamForm, ContractorResumeFilesForm, ContractorResumeForm
from archilance import util
from archilance.mixins import BaseMixin
@ -32,8 +30,8 @@ from work_sell.models import WorkSell, Picture
from .forms import (
ContractorFilterForm,
CustomerProfileProjectRealtyForm,
UserProfileBasicInfoEditForm,
UserFinancialInfoEditForm,
UserProfileBasicInfoEditForm,
UserProfileEditForm,
)
@ -46,7 +44,7 @@ class UserProfileEditView(BaseMixin, View):
if request.user.is_authenticated() and request.user.pk == int(kwargs.get('pk')):
return super().dispatch(request, *args, **kwargs)
else:
return HttpResponseForbidden('403 Forbidden')
raise PermissionDenied
def get(self, request, *args, **kwargs):
context = self.get_context_data(**_.merge({}, request.GET, kwargs))
@ -90,7 +88,7 @@ class UserFinancialInfoEditView(BaseMixin, View):
if request.user.is_authenticated() and request.user.pk == int(kwargs.get('pk')):
return super().dispatch(request, *args, **kwargs)
else:
return HttpResponseForbidden('403 Forbidden')
raise PermissionDenied
def get(self, request, *args, **kwargs):
context = self.get_context_data(**_.merge({}, request.GET, kwargs))
@ -386,55 +384,47 @@ class ContractorOfficeDetailView(DetailView):
class ContractorOfficeOpenProjectsView(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() and request.user.pk == int(kwargs.get('pk')):
if request.user.is_authenticated():
return super().dispatch(request, *args, **kwargs)
else:
raise PermissionDenied
def get(self, request, *args, **kwargs):
context = self.get_context_data(**_.merge({},request.GET, kwargs))
context = self.get_context_data(**kwargs)
contractor = get_object_or_404(User.contractor_objects, pk=kwargs.get('pk'))
owner = request.GET.get('owner')
# import code; code.interact(local=dict(globals(), **locals()))
if owner and owner == 'private':
all_project_ids = [a.project.pk for a in contractor.contractor_answers.filter(is_archive=False)]
elif owner and owner == 'teams':
all_project_ids = [a.project.pk for a in contractor.team.answers.filter(is_archive=False)]
context['contractor'] = contractor
private_projects = tuple(a.project for a in contractor.contractor_answers.all())
private_project_count = len(private_projects)
team_projects = tuple(a.project for a in contractor.team.answers.all())
team_project_count = len(team_projects)
context['all_project_count'] = private_project_count + team_project_count
if request.GET.get('owner') == 'private':
projects = private_projects
elif request.GET.get('owner') == 'teams':
projects = team_projects
else:
team_project_ids = [a.project.pk for a in contractor.team.answers.filter(is_archive=False)]
contractor_project_ids = [a.project.pk for a in contractor.contractor_answers.filter(is_archive=False)]
all_project_ids = contractor_project_ids + team_project_ids
open_projects = Project.objects.filter(pk__in=all_project_ids)
archive_contractor_count = contractor.contractor_answers.filter(is_archive=True).count()
archive_team_count = contractor.team.answers.filter(is_archive=True).count()
archive_count = archive_contractor_count + archive_team_count
context.update({
'open_projects': open_projects,
'projects_count': len(open_projects),
'current_projects_count': len(open_projects),
'archive_count': archive_count,
})
return render(request, self.template_name, context)
projects = itertools.chain(private_projects, team_projects)
active_projects = _.filter(projects, lambda p: p.state == 'active')
context['active_project_count'] = len(active_projects)
class ContractorOfficeOpenProjectsArchiveView(BaseMixin,View):
template_name = 'contractor_office_open_projects_archive.html'
archived_projects = _.filter(projects, lambda p: p.state == 'trashed')
context['archived_project_count'] = len(archived_projects)
def get(self, request, *args, **kwargs):
context = self.get_context_data(**_.merge({},request.GET, kwargs))
contractor = get_object_or_404(User.contractor_objects,pk=kwargs.get('pk'))
owner = request.GET.get('owner')
# import code; code.interact(local=dict(globals(), **locals()))
if owner and owner == 'private':
all_project_ids = [a.project.pk for a in contractor.contractor_answers.all()]
elif owner and owner == 'teams':
all_project_ids = [a.project.pk for a in contractor.team.answers.all()]
if request.GET.get('archived') == 'on':
projects = archived_projects
else:
team_project_ids = [a.project.pk for a in contractor.team.answers.all()]
contractor_project_ids = [a.project.pk for a in contractor.contractor_answers.all()]
all_project_ids = contractor_project_ids + team_project_ids
projects = active_projects
context['projects'] = projects
open_projects = Project.objects.filter(pk__in=all_project_ids)
context.update({
'open_projects': open_projects,
'projects_count': len(open_projects),
})
return render(request, self.template_name, context)
@ -644,3 +634,4 @@ class CustomerProfileReviewsView(BaseMixin, View):
return render(request, self.template_name, context)
# import code; code.interact(local=dict(globals(), **locals()))

Loading…
Cancel
Save