Merge branch 'master' of https://bitbucket.org/PekopT/archilance into mukhtar

remotes/origin/PR-39
Mukhtar 10 years ago
commit 8965d58227
  1. 1
      archilance/settings/base.py
  2. 4
      assets/js/chat.js
  3. 4
      assets/js/main.js
  4. 2
      chat/chat.py
  5. 4
      projects/models.py
  6. 12
      projects/templates/project_filter.html
  7. 21
      projects/views.py
  8. 1
      requirements/base.txt
  9. 6
      templates/partials/base.html
  10. 27
      templates/partials/pagination.html
  11. 5
      update.sh
  12. 4
      users/models.py
  13. 2
      users/templates/customer_profile_trashed_projects.html
  14. 6
      users/views.py
  15. 2
      wallets/signals.py
  16. 2
      wallets/views.py

@ -40,6 +40,7 @@ THIRD_PARTY_APPS = [
'password_reset', 'password_reset',
'mathfilters', # Basic math operations in templates; https://pypi.python.org/pypi/django-mathfilters 'mathfilters', # Basic math operations in templates; https://pypi.python.org/pypi/django-mathfilters
'generic_relations', # https://github.com/Ian-Foote/rest-framework-generic-relations 'generic_relations', # https://github.com/Ian-Foote/rest-framework-generic-relations
'hitcount',
] ]
LOCAL_APPS = [ LOCAL_APPS = [

@ -1,13 +1,13 @@
var SocketHandler = function () { var SocketHandler = function () {
domain = domain.replace(':' + port, ''); domain = domain.replace(':' + port, '');
var url = 'ws://' + domain + ':8888/chat/' + userId + '/'; var url = 'ws://' + domain + '/chat/' + userId + '/';
var sock = new WebSocket(url); var sock = new WebSocket(url);
var intervalId; var intervalId;
sock.onopen = function () { sock.onopen = function () {
console.log("Start connect"); console.log("Start connect");
intervalId = setInterval(function () { intervalId = setInterval(function () {
sock.send('{"dummy": 1}'); sock.send('{"dummy": 1}');
}, 150000); }, 15000);
}; };
sock.onmessage = function (event) { sock.onmessage = function (event) {
console.log(event.data); console.log(event.data);

@ -14,11 +14,11 @@ $(document).ready(function(){
if($('.slideRes').hasClass('activeSlide')) { if($('.slideRes').hasClass('activeSlide')) {
$('.slideRes').slideUp(300); $('.slideRes').slideUp(300);
$(this).css('transform','rotate(180deg)'); $(this).css('transform','rotate(180deg)');
$.cookie('slideResVisible', '') $.cookie('slideResVisible', '', {expires: new Date(new Date().getTime() + 300000)}) // 5 minutes
} else { } else {
$('.slideRes').slideDown(300); $('.slideRes').slideDown(300);
$(this).css('transform','rotate(0deg)'); $(this).css('transform','rotate(0deg)');
$.cookie('slideResVisible', 'on') $.cookie('slideResVisible', 'on', {expires: new Date(new Date().getTime() + 300000)})
} }
}); });

@ -111,5 +111,5 @@ if __name__ == '__main__':
future.result() future.result()
http_server = HTTPServer(application) http_server = HTTPServer(application)
http_server.listen(PORT, 'localhost') http_server.listen(PORT, '127.0.0.1')
ioloop.start() ioloop.start()

@ -3,6 +3,7 @@ from django.contrib.contenttypes.models import ContentType
from django.db import models from django.db import models
from django.db.models import Q from django.db.models import Q
from django.utils import timezone from django.utils import timezone
from hitcount.models import HitCountMixin
from mptt.models import TreeForeignKey from mptt.models import TreeForeignKey
import pydash as _; _.map = _.map_; _.filter = _.filter_ import pydash as _; _.map = _.map_; _.filter = _.filter_
@ -61,7 +62,7 @@ class Realty(models.Model):
verbose_name_plural = 'Объекты' verbose_name_plural = 'Объекты'
class Project(models.Model): class Project(models.Model, HitCountMixin):
WORK_TYPES = ( WORK_TYPES = (
(1, 'Проектирование'), (1, 'Проектирование'),
(2, 'Техническое сопровождение') (2, 'Техническое сопровождение')
@ -102,6 +103,7 @@ class Project(models.Model):
class Meta: class Meta:
verbose_name = 'Проект' verbose_name = 'Проект'
verbose_name_plural = 'Проекты' verbose_name_plural = 'Проекты'
ordering = ('-created',)
def secure_deal(self): def secure_deal(self):
return self.deal_type == 'secure_deal' return self.deal_type == 'secure_deal'

@ -202,9 +202,12 @@
<ul class="listPro"> <ul class="listPro">
<li>{{ proj.created }}</li> <li>{{ proj.created }}</li>
<li>0</li> <li>{{ proj.hit_count.hits }}</li>
<li>{{ proj.answers.count }}</li> <li>{{ proj.answers.count }}</li>
<li>{{ proj.user }}</li>
{% if request.user.is_authenticated %}
<li>{{ proj.customer.username }}</li>
{% endif %}
</ul> </ul>
</div> </div>
<div class="col-lg-3 rightPro"> <div class="col-lg-3 rightPro">
@ -219,11 +222,6 @@
<li> <li>
Стадия: "П" Стадия: "П"
</li> </li>
<li>
Отказаться и переместить
в корзину
</li>
</ul> </ul>
</div> </div>
</div> </div>

@ -9,8 +9,11 @@ from django.http import HttpResponseForbidden, HttpResponseRedirect, HttpRespons
from django.shortcuts import render, get_object_or_404, redirect from django.shortcuts import render, get_object_or_404, redirect
from django.views.generic import ListView, DetailView, CreateView, DeleteView, View, UpdateView, TemplateView, FormView from django.views.generic import ListView, DetailView, CreateView, DeleteView, View, UpdateView, TemplateView, FormView
from django.views.generic.base import ContextMixin from django.views.generic.base import ContextMixin
from hitcount.models import HitCount
from hitcount.views import HitCountMixin
from pprint import pprint, pformat from pprint import pprint, pformat
import json import json
import natsort
import pydash as _; _.map = _.map_; _.filter = _.filter_ import pydash as _; _.map = _.map_; _.filter = _.filter_
import re import re
@ -45,6 +48,9 @@ class ProjectDetailWithAnswerView(BaseMixin, View):
project = get_object_or_404(Project, pk=kwargs.get('pk')) project = get_object_or_404(Project, pk=kwargs.get('pk'))
context.update({'project': project}) 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(): if request.user.is_authenticated() and request.user.is_contractor():
project_answers = project.answers.all() project_answers = project.answers.all()
contractor = request.user contractor = request.user
@ -244,8 +250,8 @@ class ProjectFilterView(BaseMixin, View):
for k in keywords: for k in keywords:
projects = projects.filter(Q(name__icontains=k) | Q(text__icontains=k)) projects = projects.filter(Q(name__icontains=k) | Q(text__icontains=k))
# projects = projects.filter(cro=cro) if cro:
projects = projects.filter(cro=cro)
if work_type: if work_type:
projects = projects.filter(work_type=work_type) projects = projects.filter(work_type=work_type)
@ -279,7 +285,12 @@ class ProjectFilterView(BaseMixin, View):
elif last_order_by: elif last_order_by:
ord = last_order_by ord = last_order_by
if ord: 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) projects = projects.order_by('-%s' % ord if reverse_order else ord)
context.update({ context.update({
@ -287,7 +298,7 @@ class ProjectFilterView(BaseMixin, View):
'reverse_order': reverse_order, 'reverse_order': reverse_order,
}) })
project_count = projects.count() project_count = len(projects) if manual_sort else projects.count()
display_msg = 'Найдено %s проектов' % project_count if project_count > 0 else 'Ничего не найдено' display_msg = 'Найдено %s проектов' % project_count if project_count > 0 else 'Ничего не найдено'
else: else:
display_msg = 'Пожалуйста, введите корректные данные' display_msg = 'Пожалуйста, введите корректные данные'
@ -304,7 +315,7 @@ class ProjectFilterView(BaseMixin, View):
'<pre>{realty_form}</pre>' '<pre>{realty_form}</pre>'
).format(realty_form=pformat(realty_form.errors))) ).format(realty_form=pformat(realty_form.errors)))
paginator = Paginator(projects.all(), settings.PAGE_SIZE) paginator = Paginator(projects if manual_sort else projects.all(), settings.PAGE_SIZE)
page = request.GET.get('page') page = request.GET.get('page')
try: try:

@ -40,3 +40,4 @@ natsort
django-mathfilters django-mathfilters
gunicorn==19.6.0 gunicorn==19.6.0
rest-framework-generic-relations rest-framework-generic-relations
django-hitcount

@ -82,14 +82,14 @@
if (queryString.indexOf('/chat') != 0) { if (queryString.indexOf('/chat') != 0) {
domain = domain.replace(':' + port, ''); domain = domain.replace(':' + port, '');
var url = 'ws://' + domain + ':8888/chat/' + userId + '/'; var url = 'ws://' + domain + '/chat/' + userId + '/';
var sock = new WebSocket(url); var sock = new WebSocket(url);
var intervalId; var intervalId;
sock.onopen = function () { sock.onopen = function () {
console.log("Start connect"); console.log("Start connect");
intervalId = setInterval(function () { intervalId = setInterval(function () {
sock.send('{"dummy": 1}'); sock.send('{"dummy": 1}');
}, 150000); }, 15000);
}; };
sock.onmessage = function (event) { sock.onmessage = function (event) {
@ -97,7 +97,7 @@
$.jGrowl("Вам пришло новое сообщение!" + notificationData.msg, {sticky: true}); $.jGrowl("Вам пришло новое сообщение!" + notificationData.msg, {sticky: true});
}; };
} }
} };
$(function () { $(function () {
var userId = '{{ request.user.pk }}'; var userId = '{{ request.user.pk }}';
if (userId) { if (userId) {

@ -1,4 +1,19 @@
{% if is_paginated %} {% if is_paginated %}
{% if TEMPLATE_DEBUG %}
<div class="a" style="text-align: initial; font-size: 20px; line-height: initial">
<p>page_obj.has_previous: {{ page_obj.has_previous }}</p>
<p>page_obj.has_next: {{ page_obj.has_next }}</p>
<p>page_obj.previous_page_number: {% if page_obj.has_previous %}{{ page_obj.previous_page_number }}{% endif %}</p>
<p>page_obj.next_page_number: {% if page_obj.has_next %}{{ page_obj.next_page_number }}{% endif %}</p>
<p>page_obj.paginator.page_range: {{ page_obj.paginator.page_range }}</p>
<p>page_obj.number: {{ page_obj.number }}</p>
<p>page_obj.paginator.num_pages: {{ page_obj.paginator.num_pages }}</p>
</div>
{% endif %}
<nav> <nav>
<ul class="pagination"> <ul class="pagination">
<li> <li>
@ -16,14 +31,24 @@
</a> </a>
</li> </li>
{% if page_obj.number|sub:4 > 1 %}
<li><a href="#" onclick="paginateTo(1); return false">1</a></li>
<li>...</li>
{% endif %}
{% for n in page_obj.paginator.page_range %} {% for n in page_obj.paginator.page_range %}
{% if n == page_obj.number %} {% if n == page_obj.number %}
<li class="active"><a href="#" onclick="return false">{{ n }}</a></li> <li class="active"><a href="#" onclick="return false">{{ n }}</a></li>
{% else %} {% elif n > page_obj.number|sub:4 and n < page_obj.number or n < page_obj.number|add:4 and n > page_obj.number %}
<li><a href="#" onclick="paginateTo({{ n }}); return false">{{ n }}</a></li> <li><a href="#" onclick="paginateTo({{ n }}); return false">{{ n }}</a></li>
{% endif %} {% endif %}
{% endfor %} {% endfor %}
{% if page_obj.number|add:4 < page_obj.paginator.num_pages %}
<li>...</li>
<li><a href="#" onclick="paginateTo({{ page_obj.paginator.num_pages }}); return false">{{ page_obj.paginator.num_pages }}</a></li>
{% endif %}
<li> <li>
<a <a
href="#" href="#"

@ -1,8 +1,11 @@
#!/usr/bin/env bash #!/usr/bin/env bash
source ../env/bin/activate && source ../env/bin/activate &&
pip install -r requirements/base.txt &&
git reset --hard && git reset --hard &&
git pull && git pull &&
chmod +x update.sh &&
./manage.py migrate --noinput && ./manage.py migrate --noinput &&
./manage.py collectstatic --noinput && ./manage.py collectstatic --noinput &&
supervisorctl restart arch supervisorctl restart arch &&
./manage.py recalculation_spec

@ -119,7 +119,7 @@ class User(AbstractBaseUser, PermissionsMixin):
) )
avatar = models.ImageField(upload_to='users/avatars/', blank=True) avatar = models.ImageField(upload_to='users/avatars/', blank=True)
contractor_answers = GenericRelation('projects.Answer') contractor_answers = GenericRelation('projects.Answer', related_query_name='contractors')
contractor_resume = models.OneToOneField(ContractorResume, related_name='contractor', blank=True, null=True) contractor_resume = models.OneToOneField(ContractorResume, related_name='contractor', blank=True, null=True)
contractor_specializations = TreeManyToManyField(Specialization, related_name='contractors', blank=True) contractor_specializations = TreeManyToManyField(Specialization, related_name='contractors', blank=True)
contractor_status = models.CharField(default='free', max_length=20, choices=STATUSES) contractor_status = models.CharField(default='free', max_length=20, choices=STATUSES)
@ -197,7 +197,7 @@ class User(AbstractBaseUser, PermissionsMixin):
class Team(models.Model): class Team(models.Model):
answers = GenericRelation('projects.Answer') 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)
created = models.DateTimeField(default=timezone.now) created = models.DateTimeField(default=timezone.now)
name = models.CharField(max_length=255) name = models.CharField(max_length=255)

@ -45,7 +45,7 @@
Объект "{{ proj.realty.name }}" Объект "{{ proj.realty.name }}"
</li> </li>
<li> <li>
<span>2</span> ответ от имени группы <span>{{ proj.get_team_answers|length }}</span> ответ от имени группы
</li> </li>
</ul> </ul>
<p class="textPro"> <p class="textPro">

@ -1,16 +1,16 @@
from .models import ContractorResume, ContractorResumeFiles
from django.conf import settings from django.conf import settings
from django.contrib import messages from django.contrib import messages
from django.views.generic import UpdateView
from .models import ContractorResume, ContractorResumeFiles
from django.http import JsonResponse, Http404
from django.core.files.base import ContentFile from django.core.files.base import ContentFile
from django.core.mail import send_mail from django.core.mail import send_mail
from django.core.paginator import Paginator, EmptyPage, PageNotAnInteger from django.core.paginator import Paginator, EmptyPage, PageNotAnInteger
from django.core.urlresolvers import reverse from django.core.urlresolvers import reverse
from django.db.models import Q from django.db.models import Q
from django.http import HttpResponse, HttpResponseForbidden from django.http import HttpResponse, HttpResponseForbidden
from django.http import JsonResponse, Http404
from django.shortcuts import render, get_object_or_404, redirect 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 ListView, DetailView, View, UpdateView, CreateView
from django.views.generic import UpdateView
from pprint import pprint, pformat from pprint import pprint, pformat
import itertools import itertools
import json import json

@ -21,7 +21,7 @@ def send_for_accountant(sender, instance, created, **kwargs):
@receiver(post_save, sender=Transaction) @receiver(post_save, sender=Transaction)
def add_invoice_history(sender, instance,created, **kwargs): def add_invoice_history(sender, instance, created, **kwargs):
if 'add' in instance.type: if 'add' in instance.type:
inv_history = InvoiceHistory() inv_history = InvoiceHistory()
inv_history.comment = 'Пополнение счета' inv_history.comment = 'Пополнение счета'

@ -40,7 +40,7 @@ class ScoreView(View):
return HttpResponseForbidden('403 Forbidden') return HttpResponseForbidden('403 Forbidden')
def get(self, request, *args, **kwargs): def get(self, request, *args, **kwargs):
transaction = Transaction.objects.create(customer=request.user) transaction = Transaction.objects.get_or_create(customer=request.user, complete=False)
user_score = get_object_or_404(User.customer_objects, pk=kwargs.get('pk')) user_score = get_object_or_404(User.customer_objects, pk=kwargs.get('pk'))
return render(request, self.template_name, { return render(request, self.template_name, {

Loading…
Cancel
Save