diff --git a/archilance/settings/base.py b/archilance/settings/base.py index 86b3daf..918e962 100644 --- a/archilance/settings/base.py +++ b/archilance/settings/base.py @@ -280,7 +280,6 @@ REST_FRAMEWORK = { ], 'PAGE_SIZE': API_PAGE_SIZE, - 'DEFAULT_FILTER_BACKENDS': ('rest_framework_filters.backends.DjangoFilterBackend',), # djangorestframework-filters } diff --git a/assets/css/main.css b/assets/css/main.css index 749771a..ff529f7 100644 --- a/assets/css/main.css +++ b/assets/css/main.css @@ -6052,6 +6052,8 @@ input[type="radio"]{ } .welcomeMain{ line-height: 48px; + font-family: 'pfdintextcomppro-regular', sans-serif; + font-size: 43.5px; } .menuUser > div{ padding: 10px 0; diff --git a/assets/index.js b/assets/index.js index 4301312..6cef85c 100644 --- a/assets/index.js +++ b/assets/index.js @@ -23,6 +23,12 @@ $('[data-tooltip]').tooltip({ + + + + + + // Specialization select ----------------------------------- @@ -63,18 +69,65 @@ $('[data-tooltip]').tooltip({ } - $('.-spec-select-container').each(function(i, container) { + $('.-spec-work-type-combo-container').each(function(i, container) { var $container = $(container) var $specSelects = $container.find('.-spec-select') var $chosenSpecId = $container.find('.-chosen-spec-id').first() var $specSelect1 = $container.find('.-spec-select-level-1').first() + + window.select = $specSelect1 + var $specSelect2 = $container.find('.-spec-select-level-2').first() var $specSelect3 = $container.find('.-spec-select-level-3').first() var $specSelect4 = $container.find('.-spec-select-level-4').first() var specSelects = [$specSelect1, $specSelect2, $specSelect3, $specSelect4] - reinitSpecializationsByWorkType($specSelect1, null, $container) + + + + + var $workTypeSelect = $container.find('.-project-work-type-select-field').first() + + if (!_.isEmpty($workTypeSelect)) { + var workTypeId = Number($workTypeSelect.find('option:selected').first().val()) || 1 + + $workTypeSelect.on('change', function($evt) { + var $that = $(this) + var workTypeId = Number($that.val()) + + reinitSpecializationsByWorkType(specSelects, workTypeId).then(function(rootSpec) { + updateSpecializationWidgets(rootSpec.id, $container, $chosenSpecId, specSelects) + }) + }) + } else { + var $workTypeRadios = $container.find('.-project-work-type-radios-container').first().find('input[type=radio]') + + if (!_.isEmpty($workTypeRadios)) { + var workTypeId = Number($workTypeRadios.filter(':checked').val()) || 1 + + $workTypeRadios.on('change', function($evt) { + var $that = $(this) + var workTypeId = Number($that.val()) + + reinitSpecializationsByWorkType(specSelects, workTypeId).then(function(rootSpec) { + updateSpecializationWidgets(rootSpec.id, $container, $chosenSpecId, specSelects) + }) + }) + } else { + var workTypeId = 1 + } + } + + + + + + + reinitSpecializationsByWorkType(specSelects, workTypeId).then(function(rootSpec_) { + updateSpecializationWidgets(null, $container, $chosenSpecId, specSelects) + }) + var chosenSpecId = $chosenSpecId.val() @@ -88,15 +141,8 @@ $('[data-tooltip]').tooltip({ }) - function reinitSpecializationsByWorkType($specSelect1, workTypeId, $container) { - var $chosenSpecId = $container.find('.-chosen-spec-id').first() - - var $specSelect2 = $container.find('.-spec-select-level-2').first() - var $specSelect3 = $container.find('.-spec-select-level-3').first() - var $specSelect4 = $container.find('.-spec-select-level-4').first() - var specSelects = [$specSelect1, $specSelect2, $specSelect3, $specSelect4] - - $.get('/api/specializations/?parent__name=_root') + function reinitSpecializationsByWorkType(specSelects, workTypeId) { + return $.get('/api/specializations/?parent__name=_root') .then(function(res) { var rootSpecs = res.results @@ -109,13 +155,21 @@ $('[data-tooltip]').tooltip({ var url = format('/api/specializations/?lft__gte=%s&rght__lte=%s', rootSpec.lft, rootSpec.rght) } - $specSelect1.select2(_.merge(specSelectOptions, {ajax: {url: url}})) - updateSpecializationWidgets(specId, $container, $chosenSpecId, specSelects) + specSelects[0].select2(_.merge(specSelectOptions, {ajax: {url: url}})) + specSelects[1].select2(_.merge(specSelectOptions, {ajax: {url: null}})) + specSelects[2].select2(_.merge(specSelectOptions, {ajax: {url: null}})) + specSelects[3].select2(_.merge(specSelectOptions, {ajax: {url: null}})) + + + // TODO: Hardcoded: + + specSelects[0].select2('container').closest('.col-lg-3').css('display', workTypeId === 2 ? 'none' : 'block') + + + return rootSpec }) } - window.reinitSpecializationsByWorkType = reinitSpecializationsByWorkType - function updateSpecializationWidgets(specId, $container, $chosenSpecId, specSelects) { return getSpecializationTree(specId).then(function(specs) { @@ -137,18 +191,17 @@ $('[data-tooltip]').tooltip({ $chosenSpecId.val(specId) - specSelects[1].select2('container').css('display', !specLevel1 || _.isEmpty(specLevel1.children) ? 'none' : 'block') - specSelects[2].select2('container').css('display', !specLevel2 || _.isEmpty(specLevel2.children) ? 'none' : 'block') - specSelects[3].select2('container').css('display', !specLevel3 || _.isEmpty(specLevel3.children) ? 'none' : 'block') + specSelects[1].select2('enable', Boolean(specLevel1 && !_.isEmpty(specLevel1.children))) + specSelects[2].select2('enable', Boolean(specLevel2 && !_.isEmpty(specLevel2.children))) + specSelects[3].select2('enable', Boolean(specLevel3 && !_.isEmpty(specLevel3.children))) + + specializationTreeHasLevels(specId).then(function(haveLevels) { + specSelects[1].select2('container').css('display', haveLevels.level2 ? 'block' : 'none') + specSelects[2].select2('container').css('display', haveLevels.level3 ? 'block' : 'none') + specSelects[3].select2('container').css('display', haveLevels.level4 ? 'block' : 'none') + }) }) } - - window.updateSpecializationWidgets = updateSpecializationWidgets - - - //function repopulateSpecializations() { - // - //} }()) @@ -160,6 +213,9 @@ $('[data-tooltip]').tooltip({ + + + // Specialization select (simple) ------------------------------- @@ -903,6 +959,50 @@ function getLocationTree(locId) { +function specializationTreeHasLevels(specId) { + if (specId == null) { + var haveLevels = { + level2: true, + level3: true, + level4: true, + } + + return $.when(haveLevels) + } else { + return $.get(format('/api/specializations/%s/', specId)).then(function(spec) { + return $.get(format('/api/specializations/?level=1&lft__lte=%s&rght__gte=%s', spec.lft, spec.rght)).then(function(res) { + var specTreeRoot = res.results[0] + + var url_ = format('/api/specializations/?lft__gt=%s&rght__lt=%s&level=%s', specTreeRoot.lft, specTreeRoot.rght) + + return $.when( + $.get(format(url_, 2)).then(function(res) {return res}), + $.get(format(url_, 3)).then(function(res) {return res}), + $.get(format(url_, 4)).then(function(res) {return res}) + ) + .then(function(resLvl1, resLvl2, resLvl3) { + var haveLevels = { + level2: !_.isEmpty(resLvl1.results), + level3: !_.isEmpty(resLvl2.results), + level4: !_.isEmpty(resLvl3.results), + } + + return haveLevels + }) + }) + }) + } +} + + + + + + + + + + // Utils ----------------------------------------------- diff --git a/assets/js/chat.js b/assets/js/chat.js index 66235c7..4f06bea 100644 --- a/assets/js/chat.js +++ b/assets/js/chat.js @@ -29,7 +29,7 @@ window.confirm = function (message, callback, caption) { var SocketHandler = function () { domain = domain.replace(':' + port, ''); - var url = 'ws://' + domain + ':8888/chat/' + userId + '/'; + var url = 'ws://' + domain + '/chat/' + userId + '/'; var sock = new WebSocket(url); var intervalId; sock.onopen = function () { diff --git a/assets/js/chat_customer.js b/assets/js/chat_customer.js index a65172a..7615ce7 100644 --- a/assets/js/chat_customer.js +++ b/assets/js/chat_customer.js @@ -70,6 +70,7 @@ $(function () { } else { $("#stages-pay-form #stagesIds").val(currIdStage); $("#stagesSelect").prop('disabled', false); + $(".stageSum").text(sumStage); } }); diff --git a/chat/chat.py b/chat/chat.py index 57786f5..3da067e 100644 --- a/chat/chat.py +++ b/chat/chat.py @@ -127,7 +127,7 @@ class ChatHandler(websocket.WebSocketHandler): sender_name = msg_data[5] msg_time = msg_data[2].strftime("%Y-%m-%d %H:%M:%S") if docs_links: - message += '

' + docs_links; + message += '

' + docs_links if message_type: waiters = tuple(w for c, w in self.waiters if c == recipent_id) diff --git a/chat/templates/chat_customer.html b/chat/templates/chat_customer.html index 6819e67..9755e5a 100644 --- a/chat/templates/chat_customer.html +++ b/chat/templates/chat_customer.html @@ -140,7 +140,7 @@

{{ order }}

- + Исполнитель: {% if order.order.contractor %} {{ order.order.contractor.get_full_name }} diff --git a/projects/forms.py b/projects/forms.py index 3324403..7beb824 100644 --- a/projects/forms.py +++ b/projects/forms.py @@ -149,8 +149,14 @@ class CustomerProjectEditForm(forms.ModelForm): class RealtyForm(forms.ModelForm): - building_classification = TreeNodeChoiceField(BuildingClassfication.objects.all(), - widget=forms.Select(attrs={'class': 'selectpicker'})) + building_classification = TreeNodeChoiceField( + BuildingClassfication.objects.all(), + label="", initial='', + widget=forms.Select(attrs={ + 'class': 'selectpicker', + 'id': 'realtyBuildingClassificationId' + }) + ) class Meta: model = Realty @@ -194,6 +200,7 @@ class PortfolioForm(forms.ModelForm): 'construction_type': forms.Select(attrs={'class': 'selectpicker'}), 'currency': forms.Select(attrs={'class': 'selectpicker'}), 'term_type': forms.Select(attrs={'class': 'selectpicker'}), + 'work_type': forms.Select(attrs={'class': 'selectpicker -project-work-type-select-field'}), } diff --git a/projects/migrations/0043_auto_20160922_1705.py b/projects/migrations/0043_auto_20160922_1705.py new file mode 100644 index 0000000..0987b26 --- /dev/null +++ b/projects/migrations/0043_auto_20160922_1705.py @@ -0,0 +1,25 @@ +# -*- coding: utf-8 -*- +# Generated by Django 1.9.7 on 2016-09-22 14:05 +from __future__ import unicode_literals + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('projects', '0042_portfolio_work_type'), + ] + + operations = [ + migrations.AlterField( + model_name='portfolio', + name='work_type', + field=models.IntegerField(choices=[(1, 'Проектирование'), (2, 'Техническое сопровождение')], default=1), + ), + migrations.AlterField( + model_name='project', + name='work_type', + field=models.IntegerField(choices=[(1, 'Проектирование'), (2, 'Техническое сопровождение')], default=1), + ), + ] diff --git a/projects/migrations/0046_merge.py b/projects/migrations/0046_merge.py new file mode 100644 index 0000000..2257108 --- /dev/null +++ b/projects/migrations/0046_merge.py @@ -0,0 +1,16 @@ +# -*- coding: utf-8 -*- +# Generated by Django 1.9.7 on 2016-09-22 14:07 +from __future__ import unicode_literals + +from django.db import migrations + + +class Migration(migrations.Migration): + + dependencies = [ + ('projects', '0045_auto_20160922_0039'), + ('projects', '0043_auto_20160922_1705'), + ] + + operations = [ + ] diff --git a/projects/serializers.py b/projects/serializers.py index 1e5dd40..8c97bdd 100755 --- a/projects/serializers.py +++ b/projects/serializers.py @@ -258,19 +258,20 @@ class PortfolioSerializer(ModelSerializer): fields = ( # 'answers', - 'budget', 'building_classification', 'construction_type', + 'location', + 'photos', + 'specialization', + 'user', + + 'budget', 'currency', 'description', 'id', - 'location', 'name', - 'photos', - 'specialization', 'term', 'term_type', - 'user', 'worksell', ) diff --git a/projects/templates/contractor_portfolio_edit.html b/projects/templates/contractor_portfolio_edit.html index 521f57e..60721ee 100644 --- a/projects/templates/contractor_portfolio_edit.html +++ b/projects/templates/contractor_portfolio_edit.html @@ -26,8 +26,11 @@

Изменение портфолио

-
{% csrf_token %} + + {% csrf_token %} + {{ form.errors }} +

Название {{ form.name.errors.as_text }}

@@ -52,7 +55,7 @@

Специализации

-
+
@@ -72,7 +75,6 @@ -

Бюджет{{ form.budget.errors.as_text }}

@@ -170,39 +172,3 @@
{% endblock %} - - -{% block js_block %} - -{% endblock %} diff --git a/projects/templates/customer_project_create.html b/projects/templates/customer_project_create.html index 12319c8..a6c5ec6 100644 --- a/projects/templates/customer_project_create.html +++ b/projects/templates/customer_project_create.html @@ -17,7 +17,7 @@

Новый заказ

- + {% csrf_token %} @@ -59,7 +59,7 @@

Тип работы {{ form.work_type.errors.as_text }}

-
+
{% for id, text in form.work_type.field.choices %}
-
+
@@ -344,39 +344,5 @@ if (hash) window.location.hash = hash }()) - - - - // Load specialization choices by work type --------------------------- - - - ;(function() { - var $specSelectContainer = $('.-spec-select-container').first() - var $specSelects = $specSelectContainer.find('.-spec-select') - var $chosenSpecId = $specSelectContainer.find('.-chosen-spec-id').first() - - var $specSelect1 = $specSelectContainer.find('.-spec-select-level-1').first() - var $specSelect2 = $specSelectContainer.find('.-spec-select-level-2').first() - var $specSelect3 = $specSelectContainer.find('.-spec-select-level-3').first() - var $specSelect4 = $specSelectContainer.find('.-spec-select-level-4').first() - var specSelects = [$specSelect1, $specSelect2, $specSelect3, $specSelect4] - - var $radiosContainer = $('.-project-work-type-selection-container').first() - var $radios = $radiosContainer.find('input[type=radio][name={{ form.work_type.html_name }}]') - - var workTypeId = Number($radios.filter(':checked').val()) || 1 - reinitSpecializationsByWorkType($specSelect1, workTypeId, $specSelectContainer) - - var chosenSpecId = $chosenSpecId.val() - - if (chosenSpecId) - updateSpecializationWidgets(chosenSpecId, $specSelectContainer, $chosenSpecId, specSelects) - - $radios.on('change', function($evt) { - var $that = $(this) - var workTypeId = Number($that.val()) - reinitSpecializationsByWorkType($specSelect1, workTypeId, $specSelectContainer) - }) - }()) {% endblock %} diff --git a/projects/templates/customer_project_edit.html b/projects/templates/customer_project_edit.html index 05d9a81..7cbdefe 100644 --- a/projects/templates/customer_project_edit.html +++ b/projects/templates/customer_project_edit.html @@ -17,7 +17,7 @@

Изменение проекта

- + {% csrf_token %} @@ -69,7 +69,7 @@

Тип работы {{ form.work_type.errors.as_text }}

-
+
{% for id, text in form.work_type.field.choices %}
-
+
@@ -360,41 +360,5 @@ if (hash) window.location.hash = hash }()) - - - - // Load specialization choices by work type --------------------------- - - - ;(function() { - var $specSelectContainer = $('.-spec-select-container').first() - var $specSelects = $specSelectContainer.find('.-spec-select') - var $chosenSpecId = $specSelectContainer.find('.-chosen-spec-id').first() - - var $specSelect1 = $specSelectContainer.find('.-spec-select-level-1').first() - var $specSelect2 = $specSelectContainer.find('.-spec-select-level-2').first() - var $specSelect3 = $specSelectContainer.find('.-spec-select-level-3').first() - var $specSelect4 = $specSelectContainer.find('.-spec-select-level-4').first() - var specSelects = [$specSelect1, $specSelect2, $specSelect3, $specSelect4] - - var $radiosContainer = $('.-project-work-type-selection-container').first() - var $radios = $radiosContainer.find('input[type=radio][name={{ form.work_type.html_name }}]') - - var workTypeId = Number($radios.filter(':checked').val()) || 1 - reinitSpecializationsByWorkType($specSelects, workTypeId) - - var chosenSpecId = $chosenSpecId.val() - - if (chosenSpecId) - updateSpecializationWidgets(chosenSpecId, $specSelectContainer, $chosenSpecId, specSelects) - - $radios.on('change', function($evt) { - console.log('Radio change') - - var $that = $(this) - var workTypeId = $that.val() - reinitSpecializationsByWorkType($specSelects, workTypeId) - }) - }()) {% endblock %} diff --git a/projects/templates/project_filter.html b/projects/templates/project_filter.html index 686e66f..1527374 100644 --- a/projects/templates/project_filter.html +++ b/projects/templates/project_filter.html @@ -13,7 +13,7 @@
-
+
@@ -32,7 +32,7 @@
-
+
@@ -241,39 +241,3 @@
{% endblock %} - - -{% block js_block %} - -{% endblock %} diff --git a/projects/views.py b/projects/views.py index 295ef32..26b8f1c 100644 --- a/projects/views.py +++ b/projects/views.py @@ -279,6 +279,7 @@ class ProjectFilterView(BaseMixin, View): context = self.get_context_data(**_.merge({}, request.GET, kwargs)) projects = Project.objects.filter(state='active') + manual_sort = None if form.is_valid() and realty_form.is_valid(): ord = None @@ -333,8 +334,6 @@ class ProjectFilterView(BaseMixin, View): elif last_order_by: ord = last_order_by - 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 diff --git a/specializations/serializers.py b/specializations/serializers.py index 323041b..9e1a140 100755 --- a/specializations/serializers.py +++ b/specializations/serializers.py @@ -29,12 +29,13 @@ class SpecializationSerializer(ModelSerializer): fields = ( 'children', + 'parent', + 'projects', + 'id', 'level', 'lft', 'name', - 'parent', - 'projects', 'rght', 'tree_id', ) diff --git a/templates/partials/base.html b/templates/partials/base.html index d57fb43..9211d34 100644 --- a/templates/partials/base.html +++ b/templates/partials/base.html @@ -86,7 +86,7 @@ if ((queryString.indexOf('/chat') != 0) && (queryString.indexOf('/users/contractor-office/510/work-projects') != 0)) { domain = domain.replace(':' + port, ''); - var url = 'ws://' + domain + ':8888/chat/' + userId + '/'; + var url = 'ws://' + domain + '/chat/' + userId + '/'; var sock = new WebSocket(url); var intervalId; sock.onopen = function () { diff --git a/users/forms.py b/users/forms.py index cb6ae7e..69ee8e5 100644 --- a/users/forms.py +++ b/users/forms.py @@ -194,7 +194,7 @@ class ContractorFilterForm(forms.Form): work_type = forms.ChoiceField( choices=tuple(itertools.chain((('',''),), Project.WORK_TYPES)), - widget=forms.Select(attrs={'class': 'selectpicker'}), + widget=forms.Select(attrs={'class': 'selectpicker -project-work-type-select-field'}), required=False, ) diff --git a/users/templates/contractor_filter.html b/users/templates/contractor_filter.html index 8401561..42ab1b0 100644 --- a/users/templates/contractor_filter.html +++ b/users/templates/contractor_filter.html @@ -18,14 +18,29 @@
-
+
+
+
Тип работы
+
+ +
+
+ {{ form.work_type }} +
+
+ + + + + +
Специализации
-
+
@@ -104,7 +119,6 @@
Классификация здания
-
Тип работы
Вид строительства
@@ -113,10 +127,6 @@ {{ form.building_classification }}
-
- {{ form.work_type }} -
-
{{ form.construction_type }}
@@ -445,11 +455,11 @@ if (project.order.team && project.order.team.id === teamId) { window.location.href = projectOrderChatUrl } else { - var msg = 'Вашей команде предлагается проект http://{{ request.get_host }}' + projectUrl + var msg = 'Вашей команде предлагается проект http://{{ request.get_host }}' + projectUrl +'' socketMain.add_message({ format_type: 'add_message_contact', - + message_type: 'invite_order', data: { sender_id: String(customerId), recipent_id: String(contractorId), @@ -466,11 +476,11 @@ if (project.order.contractor && project.order.contractor.id === contractorId) { window.location.href = projectOrderChatUrl } else { - var msg = 'Вам предлагается проект http://{{ request.get_host }}' + projectUrl + var msg = 'Вам предлагается проект http://{{ request.get_host }}' + projectUrl +'' socketMain.add_message({ format_type: 'add_message_contact', - + message_type: 'invite_order', data: { sender_id: String(customerId), recipent_id: String(contractorId), diff --git a/users/templates/contractor_profile.html b/users/templates/contractor_profile.html index bea0be9..7248a1d 100644 --- a/users/templates/contractor_profile.html +++ b/users/templates/contractor_profile.html @@ -614,7 +614,7 @@ -{% endblock %}