remotes/origin/PR-39
ArturBaybulatov 10 years ago
commit 791f544219
  1. 11
      api/views.py
  2. 87
      assets/css/main.css
  3. 66
      assets/js/chat.js
  4. 21
      chat/migrations/0008_documents_created.py
  5. 20
      chat/migrations/0009_auto_20160829_1120.py
  6. 1
      chat/models.py
  7. 2
      chat/serializers.py
  8. 60
      chat/templates/chat_customer.html
  9. 1
      chat/views.py
  10. 4
      projects/templates/project_detail.html
  11. 36
      templates/cms_pages/cms_page.html
  12. 3
      templates/partials/header.html
  13. 2
      users/templates/contractor_filter.html
  14. 8
      users/templates/contractor_profile.html
  15. 11
      users/templates/user_financial_info_edit.html
  16. 17
      users/views.py
  17. 2
      wallets/templates/score-detail.html

@ -75,6 +75,17 @@ class DocumentViewSet(ModelViewSet):
# filter_class = DocumentsFilterSet
# permission_classes = (permissions.IsAuthenticatedOrReadOnly,)
def get_queryset(self):
queryset = Documents.objects.all()
search_param = self.request.query_params.get('operand', None)
recipent_id = self.request.query_params.get('recipent_id', None)
sender_id = self.request.query_params.get('sender_id', None)
if search_param:
# import code; code.interact(local=dict(globals(), **locals()))
if search_param == 'in':
queryset = queryset.filter(Q(sender__in=[sender_id,recipent_id]),Q(recipent__in=[sender_id,recipent_id])).order_by('created')
return queryset
class ProjectViewSet(ModelViewSet):
queryset = Project.objects.all()

@ -5524,7 +5524,7 @@ input[type="radio"]:checked + span {
width: 216px;
}
.proj_answ_form .textAreaBlock2 input[name="term"]{
width: 262px;
width: 258px;
}
.proj_answ_form .textAreaBlock2 p span{
position: absolute;
@ -5759,7 +5759,7 @@ input[type="radio"]:checked + span {
margin-bottom: 0 !important
}
.infoProfile .dropdown-menu{
height: 316px;
height: auto;
}
.form-regestration{
padding: 20px 0 40px 0;
@ -5819,4 +5819,87 @@ input[type="radio"]:checked + span {
text-transform: initial;
letter-spacing: normal;
}
.fr_answer{
width: 100%;
height: 110px;
border: 1px solid #cdcdcd;
resize: none;
padding: 10px 15px;
color: #3c1a06;
font-family: 'Arial-MT-Regular', sans-serif;
font-size: 14px;
float: left;
margin: 0px 0px 0px 55px;
}
.fr_answer_sen{
float: left;
border-radius: 40px;
font-family: 'pfdintextcomppro-regular', sans-serif;
letter-spacing: 2px;
color: #373737;
margin: 20px 0 0 55px;
font-size: 15px;
border: 1px solid #BEBEBE;
padding: 17px 46px;
text-transform: uppercase;
}
.fa-pencil:before, .fa-times:before{
color: #fff;
}
.mainMenu li.active > a {
border-color: #ff0029;
}
.mainMenu li.icon_tm1.active span{
background: url('../img/listMain2.png') no-repeat !important;
}
.mainMenu li.officeList.active span {
background: url('../img/list4tml.png') no-repeat center !important;
}
.mainMenu li.icon_tm2.active span{
background: url('../img/listMain2.png') no-repeat center !important;
}
.mainMenu li.icon_tm3.active span{
background: url('../img/listMain2.png') no-repeat right !important;
}
.faq_page_inn{
padding: 40px 0;
}
.faq_page_inn h2 {
font-size: 32px;
font-weight: normal;
margin-bottom: 20px;
margin-top: 10px;
}
.faq_page_inn h3{
font-weight: 600;
margin-bottom: 12px;
margin-top: 28px;
font-size: 1.17em;
}
.faq_page_inn ol, .faq_page_inn ul{
padding-left: 40px;
margin-top: 20px;
}
.faq_page_inn ol li, .faq_page_inn ul li{
padding-left: 8px;
list-style: inherit !important;
display: list-item;
list-style-type:inherit !important;
margin-top: 5px;
}
.faq_page_inn a{
text-decoration: underline !important;
}
.faq_page_inn a:hover{
text-decoration: none !important;
}
.faq_page_inn div{
margin-top: 20px;
}
a.linkS2[data-target="#withdraw-money"]{
float: none;
display: table;
margin: auto;
margin-bottom: 52px;
}
/*end_new*/

@ -101,12 +101,9 @@ function csrfSafeMethod(method) {
var socket = new SocketHandler();
var csrftoken = getCookie('csrftoken');
$(function () {
var currentHash = URI(location.href).hash();
console.log(currentHash);
if (currentHash.indexOf("#order") == 0) {
if (currentHash.indexOf("#order") == 0) {
var ordHashId = currentHash.replace("#order", "");
setTimeout(function () {
$("#orderBlock" + ordHashId).trigger('click');
@ -177,7 +174,6 @@ $(function () {
});
});
// Добавление сообщения для заказа.
$('#order-chat-add-message').on('click', function (e) {
e.preventDefault();
@ -255,18 +251,17 @@ $(function () {
});
});
$("#upload-document-order").bind('fileuploadsubmit', function(e, data){
data.formData = {
sender: $("#chat-order-add #senderId").val(),
recipent: $("#chat-order-add #recipentId").val(),
order: $("#chat-order-add #orderId").val(),
}
});
//Загрузка документов
$('#upload-document-order').fileupload({
url: '/chat/create/',
formData: {
sender: $("#chat-order-add #senderId").val(),
recipent: $("#chat-order-add #recipentId").val(),
order: $("#chat-order-add #orderId").val(),
},
crossDomain: false,
beforeSend: function (xhr, settings) {
$('#progress .progress-bar').css(
@ -297,6 +292,51 @@ $(function () {
progress + '%'
);
}
}).prop('disabled', !$.support.fileInput)
.parent().addClass($.support.fileInput ? undefined : 'disabled'); //Загрузка документов
$("#upload-document-contact").bind('fileuploadsubmit', function(e, data){
data.formData = {
sender: $("#contact-chat-form #senderContactId").val(),
recipent: $("#contact-chat-form #recipentContactId").val(),
}
});
$('#upload-document-contact').fileupload({
url: '/chat/create/',
crossDomain: false,
beforeSend: function (xhr, settings) {
console.log(this.formData);
$('#progress .progress-bar').css(
'width',
'0%'
);
if (!csrfSafeMethod(settings.type)) {
xhr.setRequestHeader("X-CSRFToken", csrftoken);
}
},
dataType: 'json',
done: function (e, data) {
$.each(data.result.files, function (index, file) {
var htmlImg = '<p>' + file.name + '</p>';
var document_send = $(htmlImg).appendTo("#document-send-contact");
});
},
fail: function (e) {
console.log(e);
},
progressall: function (e, data) {
var progress = parseInt(data.loaded / data.total * 100, 10);
$('#progress .progress-bar').css(
'width',
progress + '%'
);
}
}).prop('disabled', !$.support.fileInput)
.parent().addClass($.support.fileInput ? undefined : 'disabled');

@ -0,0 +1,21 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.9.7 on 2016-08-29 01:00
from __future__ import unicode_literals
from django.db import migrations, models
import django.utils.timezone
class Migration(migrations.Migration):
dependencies = [
('chat', '0007_auto_20160826_1458'),
]
operations = [
migrations.AddField(
model_name='documents',
name='created',
field=models.DateTimeField(default=django.utils.timezone.now),
),
]

@ -0,0 +1,20 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.9.7 on 2016-08-29 08:20
from __future__ import unicode_literals
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('chat', '0008_documents_created'),
]
operations = [
migrations.AlterField(
model_name='documents',
name='created',
field=models.DateTimeField(auto_now_add=True),
),
]

@ -45,6 +45,7 @@ class Documents(models.Model):
team = models.ForeignKey(Team, related_name='documents', null=True, blank=True)
sender = models.ForeignKey(User, related_name='sender_documents')
recipent = models.ForeignKey(User, related_name='recipent_documents', null=True, blank=True)
created = models.DateTimeField(auto_now_add=True)
def __str__(self):
return self.file.url

@ -4,6 +4,7 @@ from rest_framework.serializers import ModelSerializer
from .models import Message, Notes, Documents
from users.serializers import UserSerializer
class DocumentsSerializer(ModelSerializer):
class Meta:
@ -18,6 +19,7 @@ class DocumentsSerializer(ModelSerializer):
)
class MessageSerializer(ModelSerializer):
sender = UserSerializer()
recipent = UserSerializer()

@ -65,25 +65,32 @@
<div id="message-chat-space">
</div>
<form id="contact-chat-form">
<input type="hidden" value="{{ request.user.pk }}" name="senderId" id="senderId"/>
<input type="hidden" value="" name="recipentId" id="recipentId">
<input type="hidden" value="{{ request.user.pk }}" name="senderId" id="senderContactId"/>
<input type="hidden" name="recipentId" id="recipentContactId">
<textarea id="chat" name="chat_message" class="box-sizing"></textarea>
<div class="bunChat">
<div class="setChat box-sizing">
<p>Прикрепить файл</p>
<span>
Не более 10 файлов с общим объемом 500мб
</span>
<div class="setChat box-sizing upload">
<input type="file" name="file" id="upload-document-contact">
<p>Прикрепить файл</p>
</div>
<a id="contact-chat-add-message" href="#">отправить</a>
<div id="document-send-contact"></div>
<a id="contact-chat-add-message" href="#">отправить</a>
</div>
</form>
</div>
<div class="col-lg-3 wrChat1">
<div class="col-lg-12 documentsChat">
<p>Входящие документы</p>
<ul id="documentSpace">
</ul>
{# <a href="javascript:void(0)">#}
{# Распечатать с помощью ресурса#}
{# </a>#}
</div>
<div class="textAreaBlock2 box-sizing disTab">
<ul class="contractor-notes-block">
</ul>
@ -619,7 +626,7 @@
// Вытащить сообщения для конактов
$('.user-block').on('click', function () {
var userId = $(this).attr('data-id');
$("#contact-chat-form #recipentId").val(userId);
$("#contact-chat-form #recipentContactId").val(userId);
$("#add-form-contractor-note #recipentNoteContractor").val(userId);
$('.user-block').each(function () {
@ -628,7 +635,33 @@
$(this).addClass('mesAct');
var inbox = document.getElementById('message-chat-space');
var docList = document.getElementById('documentSpace');
inbox.innerHTML = '';
docList.innerHTML = '';
$.ajax({
url:'/api/documents',
type: 'GET',
data:{
csrfmiddlewaretoken: csrftoken,
'operand': 'in',
'sender_id': currentChatUser,
'recipent_id': userId
},
dataType: 'json',
success: function (json){
console.log(json);
$.each(json.results, function (i, v) {
docList.innerHTML += '<li style="word-break: break-all;">'+ v.file+'<div></div></li>';
});
},
error: function(e){
console.log(e);
}
});
$.ajax({
url: '/api/message',
type: 'GET',
@ -659,8 +692,8 @@
$('#contact-chat-add-message').on('click', function (e) {
e.preventDefault();
var chatMessage = $("#chat").val();
var recipentId = $("#recipentId").val();
var senderId = $("#senderId").val();
var recipentId = $("#recipentContactId").val();
var senderId = $("#senderContactId").val();
socket.add_contact_message({
"format_type": "add_message_contact",
@ -672,6 +705,7 @@
});
$("#chat").val("");
$("#document-send-contact").html("");
});

@ -19,7 +19,6 @@ class DocumentCreateView(CreateView):
fields = '__all__'
def form_valid(self, form):
# import code; code.interact(local=dict(globals(), **locals()))
self.object = form.save()
files = [serialize(self.object)]
data = {'files': files}

@ -313,8 +313,8 @@
{% csrf_token %}
<input type="hidden" name="next" value="{% url 'projects:detail' pk=project.pk %}">
<div><textarea name="text"></textarea></div>
<div><button type="submit">Отправить</button></div>
<div><textarea name="text" class="fr_answer"></textarea></div>
<div><button type="submit" class="fr_answer_sen">Отправить</button></div>
</form>
</div>
</div>

@ -9,14 +9,32 @@
</div>
</div>
</section>
<div class="container">
<div class="row faq_page_inn">
{% for block in page.body %}
{% if block.block_type == 'heading' %}
<h2>{{ block.value }}</h2>
{% else %}
<section class="block-{{ block.block_type }}">
{{ block }}
<h2>FAQ</h2>
<p>Lorem Ipsum has been the industry's standard dummy text ever since <a href="#">the 1500s</a>, when an <b>unknown</b> printer <strong>took a</strong> galley of type and scrambled it to make a type specimen book. It has </p>
<h3>is simply dummy text of the printing and typesetting industry</h3>
<ol>
<li>Many desktop publishing packages and web page editors now use Lorem Ipsum</li>
<li>Many desktop publishing packages and web page editors now use Lorem Ipsum</li>
<li>Many desktop publishing packages and web page editors now use Lorem Ipsum</li>
</ol>
<ul>
<li>Many desktop publishing packages and web page editors now use Lorem Ipsum</li>
<li>Many desktop publishing packages and web page editors now use Lorem Ipsum.</li>
<li>Many desktop publishing packages and web page editors now use Lorem Ipsum</li>
</ul>
<div>Contrary to popular belief, Lorem Ipsum is not simply random text. It has roots in a piece of classical Latin literature from 45 BC, making it over 2000 years old. Richard McClintock, a Latin professor at Hampden-Sydney College in Virginia, looked up one of the more obscure Latin words, consectetur, from a Lorem Ipsum passage, and going through the cites of the word in classical literature, discovered the undoubtable source. Lorem Ipsum </div>
</section>
{% endif %}
{% endfor %}
</div>
</div>
{% for block in page.body %}
{% if block.block_type == 'heading' %}
<h2>{{ block.value }}</h2>
{% else %}
<section class="block-{{ block.block_type }}">
{{ block }}
</section>
{% endif %}
{% endfor %}
{% endblock %}

@ -89,18 +89,21 @@
<span class="glyphicon glyphicon-menu-hamburger" aria-hidden="true"></span>
</button>
<ul class="dropdown-menu menu-drop-new">
{% if request.user.is_contractor %}
<li class="icon_mm1">
<a href="{% url 'auth_login' %}">
Войти заказчиком
<span></span>
</a>
</li>
{% else %}
<li class="icon_mm2">
<a href="{% url 'auth_login' %}">
Войти исполнителем
<span></span>
</a>
</li>
{% endif %}
<li class="icon_mm3">
<a href="{% url 'chat:chat-user' %}">Сообщения<span></span></a>
</li>

@ -42,7 +42,7 @@
</div>
<div class="searchF1 polsF1 polsFF polsF3">
<div class="searchF1 polsF1 polsFF polsF3 resSearchF1">
<div class="col-lg-3">
<a href="#" class="findReal" onclick="$(this).closest('form').submit(); return false">
найти исполнителя

@ -383,7 +383,9 @@
{% thumbnail diplom.img "210x334" crop="center" as im %}
<div class="imgGal"
style="background: url('{{ im.url }}') no-repeat center;">
<div class="imgFigure"></div>
<a href="{{ im.url }}" class='open-modal-image'>
<div class="imgFigure"></div>
</a>
</div>
{% endthumbnail %}
</div>
@ -414,7 +416,9 @@
{% thumbnail cro.img "210x334" crop="center" as im %}
<div class="imgGal"
style="background: url('{{ im.url }}') no-repeat center;">
<div class="imgFigure"></div>
<a href="{{ im.url }}" class='open-modal-image'>
<div class="imgFigure"></div>
</a>
</div>
{% endthumbnail %}
</div>

@ -106,7 +106,7 @@
<input type="text" class="searchInp box-sizing" value="{{ fin_info_form.fio.value }}" name="{{ fin_info_form.fio.html_name }}">
</div>
<div class="col-lg-3">
<input type="text" class="box-sizing surr surr2 datepicker" value="{{ fin_info_form.date_of_birth.value }}" name="{{ fin_info_form.date_of_birth.html_name }}">
<input type="text" class="box-sizing surr surr2 datepicker" value="{{ fin_info_form.date_of_birth.value|date:"d.m.Y" }}" name="{{ fin_info_form.date_of_birth.html_name }}">
</div>
<div class="col-lg-3">
<input type="text" class="box-sizing surr surr2" value="{{ fin_info_form.phone.value }}" name="{{ fin_info_form.phone.html_name }}">
@ -165,7 +165,7 @@
<input type="text" value="{{ fin_info_form.subdivision_code.value }}" class="box-sizing surr surr2" placeholder="0033" name="{{ fin_info_form.subdivision_code.html_name }}">
</div>
<div class="col-lg-3">
<input type="text" value="{{ fin_info_form.passport_issue_date.value }}" name="{{ fin_info_form.passport_issue_date.html_name }}" class="box-sizing surr surr2 datepicker" placeholder="11.12.1994">
<input type="text" value="{{ fin_info_form.passport_issue_date.value|date:"d.m.Y" }}" name="{{ fin_info_form.passport_issue_date.html_name }}" class="box-sizing surr surr2 datepicker" placeholder="11.12.1994">
</div>
</div>
@ -207,8 +207,11 @@
<input type="text" value="{{ fin_info_form.credit_card_number.value }}" class="box-sizing surr surr2" name="{{ fin_info_form.credit_card_number.html_name }}">
</div>
<div class="col-lg-3">
{{ fin_info_form.passport_scan.value }}
{% if fin_info_form.passport_scan.value %}
{# {{ fin_info_form.passport_scan.value }}#}
Скан-копия загружена
{% endif %}
<div class="upload2 up-l1 take-new">
<input type="file" name="{{ fin_info_form.passport_scan.html_name }}">
<p>Прикрепить файл</p>

@ -188,8 +188,6 @@ class ContractorFilterView(BaseMixin, View):
context.update({'last_party_types': last_party_types})
if get_contractors:
contractors = User.contractor_objects.all()
@ -216,9 +214,7 @@ class ContractorFilterView(BaseMixin, View):
if constr_type:
contractors = contractors.filter(orders__project__realty__construction_type=constr_type)
if get_teams:
teams = Team.objects.all()
@ -278,7 +274,6 @@ class ContractorFilterView(BaseMixin, View):
count = coll.count()
display_msg = 'Найдено %s групп' % count if count > 0 else 'Ничего не найдено'
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')
@ -421,9 +416,13 @@ class ContractorOfficeProjectsView(BaseMixin, View):
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))
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))
try:
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))
except:
team_open_projects = ()
team_archived_projects = ()
context['all_project_count'] = \
len(private_open_projects) + len(private_archived_projects) + \

@ -22,7 +22,7 @@
</div>
{% endif %}
<div class="col-lg-6">
<div class="col-lg-12">
<a href="#" data-toggle="modal" data-target="#withdraw-money"
class="linkS linkS2">вывести средства</a>
</div>

Loading…
Cancel
Save