remotes/origin/PR-39
Mukhtar 10 years ago
commit f89e79d633
  1. 8
      archilance/management/commands/generate_work_sells.py
  2. 4
      projects/migrations/0025_merge.py
  3. 8
      users/models.py
  4. 13
      users/templates/contractor_office.html
  5. 6
      users/templates/contractor_profile.html
  6. 517
      users/templates/team_profile.html
  7. 7
      users/urls.py
  8. 46
      users/views.py
  9. 4
      wallets/migrations/0013_merge.py
  10. 1
      work_sell/filters.py
  11. 22
      work_sell/migrations/0010_worksell_team.py
  12. 16
      work_sell/migrations/0011_merge.py
  13. 1
      work_sell/models.py
  14. 4
      work_sell/serializers.py

@ -9,7 +9,7 @@ from archilance import util
from common.models import Location
from projects.models import TERM_TYPES, CURRENCIES, BuildingClassfication, ConstructionType
from specializations.models import Specialization
from users.models import User
from users.models import User, Team
from work_sell.models import WorkSell, WorkSellPhoto
@ -32,7 +32,11 @@ class Command(BaseCommand):
ws.save()
ws.user = User.contractor_objects.order_by('?').first()
if _.sample((True, False)):
ws.contractor = User.contractor_objects.order_by('?').first()
else:
ws.team = Team.objects.order_by('?').first()
ws.building_classification = BuildingClassfication.objects.order_by('?').first()
ws.construction_type = ConstructionType.objects.order_by('?').first()
ws.location = Location.objects.root_nodes()[0].get_descendants().order_by('?').first()

@ -1,5 +1,5 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.9.7 on 2016-09-02 07:45
# Generated by Django 1.9.7 on 2016-09-02 15:04
from __future__ import unicode_literals
from django.db import migrations
@ -8,8 +8,8 @@ from django.db import migrations
class Migration(migrations.Migration):
dependencies = [
('projects', '0024_auto_20160901_1247'),
('projects', '0024_auto_20160901_1548'),
('projects', '0024_auto_20160901_1247'),
]
operations = [

@ -220,12 +220,16 @@ class User(AbstractBaseUser, PermissionsMixin):
def get_popular_specialization(self):
from ratings.models import SpecializationRating
# return SpecializationRating.objects.filter(user=self).order_by('position').first().specialization.name
rating = SpecializationRating.objects.filter(user=self).order_by('position').first()
if rating:
return rating.specialization.name
class Team(models.Model):
answers = GenericRelation('projects.Answer', related_query_name='teams')
avatar = models.ImageField(upload_to='teams/avatars/', blank=True)
avatar = models.ImageField(upload_to='teams/avatars/', blank=True) # TODO: Unused field?
created = models.DateTimeField(default=timezone.now)
name = models.CharField(max_length=255)
owner = models.OneToOneField(User, related_name='team', blank=True, null=True)

@ -82,7 +82,7 @@
<div class="block-users">
<p>Состав группы</p>
{% for c in team_members %}
{% for c in contractor.team.contractors.all %}
<div class="message-new">
<div class="imgMess">
{% if c.avatar %}
@ -114,7 +114,7 @@
<p class="navv">На сайте {{ contractor.team.created }}</p>
<p class="navv">
Кол-во человек: <span>{{ team_member_count }}</span>
Кол-во человек: <span>{{ contractor.team.contractors.count }}</span>
</p>
<p class="navv">
@ -261,17 +261,18 @@
var $moreWorkSellsfBtn = $('.-more-work-sells-btn').first()
var workSellAbsUrl = '/work_sell/'
var contractorId = {{ contractor.pk }}
var teamId = {{ contractor.team.pk }}
var contractorIds
var contractorIds = [contractorId]
var portfUrl = new URI('/api/portfolios/')
var workSellUrl = new URI('/api/work-sells/')
var pageSize = 3
$.get('/api/teams/' + teamId + '/').then(function(res) {
contractorIds = _.map(function(contractor) {
Array.prototype.push.apply(contractorIds, _.map(function(contractor) {
return contractor.id
}, res.contractors)
}, res.contractors))
})
.then(loadMorePortfolios)
.then(loadMoreWorkSells)
@ -305,7 +306,7 @@
function loadMoreWorkSells() {
var query = workSellUrl.query(true)
workSellUrl.setQuery('contractor__in', _.join(',', contractorIds))
workSellUrl.setQuery('contractor', contractorId)
workSellUrl.setQuery('page_size', pageSize)
workSellUrl.setQuery('page', query.page ? Number(query.page) + 1 : 2)

@ -101,7 +101,7 @@
<h4 class="modal-title">Контакты владельца </h4>
</div>
<div class="modal-body">
<div class="row" style="height: 100px;">
<div class="row" style="height: 140px;">
<div class="col-lg-8 col-lg-offset-1">
<ul class="list-summ">
{% if contractor.website %}
@ -113,6 +113,10 @@
{% if contractor.phone %}
<li>{{ contractor.phone }}</li>
{% endif %}
{% if contractor.phone2 %}
<li>{{ contractor.phone2 }}</li>
{% endif %}
</ul>
</div>
</div>

@ -0,0 +1,517 @@
{% extends 'partials/base.html' %}
{% load specializtions_tags %}
{% load thumbnail %}
{% block content %}
{% include 'partials/header.html' %}
<div class="container mainScore mainBlock2">
<div class="row">
<div class="col-lg-12">
<div class="col-lg-3 divCol3">
<div class="avatar">
<div class="avatarInset">
{% if team.owner.avatar %}
{% thumbnail team.owner.avatar "265x264" crop="center" as im %}
<img src="{{ im.url }}" alt="profile-image">
{% endthumbnail %}
{% else %}
<img src="{% static 'img/profile.jpg' %}" alt="profile-image">
{% endif %}
</div>
</div>
<div class="menuUser disTab">
<a href="{% url 'users:contractor-filter' %}" class="add-man">
добавить участника
</a>
<div class="block-users">
<p>Состав группы</p>
{% for c in team.contractors.all %}
<div class="message-new">
<div class="imgMess">
{% if c.avatar %}
{% thumbnail c.avatar "60x60" crop="center" as im %}
<img src="{{ im.url }}" alt="mess-image">
{% endthumbnail %}
{% else %}
<img src="{% static 'img/profile.jpg' %}" alt="mess-image">
{% endif %}
</div>
<p class="nameMess" style="float: none">
<a href="{% url 'users:contractor-profile' c.pk %}">{{ c.get_full_name }}</a>
</p>
<p><span>{{ c.get_popular_specialization }}</span></p>
</div>
{% empty %}
В группе пока нет участников
{% endfor %}
</div>
</div>
</div>
<div class="col-lg-9 divCol9">
<div class="col-lg-4">
<p class="nameUser">{{ team.name }}</p>
<p class="cityUser">{{ team.owner.get_location }}</p>
<p class="navv">На сайте {{ team.created }}</p>
<p class="navv">
Кол-во человек: <span>{{ team.contractors.count }}</span>
</p>
<p class="navv">
Выполненных проектов: <span>{{ completed_project_count }}</span>
</p>
<div class="statusUser st-new">Свободен</div>
<a href="javascript:void(0)" class="new-prop new-prop2 new-prop3">написать сообщение</a>
</div>
<div class="col-lg-4">
{% specialization_team_widget team.pk %}
</div>
<div class="col-lg-4">
{% ratings_team_widget team.pk %}
{% if team.owner.cro %}
<div class="sroUser">
<div class="iconSRO"></div>
<p>Есть допуск СРО</p>
</div>
{% endif %}
</div>
</div>
<div class="col-lg-9">
<div class="profileTabs2">
<ul class="nav nav-tabs nav-justified">
<li role="presentation" class="active">
<a href="#tab11" data-toggle="tab">Портфолио</a>
</li>
<li role="presentation">
<a href="#tab12" data-toggle="tab">Готовые проекты</a>
</li>
<li role="presentation">
<a href="#tab13" data-toggle="tab">Отзывы</a>
</li>
</ul>
</div>
</div>
<div class="tab-content">
<div id="tab11" class="tab-pane fade in active">
<div class="galleryWork2 disTab col-lg-9 -portfolios-container">
<script type="text/template" class="-portfolio-item-templ">
<div class="col-lg-4">
<div class="insetCol box-sizing disTab">
<div class="imgGal" style="background:rgba(0, 0, 0, 0) url('<%- portfolio.photos[0].img %>') no-repeat scroll center center / cover">
<a class="open-modal-image" href="<%- portfolio.photos[0].img %>"><div class="imgFigure"></div></a>
</div>
</div>
<div class="insetCol2 box-sizing disTab text-center">
<a href="<%- portfAbsUrl %>"><%- trunc({length: 50}, portfolio.name) %></a>
</div>
</div>
</script>
</div>
<div class="col-lg-9 col-lg-offset-3 -more-portfolios-btn">
<div class="linkElse">
<a href="#" onclick="loadMorePortfolios(); return false" class="showElse">показать еще</a>
</div>
</div>
</div>
<div id="tab12" class="tab-pane fade">
<div class="galleryWork2 disTab -work-sells-container">
<script type="text/template" class="-work-sell-item-templ">
<div class="col-lg-4">
<div class="insetCol box-sizing disTab">
<div class="imgGal" style="background:rgba(0, 0, 0, 0) url('<%- workSell.photos[0].img %>') no-repeat scroll center center / cover ;">
<a class="open-modal-image" href="<%- workSell.photos[0].img %>"><div class="imgFigure"></div></a>
</div>
<div class="cenaImg box-sizing">
<div class="cenaImgInset">
<%- workSell.budget %> <i class="fa fa-rub"></i>
</div>
</div>
</div>
<div class="insetCol2 box-sizing disTab">
<a href="<%- workSellAbsUrl %>"><%- trunc({length: 50}, workSell.name) %></a>
</div>
</div>
</script>
</div>
<div class="col-lg-9 col-lg-offset-3 -more-work-sells-btn">
<div class="linkElse">
<a href="#" onclick="loadMoreWorkSells(); return false" class="showElse">показать еще</a>
</div>
</div>
</div>
<div id="tab13" class="tab-pane fade">
{% for review in reviews %}
<div class="new-comm-44">
<div class="col-lg-12">
<p class="nameComm">
<a href="#">{{ review.get_sender }}</a>
</p>
{% if review.project.deal_type == 'secure_deal' %}
<span class="dateComm44">Безопасная сделка</span>
{% endif %}
<div class="stars box-sizing">
<a href="#">положительный отзыв</a>
</div>
<p class="textComm44">
{{ review.text|safe }}
</p>
</div>
</div>
{% empty %}
<div class="new-comm-44">
<p style="text-align: center;">Отзывов пока нет</p>
</div>
{% endfor %}
</div>
</div>
<div>
{% include 'partials/footer.html' %}
</div>
</div>
</div>
</div>
{% endblock %}
{% block js_block %}
<script type="text/javascript">
(function() {
// Pagination ---------------------------------------------------
var $portfoliosContainer = $('.-portfolios-container').first()
var portfolioItemTempl = _.template($portfoliosContainer.find('.-portfolio-item-templ').first().html())
var $morePortfBtn = $('.-more-portfolios-btn').first()
var portfAbsUrl = '/projects/portfolio/'
var $workSellsContainer = $('.-work-sells-container').first()
var workSellItemTempl = _.template($workSellsContainer.find('.-work-sell-item-templ').first().html())
var $moreWorkSellsfBtn = $('.-more-work-sells-btn').first()
var workSellAbsUrl = '/work_sell/'
var teamId = {{ team.pk }}
var contractorIds = [{{ team.owner.pk }}]
var portfUrl = new URI('/api/portfolios/')
var workSellUrl = new URI('/api/work-sells/')
var pageSize = 3
$.get('/api/teams/' + teamId + '/').then(function(res) {
Array.prototype.push.apply(contractorIds, _.map(function(contractor) {
return contractor.id
}, res.contractors))
})
.then(loadMorePortfolios)
.then(loadMoreWorkSells)
function loadMorePortfolios() {
var query = portfUrl.query(true)
portfUrl.setQuery('user__id__in', _.join(',', contractorIds))
portfUrl.setQuery('page_size', pageSize)
portfUrl.setQuery('page', query.page ? Number(query.page) + 1 : 2)
$.get(portfUrl.href())
.then(function(res) {
_.each(function(portfolio) {
$portfoliosContainer.append(portfolioItemTempl({
portfolio: portfolio,
portfAbsUrl: portfAbsUrl + portfolio.id + '/',
trunc: _.truncate,
}))
}, res.results)
if (!res.next)
$morePortfBtn.css('display', 'none')
})
.then(function() {
$('.open-modal-image').magnificPopup({type: 'image'})
})
}
function loadMoreWorkSells() {
var query = workSellUrl.query(true)
workSellUrl.setQuery('team', teamId)
workSellUrl.setQuery('page_size', pageSize)
workSellUrl.setQuery('page', query.page ? Number(query.page) + 1 : 2)
$.get(workSellUrl.href()).then(function(res) {
_.each(function(ws) {
$workSellsContainer.append(workSellItemTempl({
workSell: ws,
workSellAbsUrl: workSellAbsUrl + ws.id + '/',
trunc: _.truncate,
}))
}, res.results)
if (!res.next)
$moreWorkSellsfBtn.css('display', 'none')
})
}
window.loadMorePortfolios = loadMorePortfolios
window.loadMoreWorkSells = loadMoreWorkSells
// Persistent Bootstrap tabs --------------------------------------
$('a[data-toggle="tab"][href="' + window.location.hash + '"]').tab('show')
$('a[data-toggle="tab"]').on('click', function($evt) { // Better handle "shown.bs.tab" event?
window.location.hash = $(this).attr('href')
})
//-----------------------------------------------------------------
{# var userId = '{{ contractor.pk }}';#}
{# #}
{# var hash = window.location.hash;#}
{# #}
{# if (hash == '#open-contact') {#}
{# $("#contact-contactor-modal").modal();#}
{# }#}
{# #}
{# $('#resume-edit-form').on('submit', function (e) {#}
{# e.preventDefault();#}
{# var resumeEditUrl = "{% url 'users:contractor-resume-update' contractor.contractor_resume.pk %}";#}
{# var dataSerializer = $(this).serialize();#}
{# #}
{# $.ajax({#}
{# url: resumeEditUrl,#}
{# method: 'POST',#}
{# beforeSend: function (xhr) {#}
{# xhr.setRequestHeader("X-CSRFToken", getCookie('csrftoken'))#}
{# },#}
{# data: dataSerializer,#}
{# dataType: 'json',#}
{# success: function (data) {#}
{# console.log(data);#}
{# if (data.status == 'ok') {#}
{# $("#resume-text-out").html(data.text);#}
{# $("#resume-text-edit").modal('hide');#}
{# #}
{# }#}
{# },#}
{# error: function (jqXHR, exception) {#}
{# console.log(jqXHR);#}
{# console.log(exception);#}
{# console.log(jqXHR.statusCode);#}
{# }#}
{# #}
{# });#}
{# });#}
{# #}
{# #}
{# $("#diplom-cro-gallery").on('click', '.delete-resume-file',function(e){#}
{# e.preventDefault();#}
{# #}
{# var _this = $(this);#}
{# var deleteResumeUrl = '/api/contractorresumefiles/' + $(this).attr('data-id') + '/';#}
{# $.ajax({#}
{# url:deleteResumeUrl,#}
{# type: 'DELETE',#}
{# beforeSend: function (xhr) {#}
{# xhr.setRequestHeader("X-CSRFToken", getCookie('csrftoken'))#}
{# },#}
{# success: function(json){#}
{# _this.parent().parent().parent().remove();#}
{# console.log(json);#}
{# },#}
{# error: function(jqXHR, e){#}
{# console.log(jqXHR.statusCode);#}
{# }#}
{# });#}
{# });#}
{# #}
{# #}
{# $('#worksell-add-form').on('submit', function (e) {#}
{# e.preventDefault();#}
{# var dataSerializer = $(this).serialize();#}
{# $.ajax({#}
{# url: '/work_sell/create/',#}
{# method: 'POST',#}
{# data: dataSerializer,#}
{# dataType: 'json',#}
{# success: function (data) {#}
{# if (data.status == 'ok') {#}
{# location.reload();#}
{# }#}
{# #}
{# },#}
{# error: function (jqXHR, exception) {#}
{# console.log(jqXHR.statusCode);#}
{# console.log(jqXHR);#}
{# }#}
{# #}
{# })#}
{# });#}
{# #}
{# #}
{# $('#portfolio-add-form').on('submit', function (e) {#}
{# e.preventDefault();#}
{# var dataSerializer = $(this).serialize();#}
{# #}
{# $.ajax({#}
{# url: '/projects/portfolio/create/',#}
{# method: 'POST',#}
{# data: dataSerializer,#}
{# dataType: 'json',#}
{# success: function (data) {#}
{# if (data.status == 'ok') {#}
{# $('#portfolio-add-form').each(function () {#}
{# this.reset();#}
{# });#}
{# location.reload();#}
{# } else if (data.status == 'no') {#}
{# #}
{# $.each(data.form_errors, function (k, v) {#}
{# $('.error-' + k).html(v).show();#}
{# });#}
{# }#}
{# },#}
{# error: function (jqXHR, exception) {#}
{# console.log(jqXHR.statusCode);#}
{# }#}
{# });#}
{# });#}
{# var url = '/work_sell/basic/';#}
{# var csrftoken = $.cookie('csrftoken');#}
{# #}
{# $("#upload-resume").on('change',function(e){#}
{# $("#resume-success").html("");#}
{# var formData = new FormData($(this).closest("form"));#}
{# formData.append('resume_file', e.target.files[0]);#}
{# console.log(formData);#}
{# console.log(e.target.files[0]);#}
{# $.ajax({#}
{# url:'/api/contractorresume/{{ contractor.contractor_resume.pk }}/',#}
{# method:'PUT',#}
{# beforeSend: function (xhr) {#}
{# xhr.setRequestHeader("X-CSRFToken", getCookie('csrftoken'));#}
{# },#}
{# data: formData,#}
{# cache: false,#}
{# dataType: 'json',#}
{# processData: false,#}
{# contentType: false,#}
{# success: function(data){#}
{# $("#resume-success").html("Файл для резюме успешно загружен!");#}
{# $(".download-summ").css('display','block').attr('href',data.resume_file);#}
{# console.log(data);#}
{# },#}
{# error: function(jqXHR){#}
{# console.log(jqXHR);#}
{# }#}
{# });#}
{# });#}
{# #}
{# $('#fileupload').fileupload({#}
{# url: url,#}
{# crossDomain: false,#}
{# beforeSend: function (xhr, settings) {#}
{# $('#progress-portfolio .progress-bar').css(#}
{# 'width',#}
{# '0%'#}
{# );#}
{# if (!csrfSafeMethod(settings.type)) {#}
{# xhr.setRequestHeader("X-CSRFToken", csrftoken);#}
{# }#}
{# },#}
{# dataType: 'json',#}
{# done: function (e, data) {#}
{# console.log(data);#}
{# $.each(data.result.files, function (index, file) {#}
{# var img = $('<img style="width:200px;height:200px;margin:10px;">').attr('src', file.url).appendTo("#files");#}
{# console.log(file);#}
{# var currentValue = $("#upload-files-pk").val();#}
{# currentValue += file.id + ';';#}
{# $("#upload-files-pk").val(currentValue);#}
{# #}
{# });#}
{# },#}
{# progressall: function (e, data) {#}
{# var progress = parseInt(data.loaded / data.total * 100, 10);#}
{# console.log(progress);#}
{# $('#progress-portfolio .progress-bar').css(#}
{# 'width',#}
{# progress + '%'#}
{# );#}
{# }#}
{# }).prop('disabled', !$.support.fileInput)#}
{# .parent().addClass($.support.fileInput ? undefined : 'disabled');#}
{# #}
{# $('#fileupload-worksell').fileupload({#}
{# url: url,#}
{# crossDomain: false,#}
{# beforeSend: function (xhr, settings) {#}
{# $('#progress-worksell .progress-bar').css(#}
{# 'width',#}
{# '0%'#}
{# );#}
{# if (!csrfSafeMethod(settings.type)) {#}
{# xhr.setRequestHeader("X-CSRFToken", csrftoken);#}
{# }#}
{# },#}
{# dataType: 'json',#}
{# done: function (e, data) {#}
{# console.log(data);#}
{# $.each(data.result.files, function (index, file) {#}
{# var img = $('<img style="width:200px;height:200px;margin:10px;">').attr('src', file.url).appendTo("#files-worksell");#}
{# console.log(file);#}
{# var currentValue = $("#upload-files-worksell-pk").val();#}
{# currentValue += file.id + ';';#}
{# $("#upload-files-worksell-pk").val(currentValue);#}
{# #}
{# });#}
{# },#}
{# progressall: function (e, data) {#}
{# var progress = parseInt(data.loaded / data.total * 100, 10);#}
{# console.log(progress);#}
{# $('#progress-worksell .progress-bar').css(#}
{# 'width',#}
{# progress + '%'#}
{# );#}
{# }#}
{# }).prop('disabled', !$.support.fileInput)#}
{# .parent().addClass($.support.fileInput ? undefined : 'disabled');#}
{# #}
{# function csrfSafeMethod(method) {#}
{# // these HTTP methods do not require CSRF protection#}
{# return (/^(GET|HEAD|OPTIONS|TRACE)$/.test(method));#}
{# }#}
}())
</script>
{% endblock %}

@ -7,13 +7,14 @@ from .views import (
ContractorFilterView,
ContractorOfficeProjectsView,
ContractorOfficeView,
ContractorProfileDetailView,
ContractorProfileView,
ContractorResumeUpdateView,
CustomerProfileCurrentProjectsView,
CustomerProfileOpenProjectsView,
CustomerProfileReviewsView,
CustomerProfileTrashedProjectsView,
TeamCreateView,
TeamProfileView,
UserFinancialInfoEditView,
UserProfileEditView,
ContractorChatProjectsView,
@ -35,8 +36,10 @@ urlpatterns = [
urls.url(r'^contractors/resume/(?P<pk>\d+)/edit/$', ContractorResumeUpdateView.as_view(), name='contractor-resume-update'),
urls.url(r'^contractors/team/create/$', TeamCreateView.as_view(), name='team-create'),
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'^contractors/(?P<pk>\d+)/$', ContractorProfileView.as_view(), name='contractor-profile'),
urls.url(r'^contractor-office/(?P<pk>\d+)/$', ContractorOfficeView.as_view(), name='contractor-office'),
urls.url(r'^contractor-office/(?P<pk>\d+)/open-projects/$', ContractorOfficeProjectsView.as_view(), name='contractor-office-open-projects'),
urls.url(r'^teams/(?P<pk>\d+)/$', TeamProfileView.as_view(), name='team-profile'),
urls.url(r'^contractor-office/(?P<pk>\d+)/work-projects/$', ContractorChatProjectsView.as_view(), name='contractor-office-chat-projects'),
]

@ -326,7 +326,7 @@ class ContractorFilterView(BaseMixin, View):
return render(request, self.template_name, context)
class ContractorProfileDetailView(DetailView):
class ContractorProfileView(DetailView):
model = User
worksell_form_class = WorkSellForm
portfolio_form_class = PortfolioForm
@ -372,34 +372,42 @@ class ContractorOfficeView(DetailView):
contractor = self.object
if util.get_related_or_none(contractor, 'team'):
members = contractor.team.contractors.all()
context['team_members'] = members
context['team_member_count'] = len(members)
team = contractor.team
compl_proj = []
# portfolios = [] # Fetched via DRF
# work_sells = [] # Fetched via DRF
# 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')))
compl_proj.extend(tuple(o.project for o in contractor.orders.filter(status='completed')))
# portfolios.extend(contractor.portfolios.all())
# work_sells.extend(contractor.work_sell.all())
for c in members:
compl_proj.extend(tuple(o.project for o in c.orders.filter(status='completed')))
# portfolios.extend(c.portfolios.all())
# work_sells.extend(c.work_sell.all())
compl_proj = tuple(o.project for o in team.orders.filter(status='completed'))
context['completed_project_count'] = len(compl_proj)
# context['portfolios'] = portfolios
# context['work_sells'] = work_sells
context['reviews'] = Review.objects.filter(target_contractor__in=itertools.chain((contractor,), members))
context['reviews'] = Review.objects.filter(target_contractor=contractor)
context['form_team'] = self.form_class
return context
class TeamProfileView(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(BaseMixin, View):
template_name = 'contractor_office_chat_projects.html'

@ -1,5 +1,5 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.9.7 on 2016-09-02 07:45
# Generated by Django 1.9.7 on 2016-09-02 15:04
from __future__ import unicode_literals
from django.db import migrations
@ -8,8 +8,8 @@ from django.db import migrations
class Migration(migrations.Migration):
dependencies = [
('wallets', '0012_auto_20160901_1247'),
('wallets', '0012_auto_20160901_1548'),
('wallets', '0012_auto_20160901_1247'),
]
operations = [

@ -38,6 +38,7 @@ class WorkSellFilterSet(FilterSet):
location = RelatedFilter('common.filters.LocationFilterSet')
photos = RelatedFilter('work_sell.filters.WorkSellPhotoFilterSet')
specialization = RelatedFilter('specializations.filters.SpecializationFilterSet')
team = RelatedFilter('users.filters.TeamFilterSet')
class Meta:
model = WorkSell

@ -0,0 +1,22 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.9.7 on 2016-09-02 14:19
from __future__ import unicode_literals
from django.db import migrations, models
import django.db.models.deletion
class Migration(migrations.Migration):
dependencies = [
('users', '0015_user_phone2'),
('work_sell', '0009_auto_20160901_1548'),
]
operations = [
migrations.AddField(
model_name='worksell',
name='team',
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='work_sells', to='users.Team'),
),
]

@ -0,0 +1,16 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.9.7 on 2016-09-02 15:04
from __future__ import unicode_literals
from django.db import migrations
class Migration(migrations.Migration):
dependencies = [
('work_sell', '0009_auto_20160901_1247'),
('work_sell', '0010_worksell_team'),
]
operations = [
]

@ -21,6 +21,7 @@ class WorkSell(models.Model):
location = TreeForeignKey('common.Location', related_name='worksells', null=True, blank=True)
name = models.CharField(max_length=255)
specialization = TreeForeignKey(Specialization, related_name='worksells', null=True, blank=True)
team = models.ForeignKey(Team, related_name='work_sells', null=True, blank=True)
term = models.IntegerField(default=0, null=True, blank=True)
term_type = models.CharField(max_length=20, choices=TERM_TYPES, default='hour', null=True, blank=True)

@ -5,7 +5,7 @@ from .models import WorkSell, WorkSellPhoto
from common.serializers import LocationSerializer
from projects.serializers import BuildingClassficationSerializer, ConstructionTypeSerializer
from specializations.serializers import SpecializationSerializer
from users.serializers import UserSerializer
from users.serializers import UserSerializer, TeamSerializer
class WorkSellPhotoSerializer(ModelSerializer):
@ -30,6 +30,7 @@ class WorkSellSerializer(ModelSerializer):
location = LocationSerializer()
photos = WorkSellPhotoSerializer(many=True)
specialization = SpecializationSerializer()
team = TeamSerializer()
class Meta:
model = WorkSell
@ -47,6 +48,7 @@ class WorkSellSerializer(ModelSerializer):
'name',
'photos',
'specialization',
'team',
'term',
'term_type',
)

Loading…
Cancel
Save