remotes/origin/PR-39
Mukhtar 10 years ago
commit f7b25a91c4
  1. 5
      common/templatetags/common_tags.py
  2. 6
      projects/templates/project_detail.html
  3. 35
      projects/templates/project_filter.html
  4. 10
      projects/templatetags/project_tags.py
  5. 18
      projects/views.py
  6. 75
      users/templates/contractor_office_open_projects.html
  7. 4
      users/urls.py
  8. 45
      users/views.py

@ -76,6 +76,11 @@ def basename(val):
return os.path.basename(val)
@register.filter
def pk(obj):
return obj.pk
@register.simple_tag
def lorem(*args, **kwargs):
return util.lorem(*args, **kwargs)

@ -248,7 +248,7 @@
<form action="{% url 'projects:reject-project-answer' pk=answer.pk %}" method="POST" novalidate>
{% csrf_token %}
<input type="hidden" name="next" value="{{ request.path }}">
<a href="#" onclick="$(this).closest('form').submit(); return false" class="candLink candLink3">отказ</a>
<a href="#" onclick="$(this).closest('form').submit(); return false" class="candLink candLink3" title="{{ answer.pk }}">отказ</a>
</form>
</div>
@ -593,7 +593,7 @@
<form action="{% url 'projects:reject-project-answer' pk=answer.pk %}" method="POST" novalidate>
{% csrf_token %}
<input type="hidden" name="next" value="{{ request.path }}">
<a href="#" onclick="$(this).closest('form').submit(); return false" class="candLink candLink3">отказ</a>
<a href="#" onclick="$(this).closest('form').submit(); return false" class="candLink candLink3" title="{{ answer.pk }}">отказ</a>
</form>
</div>
@ -747,7 +747,7 @@
<form action="{% url 'projects:reject-project-answer' pk=answer.pk %}" method="POST" novalidate>
{% csrf_token %}
<input type="hidden" name="next" value="{{ request.path }}">
<a href="#" onclick="$(this).closest('form').submit(); return false" class="candLink candLink3">отказ</a>
<a href="#" onclick="$(this).closest('form').submit(); return false" class="candLink candLink3" title="{{ answer.pk }}">отказ</a>
</form>
</div>

@ -173,54 +173,55 @@
<div class="projectsBlock disTab">
{% for proj in projects %}
{% for project in projects %}
<div class="projectPro clearfix">
<div class="col-lg-9 leftPro">
<p class="titlePro">
<a href="{% url 'projects:detail' pk=proj.pk %}">{{ proj }}</a>
<a href="{% url 'projects:detail' pk=project.pk %}">{{ project.name }}</a>
</p>
<ul class="desPro">
<li>
Объект "{{ proj.realty.name }}"
Объект "{{ project.realty.name }}"
</li>
</ul>
<p class="textPro">{{ proj.text|linebreaksbr|truncatechars:300 }}</p>
<p class="textPro">{{ project.text|linebreaksbr|truncatechars:300 }}</p>
{% if TEMPLATE_DEBUG %}
<pre><!--
-->{{ proj|inspect }}<br><!--
--><b>Specialization:</b> {{ project.specialization }}<br><!--
--><br><!--
--><b>Specialization:</b> {{ proj.specialization }}<br><!--
--><b>Realty location:</b> {{ project.realty.location }}<br><!--
--><br><!--
--><b>Realty location:</b> {{ proj.realty.location }}<br><!--
--><b>Constr. type:</b> {{ project.realty.construction_type }}<br><!--
--><br><!--
--><b>Constr. type:</b> {{ proj.realty.construction_type }}<br><!--
--><br><!--
--><b>Build. classif.:</b> {{ proj.realty.building_classification }}<br><!--
--><b>Build. classif.:</b> {{ project.realty.building_classification }}<br><!--
--></pre>
{% endif %}
<ul class="listPro">
<li>{{ proj.created }}</li>
<li>{{ proj.hit_count.hits }}</li>
<li>{{ proj.answers.count }}</li>
<li>{{ project.created }}</li>
<li>{{ project.hit_count.hits }}</li>
<li>{{ project.answers.count }}</li>
{% if request.user.is_authenticated %}
<li>{{ proj.customer.username }}</li>
<li>{{ project.customer.username }}</li>
{% endif %}
</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.secure_deal %}
{% if project.secure_deal %}
<li>Безопасная сделка</li>
{% endif %}
<li>
{{ proj.specialization.name }}
{{ project.specialization.name }}
</li>
</ul>
</div>

@ -1,5 +1,6 @@
from django import template
from pprint import pprint, pformat
import pydash as _; _.map = _.map_; _.filter = _.filter_
from archilance import util
@ -22,5 +23,14 @@ def get_candidate_answers(project):
def get_rejected_answers(project):
return project.answers.filter(rejected=True)
@register.filter
def get_answer(project, contractor):
answer = _.find(project.answers.all(), lambda a: a.author == contractor)
if not answer:
answer = _.find(project.answers.all(), lambda a: a.author == contractor.team)
return answer
# import code; code.interact(local=dict(globals(), **locals()))

@ -19,6 +19,7 @@ import re
from .mixins import LastAccessMixin
from .models import Project, ProjectFile, Portfolio, PortfolioPhoto, Candidate, Answer, AnswerFile, AnswerMessage, Realty, Order
from archilance import util
from archilance.mixins import BaseMixin
from users.models import User, Team
from work_sell.models import Picture, WorkSell, WorkSellPhoto
@ -187,16 +188,25 @@ class RejectProjectAnswerView(BaseMixin, View):
def post(self, request, *args, **kwargs):
if request.user.is_contractor():
answer = get_object_or_404(request.user.contractor_answers, pk=kwargs.get('pk'))
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.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)

@ -1,5 +1,6 @@
{% extends 'partials/base.html' %}
{% load project_tags %}
{% load specializtions_tags %}
{% load thumbnail %}
@ -17,18 +18,18 @@
<div class="buttonGP disTab">
<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>
<a href="#" data-param-name="owner" data-default onclick="return false" class="btn btn-default -nav">Все</a>
<a href="#" data-param-name="owner" data-param-val="private" onclick="return false" class="btn btn-default -nav">Личные</a>
<a href="#" data-param-name="owner" data-param-val="teams" onclick="return false" class="btn btn-default -nav">От именни группы</a>
</div>
<div class="btn-group valProject2" role="group">
<a href="#" onclick="query('archived', ''); return false" class="btn btn-default">
<a href="#" data-param-name="archived" data-default onclick="return false" class="btn btn-default -nav">
Открытые проекты
<span><mark>0</mark> / <span>{{ active_project_count }}</span></span>
</a>
<a href="#" onclick="query('archived', 'on'); return false" class="btn btn-default">
<a href="#" data-param-name="archived" data-param-val="on" onclick="return false" class="btn btn-default -nav">
Архив
<span><mark></mark><span>{{ archived_project_count }}</span></span>
</a>
@ -53,13 +54,15 @@
<pre><!--
--><b>State:</b> {{ project.state }}<br><!--
--><br><!--
--><b>Specialization:</b> {{ proj.specialization }}<br><!--
--><b>Specialization:</b> {{ project.specialization }}<br><!--
--><br><!--
--><b>Realty location:</b> {{ proj.realty.location }}<br><!--
--><b>Answer author:</b> {{ project|get_answer:contractor }}<br><!--
--><br><!--
--><b>Constr. type:</b> {{ proj.realty.construction_type }}<br><!--
--><b>Realty location:</b> {{ project.realty.location }}<br><!--
--><br><!--
--><b>Build. classif.:</b> {{ proj.realty.building_classification }}<br><!--
--><b>Constr. type:</b> {{ project.realty.construction_type }}<br><!--
--><br><!--
--><b>Build. classif.:</b> {{ project.realty.building_classification }}<br><!--
--></pre>
{% endif %}
@ -85,13 +88,14 @@
{{ project.specialization.name }}
</li>
<li>
<form action="{% url 'projects:contractor-answer-archive' %}" method="POST" novalidate>
<li class="-hide-if-archived" style="display: none">
<form action="{% url 'projects:reject-project-answer' pk=project|get_answer:contractor|pk %}" method="POST" novalidate>
{% csrf_token %}
<input type="hidden" name="next" value="{{ request.path }}">
<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>
<a href="#" onclick="$(this).closest('form').submit(); return false" title="{{ project|get_answer:contractor|pk }}">
Отказаться и переместить в архив
</a>
</form>
</li>
</ul>
@ -103,12 +107,45 @@
{% include 'partials/footer.html' %}
</div>
</div>
{% endblock %}
{% block js_block %}
<script>
function query(paramName, paramVal) {
(function() {
var $navLinks = $('a.-nav')
var urlObj = new URI(window.location.href)
paramVal === '' ? urlObj.removeQuery(paramName) : urlObj.setQuery(paramName, paramVal)
window.location.href = urlObj.href()
}
var query = urlObj.query(true)
$('[data-default]').addClass('_defaultActive')
$navLinks.each(function(i, link) {
var $link = $(link)
var paramName = $link.data('paramName')
var paramVal = $link.data('paramVal')
if (query[paramName] === paramVal) {
$link.addClass('active')
$('[data-param-name="' + paramName + '"][data-default]').removeClass('_defaultActive')
}
})
$navLinks.filter('._defaultActive').addClass('active')
$navLinks.on('click', function($evt) {
var $link = $(this)
var paramName = $link.data('paramName')
var paramVal = $link.data('paramVal')
paramVal ? urlObj.setQuery(paramName, paramVal) : urlObj.removeQuery(paramName)
window.location.href = urlObj.href()
})
//---------------------------------------------------
if (query.archived !== 'on')
$('.-hide-if-archived').css('display', 'block')
}())
</script>
{% endblock %}

@ -6,7 +6,7 @@ from .views import (
contractor_resumefile_create,
ContractorFilterView,
ContractorOfficeDetailView,
ContractorOfficeOpenProjectsView,
ContractorOfficeProjectsView,
ContractorProfileDetailView,
ContractorResumeUpdateView,
CustomerProfileCurrentProjectsView,
@ -36,5 +36,5 @@ urlpatterns = [
urls.url(r'^contractorsresumefiles/create/$', contractor_resumefile_create, name='contractor-resume-file-create'),
urls.url(r'^contractors/(?P<pk>\d+)/$', ContractorProfileDetailView.as_view(), name='contractor-profile'),
urls.url(r'^contractor-office/(?P<pk>\d+)/$', ContractorOfficeDetailView.as_view(), name='contractor-office'),
urls.url(r'^contractor-office/(?P<pk>\d+)/open-projects/$', ContractorOfficeOpenProjectsView.as_view(), name='contractor-office-open-projects'),
urls.url(r'^contractor-office/(?P<pk>\d+)/open-projects/$', ContractorOfficeProjectsView.as_view(), name='contractor-office-open-projects'),
]

@ -381,7 +381,7 @@ class ContractorOfficeDetailView(DetailView):
return context
class ContractorOfficeOpenProjectsView(BaseMixin, View):
class ContractorOfficeProjectsView(BaseMixin, View):
template_name = 'contractor_office_open_projects.html'
def dispatch(self, request, *args, **kwargs):
@ -397,31 +397,36 @@ class ContractorOfficeOpenProjectsView(BaseMixin, View):
contractor = get_object_or_404(User.contractor_objects, pk=kwargs.get('pk'))
context['contractor'] = contractor
private_projects = tuple(a.project for a in contractor.contractor_answers.all())
private_project_count = len(private_projects)
# TODO: Show projects only with "active" state
team_projects = tuple(a.project for a in contractor.team.answers.all())
team_project_count = len(team_projects)
private_open_projects = tuple(a.project for a in contractor.contractor_answers.filter(project__state='active', rejected=False))
private_archived_projects = tuple(a.project for a in contractor.contractor_answers.filter(project__state='active', rejected=True))
context['all_project_count'] = private_project_count + team_project_count
team_open_projects = tuple(a.project for a in contractor.team.answers.filter(project__state='active', rejected=False))
team_archived_projects = tuple(a.project for a in contractor.team.answers.filter(project__state='active', rejected=True))
if request.GET.get('owner') == 'private':
projects = private_projects
elif request.GET.get('owner') == 'teams':
projects = team_projects
else:
projects = itertools.chain(private_projects, team_projects)
context['all_project_count'] = \
len(private_open_projects) + len(private_archived_projects) + \
len(team_open_projects) + len(team_archived_projects)
active_projects = _.filter(projects, lambda p: p.state == 'active')
context['active_project_count'] = len(active_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)
archived_projects = _.filter(projects, lambda p: p.state == 'trashed')
context['archived_project_count'] = len(archived_projects)
if request.GET.get('archived') == 'on':
projects = 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:
projects = active_projects
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

Loading…
Cancel
Save