Merge branch 'PR-45' into PR-54

remotes/origin/PR-58
booblegum 9 years ago
commit cb45ce94e2
  1. 5
      archilance/urls.py
  2. BIN
      assets/img/icons/icon_eye.png
  3. BIN
      assets/img/icons/icon_speach-ball_gray.png
  4. BIN
      assets/img/icons/icon_сertificate-512.png
  5. 68
      assets/js/build/create_worksell.js
  6. 203
      assets/js/build/customer_profile.js
  7. 4
      assets/js/build/home_page.js
  8. 61
      assets/js/build/init_create_worksell.js
  9. 61
      assets/js/build/init_customer_project_create.js
  10. 2
      assets/js/chat.js
  11. 12
      assets/js/src/customer_profile.js
  12. 24
      assets/js/src/seeds/bootstrap_tabs.js
  13. 6
      assets/js/src/seeds/show_hide.js
  14. 21
      assets/js/src/seeds/sort_by.js
  15. 2
      assets/sass/base/_colors.sass
  16. 99
      assets/sass/components/custom-components.sass
  17. 26
      assets/sass/main.sass
  18. 6
      assets/sass/modules/_mods.sass
  19. 5420
      assets/sass/old_main.sass
  20. 0
      chat/settings/__init__.py
  21. 20
      projects/migrations/0051_realty_state.py
  22. 21
      projects/migrations/0052_realty_created.py
  23. 18
      projects/models.py
  24. 1
      projects/static/css/project_filter.css
  25. 4
      projects/templates/project_detail.html
  26. 168
      projects/views.py
  27. 11
      specializations/models.py
  28. 4
      templates/home.html
  29. 162
      templates/partials/_base.html
  30. 2
      templates/partials/base.html
  31. 2
      templates/partials/header.html
  32. 134
      templates/partials/sass/footer.sass
  33. 13
      users/forms.py
  34. 11
      users/models.py
  35. 1
      users/static/css/user_profile_edit.css
  36. 178
      users/static/sass/customer-profile.sass
  37. 42
      users/templates/customer_profile.html
  38. 105
      users/templates/partials/inc-customer_profile-info.html
  39. 114
      users/templates/partials/inc-objects.html
  40. 99
      users/templates/partials/inc-projects.html
  41. 82
      users/templates/partials/tabs/tab-in_work_projects.html
  42. 48
      users/templates/partials/tabs/tab-objects.html
  43. 39
      users/templates/partials/tabs/tab-open_projects.html
  44. 29
      users/templates/partials/tabs/tab-rewiews.html
  45. 0
      users/templates/trash/customer_profile_current_projects.html
  46. 27
      users/templates/trash/customer_profile_info_block.html
  47. 0
      users/templates/trash/customer_profile_open_projects.html
  48. 0
      users/templates/trash/customer_profile_reviews.html
  49. 0
      users/templates/trash/customer_profile_trashed_projects.html
  50. 2
      users/templates/user_financial_info_edit.html
  51. 508
      users/templates/user_profile_edit.html
  52. 2
      users/templates/user_profile_edit_old.html
  53. 11
      users/urls.py
  54. 66
      users/views.py
  55. 2
      webpack.config.js

@ -10,6 +10,7 @@ from wagtail.wagtailcore import urls as wagtail_urls
from common.views import CustomRegistrationView from common.views import CustomRegistrationView
from wallets.views import TmpCheckOrderView, TmpPaymentAvisoView from wallets.views import TmpCheckOrderView, TmpPaymentAvisoView
from .views import HomeTemplateView, TestChatTemplateView, TestView from .views import HomeTemplateView, TestChatTemplateView, TestView
from projects.views import CustomerRealtyTrashView, CustomerRealtyDeleteView, CustomerRealtyRestoreView, SortRealtyBy
urlpatterns = [ urlpatterns = [
url(r'^$', HomeTemplateView.as_view()), url(r'^$', HomeTemplateView.as_view()),
@ -18,6 +19,10 @@ urlpatterns = [
url(r'^work_sell/', include('work_sell.urls')), url(r'^work_sell/', include('work_sell.urls')),
url(r'^test/$', TestView.as_view(), name='test'), url(r'^test/$', TestView.as_view(), name='test'),
url(r'^projects/', include('projects.urls')), url(r'^projects/', include('projects.urls')),
url(r'^object/(?P<pk>\d+)/trash/$', CustomerRealtyTrashView.as_view(), name='customer-object-trash'),
url(r'^object/(?P<pk>\d+)/delete/$', CustomerRealtyDeleteView.as_view(), name='customer-object-delete'),
url(r'^object/(?P<pk>\d+)/restore/$', CustomerRealtyRestoreView.as_view(), name='customer-object-restore'),
url(r'^objects/sort/$', SortRealtyBy.as_view(), name='sort-realty-by'),
url(r'^reviews/', include('reviews.urls')), url(r'^reviews/', include('reviews.urls')),
url(r'^wallets/', include('wallets.urls')), url(r'^wallets/', include('wallets.urls')),
url(r'^chat/', include('chat.urls')), url(r'^chat/', include('chat.urls')),

Binary file not shown.

After

Width:  |  Height:  |  Size: 71 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 67 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 19 KiB

@ -46,8 +46,6 @@
'use strict'; 'use strict';
var _file_upload = __webpack_require__(1);
var _image_upload = __webpack_require__(11); var _image_upload = __webpack_require__(11);
var _scroll_on_required = __webpack_require__(8); var _scroll_on_required = __webpack_require__(8);
@ -59,8 +57,6 @@
var _ajax_send_form_data = __webpack_require__(12); var _ajax_send_form_data = __webpack_require__(12);
$(function () { $(function () {
// fileUploadInit();
// previewImg();
(0, _image_upload.imageUploadInit)(); (0, _image_upload.imageUploadInit)();
(0, _scroll_on_required.scrollOnRequiredInit)(); (0, _scroll_on_required.scrollOnRequiredInit)();
(0, _popups.showPopupsInit)(); (0, _popups.showPopupsInit)();
@ -71,54 +67,7 @@
}); });
/***/ }, /***/ },
/* 1 */ /* 1 */,
/***/ function(module, exports, __webpack_require__) {
'use strict';
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.fileUploadInit = undefined;
var _utils = __webpack_require__(2);
function fileUploadInit() {
var $fileUploadContainer = $('#fileUploadContainer');
$('#fileUploadAddBtn').on('click', function ($evt) {
$fileUploadContainer.find('.file-upload-widget').last().find('.file-upload-input').click();
});
$fileUploadContainer.on('change', '.file-upload-input', function ($evt) {
var $fileInput = $(this);
var $fileUploadWidget = $fileInput.closest('.file-upload-widget');
var filePath = $fileInput.val().replace(/\\/g, '/');
var fileName = path.basename(filePath);
//var fileExt = path.extname(filePath)
var fileSize = $fileInput.get(0).files && (0, _utils.humanFileSize)($fileInput.get(0).files[0].size);
if (fileName) {
$fileUploadWidget.find('.file-upload-label').text(fileName + ' ' + fileSize);
var $newFileUploadWidget = $fileUploadWidget.clone();
$newFileUploadWidget.find('.file-upload-label').text('');
$fileUploadContainer.find('ul').first().append($newFileUploadWidget);
$fileUploadWidget.css('display', 'block');
}
});
$fileUploadContainer.on('click', '.file-upload-remove-btn', function ($evt) {
var $btn = $(this);
$btn.closest('.file-upload-widget').remove();
});
}
exports.fileUploadInit = fileUploadInit;
/***/ },
/* 2 */ /* 2 */
/***/ function(module, exports) { /***/ function(module, exports) {
@ -431,11 +380,8 @@
function sendFormData(e) { function sendFormData(e) {
e.preventDefault(); e.preventDefault();
// console.log("send dat later");
var $target = $(e.target); var $target = $(e.target);
var $form = $target.closest("form"); var $form = $target.closest("form");
// console.log("actions = ", $form.attr("action"));
// let url = $form.attr("action");
// let formData = $form.serializeArray(); // let formData = $form.serializeArray();
var formData = new FormData($form[0]); var formData = new FormData($form[0]);
$.ajax({ $.ajax({
@ -447,10 +393,8 @@
xhr.setRequestHeader("X-CSRFToken", (0, _utils.getCookie)('csrftoken')); xhr.setRequestHeader("X-CSRFToken", (0, _utils.getCookie)('csrftoken'));
}, },
success: function success(data) { success: function success(data) {
// console.log("success xhr -->", xhr);
// let data = xhr.responseJSON; // let data = xhr.responseJSON;
// console.log('success data -->', data); // console.log('success data -->', data);
// console.log('success data -->', data.redirect_to);
window.location.href = data.redirect_to; window.location.href = data.redirect_to;
}, },
cache: false, cache: false,
@ -459,25 +403,15 @@
error: function error(xhr, ajaxOptions, thrownError) { error: function error(xhr, ajaxOptions, thrownError) {
var status = xhr.status; var status = xhr.status;
$('.error').removeClass('error'); $('.error').removeClass('error');
// console.log('error data -->', xhr.responseJSON);
if (status == 400) { if (status == 400) {
// let data = JSON.parse(xhr.responseText);
var data = xhr.responseJSON; var data = xhr.responseJSON;
$.each(data, function (key, value) { $.each(data, function (key, value) {
// let ul = $("<ul class='errorlist'></ul>");
// for (let error of value) {
// ul.append(`<li>${error}</li>`)
// }
// console.log("key = ", key, "value =", value);
var $header = $form.find("[name=" + key + "]").siblings('.required'); var $header = $form.find("[name=" + key + "]").siblings('.required');
// console.log("$header = ", $header);
if ($header.length > 0) { if ($header.length > 0) {
$header.addClass("error"); $header.addClass("error");
} }
}); });
window.scrollOnRequiredInit(); window.scrollOnRequiredInit();
// console.log('captcha error = ', data.captcha);
// console.log('data type = ', typeof data);
} else { } else {
console.log('xhr = ', xhr); console.log('xhr = ', xhr);
} }

@ -0,0 +1,203 @@
/******/ (function(modules) { // webpackBootstrap
/******/ // The module cache
/******/ var installedModules = {};
/******/ // The require function
/******/ function __webpack_require__(moduleId) {
/******/ // Check if module is in cache
/******/ if(installedModules[moduleId])
/******/ return installedModules[moduleId].exports;
/******/ // Create a new module (and put it into the cache)
/******/ var module = installedModules[moduleId] = {
/******/ exports: {},
/******/ id: moduleId,
/******/ loaded: false
/******/ };
/******/ // Execute the module function
/******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__);
/******/ // Flag the module as loaded
/******/ module.loaded = true;
/******/ // Return the exports of the module
/******/ return module.exports;
/******/ }
/******/ // expose the modules object (__webpack_modules__)
/******/ __webpack_require__.m = modules;
/******/ // expose the module cache
/******/ __webpack_require__.c = installedModules;
/******/ // __webpack_public_path__
/******/ __webpack_require__.p = "";
/******/ // Load entry module and return exports
/******/ return __webpack_require__(0);
/******/ })
/************************************************************************/
/******/ ([
/* 0 */
/***/ function(module, exports, __webpack_require__) {
'use strict';
var _show_hide = __webpack_require__(13);
var _bootstrap_tabs = __webpack_require__(14);
var _sort_by = __webpack_require__(15);
$(function () {
(0, _bootstrap_tabs.restoreTab)();
(0, _bootstrap_tabs.tabsHashInit)();
window.toggler = _show_hide.toggler;
window.sortRealtyBy = _sort_by.sortRealtyBy;
// on load of the page: switch to the currently selected tab
});
/***/ },
/* 1 */,
/* 2 */
/***/ function(module, exports) {
'use strict';
Object.defineProperty(exports, "__esModule", {
value: true
});
function getCookie(name) {
var cookieValue = null;
if (document.cookie && document.cookie != '') {
var cookies = document.cookie.split(';');
for (var i = 0; i < cookies.length; i++) {
var cookie = jQuery.trim(cookies[i]);
if (cookie.substring(0, name.length + 1) == name + '=') {
cookieValue = decodeURIComponent(cookie.substring(name.length + 1));
break;
}
}
}
return cookieValue;
}
function humanFileSize(bytes, si) {
var thresh = si ? 1000 : 1024;
if (Math.abs(bytes) < thresh) return bytes + ' B';
var units = si ? ['kB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB'] : ['KiB', 'MiB', 'GiB', 'TiB', 'PiB', 'EiB', 'ZiB', 'YiB'];
var u = -1;
do {
bytes /= thresh;
++u;
} while (Math.abs(bytes) >= thresh && u < units.length - 1);
return bytes.toFixed(1) + ' ' + units[u];
}
exports.humanFileSize = humanFileSize;
exports.getCookie = getCookie;
/***/ },
/* 3 */,
/* 4 */,
/* 5 */,
/* 6 */,
/* 7 */,
/* 8 */,
/* 9 */,
/* 10 */,
/* 11 */,
/* 12 */,
/* 13 */
/***/ function(module, exports) {
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
function toggler(from, divId) {
$(from).toggleClass("clicked");
$("#" + divId).toggle();
}
exports.toggler = toggler;
/***/ },
/* 14 */
/***/ function(module, exports) {
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
function tabsHashInit() {
// store the currently selected tab in the hash value
$("a[data-toggle=tab]").on("shown.bs.tab", function (e) {
var target = $(e.target);
if (target.hasClass("tab-inserted")) {
target.siblings(".active").removeClass("active");
target.addClass("active");
return;
}
var id = target.attr("href").substr(1);
var scrollmem = $('body').scrollTop() || $('html').scrollTop();
window.location.hash = id;
$('html,body').scrollTop(scrollmem);
});
}
function restoreTab() {
// on load of the page: switch to the currently selected tab
var hash = window.location.hash;
var a = $("a[data-toggle=\"tab\"][href=\"" + hash + "\"]");
hash && a.tab('show');
}
exports.tabsHashInit = tabsHashInit;
exports.restoreTab = restoreTab;
/***/ },
/* 15 */
/***/ function(module, exports, __webpack_require__) {
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.sortRealtyBy = undefined;
var _utils = __webpack_require__(2);
function sortRealtyBy(data, container_id) {
console.log("sort_by = ", data);
console.log("container_id = ", container_id);
var url = '/objects/sort/';
$.ajax({
url: url,
type: 'POST',
data: data,
beforeSend: function beforeSend(xhr) {
xhr.setRequestHeader("X-CSRFToken", (0, _utils.getCookie)('csrftoken'));
},
success: function success(data) {
$(container_id).html(data);
// console.log("data = ", data);
}
});
}
exports.sortRealtyBy = sortRealtyBy;
/***/ }
/******/ ]);

@ -47,7 +47,7 @@
'use strict'; 'use strict';
var _popupYoutube = __webpack_require__(13); var _popupYoutube = __webpack_require__(16);
$(function () { $(function () {
(0, _popupYoutube.popupYoutubeInit)(); (0, _popupYoutube.popupYoutubeInit)();
@ -55,7 +55,7 @@
/***/ }, /***/ },
/***/ 13: /***/ 16:
/***/ function(module, exports) { /***/ function(module, exports) {
'use strict'; 'use strict';

@ -46,27 +46,27 @@
'use strict'; 'use strict';
var _SelectedContainer = __webpack_require__(14); var _SelectedContainer = __webpack_require__(17);
var _SelectedContainer2 = _interopRequireDefault(_SelectedContainer); var _SelectedContainer2 = _interopRequireDefault(_SelectedContainer);
var _SelectedContainerCreate = __webpack_require__(18); var _SelectedContainerCreate = __webpack_require__(21);
var _SelectedContainerCreate2 = _interopRequireDefault(_SelectedContainerCreate); var _SelectedContainerCreate2 = _interopRequireDefault(_SelectedContainerCreate);
var _NoTreeSelect = __webpack_require__(19); var _NoTreeSelect = __webpack_require__(22);
var _NoTreeSelect2 = _interopRequireDefault(_NoTreeSelect); var _NoTreeSelect2 = _interopRequireDefault(_NoTreeSelect);
var _TreeSelect = __webpack_require__(21); var _TreeSelect = __webpack_require__(24);
var _TreeSelect2 = _interopRequireDefault(_TreeSelect); var _TreeSelect2 = _interopRequireDefault(_TreeSelect);
var _SingleTreeSelect = __webpack_require__(22); var _SingleTreeSelect = __webpack_require__(25);
var _SingleTreeSelect2 = _interopRequireDefault(_SingleTreeSelect); var _SingleTreeSelect2 = _interopRequireDefault(_SingleTreeSelect);
var _SelectOrCreate = __webpack_require__(23); var _SelectOrCreate = __webpack_require__(26);
var _SelectOrCreate2 = _interopRequireDefault(_SelectOrCreate); var _SelectOrCreate2 = _interopRequireDefault(_SelectOrCreate);
@ -180,7 +180,10 @@
/* 11 */, /* 11 */,
/* 12 */, /* 12 */,
/* 13 */, /* 13 */,
/* 14 */ /* 14 */,
/* 15 */,
/* 16 */,
/* 17 */
/***/ function(module, exports, __webpack_require__) { /***/ function(module, exports, __webpack_require__) {
'use strict'; 'use strict';
@ -195,15 +198,15 @@
var _desc, _value, _class; // ` var _desc, _value, _class; // `
var _DataTree = __webpack_require__(15); var _DataTree = __webpack_require__(18);
var _DataTree2 = _interopRequireDefault(_DataTree); var _DataTree2 = _interopRequireDefault(_DataTree);
var _NoTreeData = __webpack_require__(16); var _NoTreeData = __webpack_require__(19);
var _NoTreeData2 = _interopRequireDefault(_NoTreeData); var _NoTreeData2 = _interopRequireDefault(_NoTreeData);
var _decorators = __webpack_require__(17); var _decorators = __webpack_require__(20);
var _decorators2 = _interopRequireDefault(_decorators); var _decorators2 = _interopRequireDefault(_decorators);
@ -434,7 +437,7 @@
exports.default = SelectedContainer; exports.default = SelectedContainer;
/***/ }, /***/ },
/* 15 */ /* 18 */
/***/ function(module, exports) { /***/ function(module, exports) {
"use strict"; "use strict";
@ -589,7 +592,7 @@
exports.default = DataTree; exports.default = DataTree;
/***/ }, /***/ },
/* 16 */ /* 19 */
/***/ function(module, exports) { /***/ function(module, exports) {
"use strict"; "use strict";
@ -645,7 +648,7 @@
exports.default = NoTreeData; exports.default = NoTreeData;
/***/ }, /***/ },
/* 17 */ /* 20 */
/***/ function(module, exports) { /***/ function(module, exports) {
"use strict"; "use strict";
@ -729,7 +732,7 @@
// export {onBind}; // export {onBind};
/***/ }, /***/ },
/* 18 */ /* 21 */
/***/ function(module, exports, __webpack_require__) { /***/ function(module, exports, __webpack_require__) {
'use strict'; 'use strict';
@ -745,11 +748,11 @@
var _desc, _value, _class; var _desc, _value, _class;
var _SelectedContainer2 = __webpack_require__(14); var _SelectedContainer2 = __webpack_require__(17);
var _SelectedContainer3 = _interopRequireDefault(_SelectedContainer2); var _SelectedContainer3 = _interopRequireDefault(_SelectedContainer2);
var _decorators = __webpack_require__(17); var _decorators = __webpack_require__(20);
var _decorators2 = _interopRequireDefault(_decorators); var _decorators2 = _interopRequireDefault(_decorators);
@ -830,7 +833,7 @@
exports.default = SelectedContainerCreate; exports.default = SelectedContainerCreate;
/***/ }, /***/ },
/* 19 */ /* 22 */
/***/ function(module, exports, __webpack_require__) { /***/ function(module, exports, __webpack_require__) {
'use strict'; 'use strict';
@ -844,9 +847,9 @@
var _get = function get(object, property, receiver) { if (object === null) object = Function.prototype; var desc = Object.getOwnPropertyDescriptor(object, property); if (desc === undefined) { var parent = Object.getPrototypeOf(object); if (parent === null) { return undefined; } else { return get(parent, property, receiver); } } else if ("value" in desc) { return desc.value; } else { var getter = desc.get; if (getter === undefined) { return undefined; } return getter.call(receiver); } }; var _get = function get(object, property, receiver) { if (object === null) object = Function.prototype; var desc = Object.getOwnPropertyDescriptor(object, property); if (desc === undefined) { var parent = Object.getPrototypeOf(object); if (parent === null) { return undefined; } else { return get(parent, property, receiver); } } else if ("value" in desc) { return desc.value; } else { var getter = desc.get; if (getter === undefined) { return undefined; } return getter.call(receiver); } };
var _AbsBaseSelect2 = __webpack_require__(20); var _AbsBaseSelect2 = __webpack_require__(23);
var _NoTreeData = __webpack_require__(16); var _NoTreeData = __webpack_require__(19);
var _NoTreeData2 = _interopRequireDefault(_NoTreeData); var _NoTreeData2 = _interopRequireDefault(_NoTreeData);
@ -913,7 +916,7 @@
exports.default = NoTreeSelect; exports.default = NoTreeSelect;
/***/ }, /***/ },
/* 20 */ /* 23 */
/***/ function(module, exports) { /***/ function(module, exports) {
"use strict"; "use strict";
@ -1457,7 +1460,7 @@
exports.AbsBaseSelect = AbsBaseSelect; exports.AbsBaseSelect = AbsBaseSelect;
/***/ }, /***/ },
/* 21 */ /* 24 */
/***/ function(module, exports, __webpack_require__) { /***/ function(module, exports, __webpack_require__) {
'use strict'; 'use strict';
@ -1471,9 +1474,9 @@
var _get = function get(object, property, receiver) { if (object === null) object = Function.prototype; var desc = Object.getOwnPropertyDescriptor(object, property); if (desc === undefined) { var parent = Object.getPrototypeOf(object); if (parent === null) { return undefined; } else { return get(parent, property, receiver); } } else if ("value" in desc) { return desc.value; } else { var getter = desc.get; if (getter === undefined) { return undefined; } return getter.call(receiver); } }; var _get = function get(object, property, receiver) { if (object === null) object = Function.prototype; var desc = Object.getOwnPropertyDescriptor(object, property); if (desc === undefined) { var parent = Object.getPrototypeOf(object); if (parent === null) { return undefined; } else { return get(parent, property, receiver); } } else if ("value" in desc) { return desc.value; } else { var getter = desc.get; if (getter === undefined) { return undefined; } return getter.call(receiver); } };
var _AbsBaseSelect2 = __webpack_require__(20); var _AbsBaseSelect2 = __webpack_require__(23);
var _DataTree = __webpack_require__(15); var _DataTree = __webpack_require__(18);
var _DataTree2 = _interopRequireDefault(_DataTree); var _DataTree2 = _interopRequireDefault(_DataTree);
@ -1582,7 +1585,7 @@
exports.default = TreeSelect; exports.default = TreeSelect;
/***/ }, /***/ },
/* 22 */ /* 25 */
/***/ function(module, exports, __webpack_require__) { /***/ function(module, exports, __webpack_require__) {
'use strict'; 'use strict';
@ -1594,9 +1597,9 @@
var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
var _AbsBaseSelect = __webpack_require__(20); var _AbsBaseSelect = __webpack_require__(23);
var _TreeSelect2 = __webpack_require__(21); var _TreeSelect2 = __webpack_require__(24);
var _TreeSelect3 = _interopRequireDefault(_TreeSelect2); var _TreeSelect3 = _interopRequireDefault(_TreeSelect2);
@ -1677,7 +1680,7 @@
exports.default = SingleTreeSelect; exports.default = SingleTreeSelect;
/***/ }, /***/ },
/* 23 */ /* 26 */
/***/ function(module, exports, __webpack_require__) { /***/ function(module, exports, __webpack_require__) {
'use strict'; 'use strict';
@ -1691,9 +1694,9 @@
var _get = function get(object, property, receiver) { if (object === null) object = Function.prototype; var desc = Object.getOwnPropertyDescriptor(object, property); if (desc === undefined) { var parent = Object.getPrototypeOf(object); if (parent === null) { return undefined; } else { return get(parent, property, receiver); } } else if ("value" in desc) { return desc.value; } else { var getter = desc.get; if (getter === undefined) { return undefined; } return getter.call(receiver); } }; var _get = function get(object, property, receiver) { if (object === null) object = Function.prototype; var desc = Object.getOwnPropertyDescriptor(object, property); if (desc === undefined) { var parent = Object.getPrototypeOf(object); if (parent === null) { return undefined; } else { return get(parent, property, receiver); } } else if ("value" in desc) { return desc.value; } else { var getter = desc.get; if (getter === undefined) { return undefined; } return getter.call(receiver); } };
var _AbsBaseSelect2 = __webpack_require__(20); var _AbsBaseSelect2 = __webpack_require__(23);
var _NoTreeData = __webpack_require__(16); var _NoTreeData = __webpack_require__(19);
var _NoTreeData2 = _interopRequireDefault(_NoTreeData); var _NoTreeData2 = _interopRequireDefault(_NoTreeData);

@ -46,27 +46,27 @@
'use strict'; 'use strict';
var _SelectedContainer = __webpack_require__(14); var _SelectedContainer = __webpack_require__(17);
var _SelectedContainer2 = _interopRequireDefault(_SelectedContainer); var _SelectedContainer2 = _interopRequireDefault(_SelectedContainer);
var _SelectedContainerCreate = __webpack_require__(18); var _SelectedContainerCreate = __webpack_require__(21);
var _SelectedContainerCreate2 = _interopRequireDefault(_SelectedContainerCreate); var _SelectedContainerCreate2 = _interopRequireDefault(_SelectedContainerCreate);
var _NoTreeSelect = __webpack_require__(19); var _NoTreeSelect = __webpack_require__(22);
var _NoTreeSelect2 = _interopRequireDefault(_NoTreeSelect); var _NoTreeSelect2 = _interopRequireDefault(_NoTreeSelect);
var _TreeSelect = __webpack_require__(21); var _TreeSelect = __webpack_require__(24);
var _TreeSelect2 = _interopRequireDefault(_TreeSelect); var _TreeSelect2 = _interopRequireDefault(_TreeSelect);
var _SingleTreeSelect = __webpack_require__(22); var _SingleTreeSelect = __webpack_require__(25);
var _SingleTreeSelect2 = _interopRequireDefault(_SingleTreeSelect); var _SingleTreeSelect2 = _interopRequireDefault(_SingleTreeSelect);
var _SelectOrCreate = __webpack_require__(23); var _SelectOrCreate = __webpack_require__(26);
var _SelectOrCreate2 = _interopRequireDefault(_SelectOrCreate); var _SelectOrCreate2 = _interopRequireDefault(_SelectOrCreate);
@ -215,7 +215,10 @@
/* 11 */, /* 11 */,
/* 12 */, /* 12 */,
/* 13 */, /* 13 */,
/* 14 */ /* 14 */,
/* 15 */,
/* 16 */,
/* 17 */
/***/ function(module, exports, __webpack_require__) { /***/ function(module, exports, __webpack_require__) {
'use strict'; 'use strict';
@ -230,15 +233,15 @@
var _desc, _value, _class; // ` var _desc, _value, _class; // `
var _DataTree = __webpack_require__(15); var _DataTree = __webpack_require__(18);
var _DataTree2 = _interopRequireDefault(_DataTree); var _DataTree2 = _interopRequireDefault(_DataTree);
var _NoTreeData = __webpack_require__(16); var _NoTreeData = __webpack_require__(19);
var _NoTreeData2 = _interopRequireDefault(_NoTreeData); var _NoTreeData2 = _interopRequireDefault(_NoTreeData);
var _decorators = __webpack_require__(17); var _decorators = __webpack_require__(20);
var _decorators2 = _interopRequireDefault(_decorators); var _decorators2 = _interopRequireDefault(_decorators);
@ -469,7 +472,7 @@
exports.default = SelectedContainer; exports.default = SelectedContainer;
/***/ }, /***/ },
/* 15 */ /* 18 */
/***/ function(module, exports) { /***/ function(module, exports) {
"use strict"; "use strict";
@ -624,7 +627,7 @@
exports.default = DataTree; exports.default = DataTree;
/***/ }, /***/ },
/* 16 */ /* 19 */
/***/ function(module, exports) { /***/ function(module, exports) {
"use strict"; "use strict";
@ -680,7 +683,7 @@
exports.default = NoTreeData; exports.default = NoTreeData;
/***/ }, /***/ },
/* 17 */ /* 20 */
/***/ function(module, exports) { /***/ function(module, exports) {
"use strict"; "use strict";
@ -764,7 +767,7 @@
// export {onBind}; // export {onBind};
/***/ }, /***/ },
/* 18 */ /* 21 */
/***/ function(module, exports, __webpack_require__) { /***/ function(module, exports, __webpack_require__) {
'use strict'; 'use strict';
@ -780,11 +783,11 @@
var _desc, _value, _class; var _desc, _value, _class;
var _SelectedContainer2 = __webpack_require__(14); var _SelectedContainer2 = __webpack_require__(17);
var _SelectedContainer3 = _interopRequireDefault(_SelectedContainer2); var _SelectedContainer3 = _interopRequireDefault(_SelectedContainer2);
var _decorators = __webpack_require__(17); var _decorators = __webpack_require__(20);
var _decorators2 = _interopRequireDefault(_decorators); var _decorators2 = _interopRequireDefault(_decorators);
@ -865,7 +868,7 @@
exports.default = SelectedContainerCreate; exports.default = SelectedContainerCreate;
/***/ }, /***/ },
/* 19 */ /* 22 */
/***/ function(module, exports, __webpack_require__) { /***/ function(module, exports, __webpack_require__) {
'use strict'; 'use strict';
@ -879,9 +882,9 @@
var _get = function get(object, property, receiver) { if (object === null) object = Function.prototype; var desc = Object.getOwnPropertyDescriptor(object, property); if (desc === undefined) { var parent = Object.getPrototypeOf(object); if (parent === null) { return undefined; } else { return get(parent, property, receiver); } } else if ("value" in desc) { return desc.value; } else { var getter = desc.get; if (getter === undefined) { return undefined; } return getter.call(receiver); } }; var _get = function get(object, property, receiver) { if (object === null) object = Function.prototype; var desc = Object.getOwnPropertyDescriptor(object, property); if (desc === undefined) { var parent = Object.getPrototypeOf(object); if (parent === null) { return undefined; } else { return get(parent, property, receiver); } } else if ("value" in desc) { return desc.value; } else { var getter = desc.get; if (getter === undefined) { return undefined; } return getter.call(receiver); } };
var _AbsBaseSelect2 = __webpack_require__(20); var _AbsBaseSelect2 = __webpack_require__(23);
var _NoTreeData = __webpack_require__(16); var _NoTreeData = __webpack_require__(19);
var _NoTreeData2 = _interopRequireDefault(_NoTreeData); var _NoTreeData2 = _interopRequireDefault(_NoTreeData);
@ -948,7 +951,7 @@
exports.default = NoTreeSelect; exports.default = NoTreeSelect;
/***/ }, /***/ },
/* 20 */ /* 23 */
/***/ function(module, exports) { /***/ function(module, exports) {
"use strict"; "use strict";
@ -1492,7 +1495,7 @@
exports.AbsBaseSelect = AbsBaseSelect; exports.AbsBaseSelect = AbsBaseSelect;
/***/ }, /***/ },
/* 21 */ /* 24 */
/***/ function(module, exports, __webpack_require__) { /***/ function(module, exports, __webpack_require__) {
'use strict'; 'use strict';
@ -1506,9 +1509,9 @@
var _get = function get(object, property, receiver) { if (object === null) object = Function.prototype; var desc = Object.getOwnPropertyDescriptor(object, property); if (desc === undefined) { var parent = Object.getPrototypeOf(object); if (parent === null) { return undefined; } else { return get(parent, property, receiver); } } else if ("value" in desc) { return desc.value; } else { var getter = desc.get; if (getter === undefined) { return undefined; } return getter.call(receiver); } }; var _get = function get(object, property, receiver) { if (object === null) object = Function.prototype; var desc = Object.getOwnPropertyDescriptor(object, property); if (desc === undefined) { var parent = Object.getPrototypeOf(object); if (parent === null) { return undefined; } else { return get(parent, property, receiver); } } else if ("value" in desc) { return desc.value; } else { var getter = desc.get; if (getter === undefined) { return undefined; } return getter.call(receiver); } };
var _AbsBaseSelect2 = __webpack_require__(20); var _AbsBaseSelect2 = __webpack_require__(23);
var _DataTree = __webpack_require__(15); var _DataTree = __webpack_require__(18);
var _DataTree2 = _interopRequireDefault(_DataTree); var _DataTree2 = _interopRequireDefault(_DataTree);
@ -1617,7 +1620,7 @@
exports.default = TreeSelect; exports.default = TreeSelect;
/***/ }, /***/ },
/* 22 */ /* 25 */
/***/ function(module, exports, __webpack_require__) { /***/ function(module, exports, __webpack_require__) {
'use strict'; 'use strict';
@ -1629,9 +1632,9 @@
var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
var _AbsBaseSelect = __webpack_require__(20); var _AbsBaseSelect = __webpack_require__(23);
var _TreeSelect2 = __webpack_require__(21); var _TreeSelect2 = __webpack_require__(24);
var _TreeSelect3 = _interopRequireDefault(_TreeSelect2); var _TreeSelect3 = _interopRequireDefault(_TreeSelect2);
@ -1712,7 +1715,7 @@
exports.default = SingleTreeSelect; exports.default = SingleTreeSelect;
/***/ }, /***/ },
/* 23 */ /* 26 */
/***/ function(module, exports, __webpack_require__) { /***/ function(module, exports, __webpack_require__) {
'use strict'; 'use strict';
@ -1726,9 +1729,9 @@
var _get = function get(object, property, receiver) { if (object === null) object = Function.prototype; var desc = Object.getOwnPropertyDescriptor(object, property); if (desc === undefined) { var parent = Object.getPrototypeOf(object); if (parent === null) { return undefined; } else { return get(parent, property, receiver); } } else if ("value" in desc) { return desc.value; } else { var getter = desc.get; if (getter === undefined) { return undefined; } return getter.call(receiver); } }; var _get = function get(object, property, receiver) { if (object === null) object = Function.prototype; var desc = Object.getOwnPropertyDescriptor(object, property); if (desc === undefined) { var parent = Object.getPrototypeOf(object); if (parent === null) { return undefined; } else { return get(parent, property, receiver); } } else if ("value" in desc) { return desc.value; } else { var getter = desc.get; if (getter === undefined) { return undefined; } return getter.call(receiver); } };
var _AbsBaseSelect2 = __webpack_require__(20); var _AbsBaseSelect2 = __webpack_require__(23);
var _NoTreeData = __webpack_require__(16); var _NoTreeData = __webpack_require__(19);
var _NoTreeData2 = _interopRequireDefault(_NoTreeData); var _NoTreeData2 = _interopRequireDefault(_NoTreeData);

@ -29,7 +29,7 @@ window.confirm = function (message, callback, caption) {
var SocketHandler = function () { var SocketHandler = function () {
//TODO: получать порт с файла настроек //TODO: получать порт с файла настроек
domain = domain.replace(':' + port, ''); domain = domain.replace(':' + port, ':8888');
if (window.location.protocol == 'https:') { if (window.location.protocol == 'https:') {
var ws = "wss://"; var ws = "wss://";
} else { } else {

@ -0,0 +1,12 @@
import {toggler} from './seeds/show_hide'
import {tabsHashInit, restoreTab} from './seeds/bootstrap_tabs'
import {sortRealtyBy} from './seeds/sort_by'
$(function () {
restoreTab();
tabsHashInit();
window.toggler = toggler;
window.sortRealtyBy = sortRealtyBy;
// on load of the page: switch to the currently selected tab
});

@ -0,0 +1,24 @@
function tabsHashInit() {
// store the currently selected tab in the hash value
$("a[data-toggle=tab]").on("shown.bs.tab", function (e) {
let target = $(e.target);
if(target.hasClass("tab-inserted")){
target.siblings(".active").removeClass("active");
target.addClass("active");
return
}
let id = target.attr("href").substr(1);
let scrollmem = $('body').scrollTop() || $('html').scrollTop();
window.location.hash = id;
$('html,body').scrollTop(scrollmem);
});
}
function restoreTab() {
// on load of the page: switch to the currently selected tab
let hash = window.location.hash;
let a = $(`a[data-toggle="tab"][href="${hash}"]`);
hash && a.tab('show');
}
export {tabsHashInit, restoreTab}

@ -0,0 +1,6 @@
function toggler(from, divId) {
$(from).toggleClass("clicked");
$("#" + divId).toggle();
}
export {toggler}

@ -0,0 +1,21 @@
import {getCookie} from '../utils'
function sortRealtyBy(data, container_id) {
console.log("sort_by = ", data);
console.log("container_id = ", container_id);
let url = '/objects/sort/';
$.ajax({
url: url,
type: 'POST',
data: data,
beforeSend: function (xhr) {
xhr.setRequestHeader("X-CSRFToken", getCookie('csrftoken'))
},
success: function (data) {
$(container_id).html(data);
// console.log("data = ", data);
}
})
}
export {sortRealtyBy}

@ -1,6 +1,6 @@
$col_component_headers: #000 $col_component_headers: #000
//$colors: (c_red: #ff0000, c_green: #00FF00, c_blue: #0000FF) //$colors: (c_red: #ff0000, c_green: #00FF00, c_blue: #0000FF)
$component_colors: (header: #000, header_favicon: #5e5e5e, border: #cccccc, select: #FF0029) $component_colors: (header: #000, header_favicon: #5e5e5e, border: #cccccc, select: #FF0029, footer_background: #F7F7F7)
// #{map_get($component_colors, border)} // #{map_get($component_colors, border)}

@ -10,6 +10,9 @@
label label
font-weight: normal font-weight: normal
li.active
border-top: 2px solid black
.simple-input .simple-input
height: 51px height: 51px
width: 100% width: 100%
@ -65,6 +68,7 @@ textarea.description
font-style: italic font-style: italic
.btn-simple .btn-simple
text-transform: uppercase
border-radius: 40px border-radius: 40px
padding: 10px 15px padding: 10px 15px
border: 1px solid #FF0029 border: 1px solid #FF0029
@ -74,9 +78,9 @@ textarea.description
font-style: normal font-style: normal
font-size: 14pt font-size: 14pt
display: inline-block display: inline-block
color: #000 color: #4e4c4c
&:hover &:hover
color: #000 color: #4e4c4c
text-decoration: none text-decoration: none
box-shadow: 0 0 15px rgba(0, 0, 0, 0.2) box-shadow: 0 0 15px rgba(0, 0, 0, 0.2)
-webkit-transform: scale(1.04) -webkit-transform: scale(1.04)
@ -87,6 +91,38 @@ textarea.description
&:active &:active
outline: 0 !important outline: 0 !important
&.-small
padding: 5px 14px
font-size: 10pt
&.-gray
border: 1px solid #bdbdbd
&.-up_down:after
content: "\e252"
font-family: 'Glyphicons Halflings'
position: relative
right: -5px
top: 3px
font-style: normal
font-weight: normal
font-size: 10pt
line-height: 1
padding-right: 20px
-webkit-font-smoothing: antialiased
.icon-edit
//padding-left: 30px
//content: ''
display: inline-block
width: 40px
height: 20px
background:
image: url("#{$static}/img/menuUser.png")
//color: #00A66E
repeat: no-repeat
position: 0 0
.upload-new, .btn-simple .upload-new, .btn-simple
transition: all 0.3s transition: all 0.3s
cursor: pointer cursor: pointer
@ -259,3 +295,62 @@ textarea.description
&.less &.less
&:before &:before
content: 'свернуть' content: 'свернуть'
.btn-group
.btn
padding: 15px 30px
.btn-round
$radius: 30px
.btn:first-child
border-top-left-radius: $radius
border-bottom-left-radius: $radius
.btn:last-child
border-top-right-radius: $radius
border-bottom-right-radius: $radius
.link-sort button
font-size: 14px
font-family: 'Arial-MT-Regular', sans-serif
color: #6b6b6b
padding: 11px 23px
border-radius: 40px
margin-right: 6px
border: 1px solid #c2c2c2
background-color: #fff
&:after
content: "\e252"
font-family: 'Glyphicons Halflings'
position: relative
right: -5px
top: 3px
font-style: normal
font-weight: normal
line-height: 1
-webkit-font-smoothing: antialiased
.btn-up_down
width: 110px
text-transform: uppercase
font-size: 10pt
font-family: 'Myriad', sans-serif
color: #6b6b6b
padding: 11px 23px
border-radius: 40px
margin-right: 6px
border: 1px solid #c2c2c2
background-color: #fff
&:after
content: "\e253"
font-family: 'Glyphicons Halflings'
font-style: normal
font-weight: normal
line-height: 1
-webkit-font-smoothing: antialiased
&.-small
padding: 5px 10px
.btn-up_down.clicked
&:after
content: "\e252"

@ -1,3 +1,9 @@
/********************************
* Общие стили для ВСЕХ страниц *
* 10 раз подумайет, прежде чем *
* добавить сюда стили *
********************************/
@import "base/fonts" @import "base/fonts"
@import "base/colors" @import "base/colors"
@import "base/variavles" @import "base/variavles"
@ -8,6 +14,12 @@ body
font-size: 11pt font-size: 11pt
font-family: Arial-MT-Regular, Arial, sans-serif font-family: Arial-MT-Regular, Arial, sans-serif
.btn-default:focus
outline: 0
.hidden
display: none
.main-scope .main-scope
> .row > .row
border-right: 1px solid #{map_get($component_colors, border)} border-right: 1px solid #{map_get($component_colors, border)}
@ -21,7 +33,6 @@ body
padding: 0 100px padding: 0 100px
text-align: center text-align: center
border-bottom: 1px solid #{map_get($component_colors, border)} border-bottom: 1px solid #{map_get($component_colors, border)}
//width: 100%
h1 h1
font: font:
family: 'pfbeausanspro-thin', sans-serif family: 'pfbeausanspro-thin', sans-serif
@ -41,12 +52,6 @@ body
@extend %header @extend %header
max-width: 100% max-width: 100%
.logical-block
$pad: 30px
padding-top: $pad
padding-bottom: $pad
margin-top: $pad
.select-text .select-text
color: #{map_get($component_colors, select)} color: #{map_get($component_colors, select)}
@ -56,3 +61,10 @@ body
.slide.active .slide.active
display: block display: block
.footer-wrapper
background-color: #{map_get($component_colors, footer_background)}
.footer-border
border-left: 1px solid #{map_get($component_colors, border)}
border-right: 1px solid #{map_get($component_colors, border)}

@ -8,11 +8,15 @@
align-items: flex-end align-items: flex-end
.mod-align-center .mod-align-center
display: flex display: flex !important
-ms-flex-align: center -ms-flex-align: center
-webkit-align-items: center -webkit-align-items: center
-webkit-box-align: center -webkit-box-align: center
align-items: center align-items: center
&-inline
display: inline-flex !important
align-items: center
.mod-no-padding .mod-no-padding
padding: 0 !important padding: 0 !important

File diff suppressed because it is too large Load Diff

@ -0,0 +1,20 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.9.7 on 2016-12-21 09:57
from __future__ import unicode_literals
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('projects', '0050_auto_20161207_1637'),
]
operations = [
migrations.AddField(
model_name='realty',
name='state',
field=models.CharField(choices=[('active', 'Активный'), ('trashed', 'В корзине'), ('deleted', 'Удален')], default='active', max_length=20),
),
]

@ -0,0 +1,21 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.9.7 on 2016-12-22 07:25
from __future__ import unicode_literals
from django.db import migrations, models
import django.utils.timezone
class Migration(migrations.Migration):
dependencies = [
('projects', '0051_realty_state'),
]
operations = [
migrations.AddField(
model_name='realty',
name='created',
field=models.DateTimeField(default=django.utils.timezone.now),
),
]

@ -7,6 +7,7 @@ from django.utils import timezone
from hitcount.models import HitCountMixin from hitcount.models import HitCountMixin
from mptt.managers import TreeManager from mptt.managers import TreeManager
from mptt.models import TreeForeignKey, MPTTModel from mptt.models import TreeForeignKey, MPTTModel
from django.db.models import Sum, Count
_.map = _.map_; _.map = _.map_;
_.filter = _.filter_ _.filter = _.filter_
@ -68,15 +69,25 @@ class ConstructionType(models.Model):
class Realty(models.Model): class Realty(models.Model):
STATES = (
('active', 'Активный'),
('trashed', 'В корзине'),
('deleted', 'Удален'),
)
building_classification = TreeForeignKey(BuildingClassfication, related_name='realties', null=True, blank=True) building_classification = TreeForeignKey(BuildingClassfication, related_name='realties', null=True, blank=True)
construction_type = models.ForeignKey(ConstructionType, related_name='realties', null=True, blank=True) construction_type = models.ForeignKey(ConstructionType, related_name='realties', null=True, blank=True)
location = TreeForeignKey('common.Location', related_name='realties', null=True, blank=True) created = models.DateTimeField(default=timezone.now)
name = models.CharField(max_length=255, blank=True)
# Виртуальные объекты привязываются к Проектам, для которых Объект не создан явно # Виртуальные объекты привязываются к Проектам, для которых Объект не создан явно
is_virtual = models.BooleanField(default=False, editable=False) is_virtual = models.BooleanField(default=False, editable=False)
location = TreeForeignKey('common.Location', related_name='realties', null=True, blank=True)
name = models.CharField(max_length=255, blank=True)
state = models.CharField(default='active', max_length=20, choices=STATES)
user = models.ForeignKey(User, related_name='realties') # Do we actually need this field? user = models.ForeignKey(User, related_name='realties') # Do we actually need this field?
def __str__(self): def __str__(self):
if self.is_virtual:
return "Virtual"
return self.name return self.name
class Meta: class Meta:
@ -139,6 +150,9 @@ class Project(models.Model, HitCountMixin):
def get_team_answers(self): def get_team_answers(self):
return _.filter(self.answers.all(), lambda a: isinstance(a.author, Team)) return _.filter(self.answers.all(), lambda a: isinstance(a.author, Team))
def message_count(self):
return self.answers.aggregate(c=Count('messages'))['c']
class ProjectFile(models.Model): class ProjectFile(models.Model):
file = models.FileField(upload_to='projects/project_files/') file = models.FileField(upload_to='projects/project_files/')

@ -24,6 +24,7 @@ body {
.header { .header {
display: block;
font-size: 12pt; font-size: 12pt;
color: black; color: black;
} }

@ -34,7 +34,7 @@
{% endif %} {% endif %}
<div class="col-lg-4"> <div class="col-lg-4">
<a href="{% url 'users:customer-profile-open-projects' project.customer.pk %}" class="aLinkExe"> <a href="{% url 'users:customer-profile' project.customer.pk %}" class="aLinkExe">
<div class="imgExecutor"> <div class="imgExecutor">
{% if project.customer.avatar %} {% if project.customer.avatar %}
{% thumbnail project.customer.avatar "125x125" crop="center" as im %} {% thumbnail project.customer.avatar "125x125" crop="center" as im %}
@ -46,7 +46,7 @@
</div> </div>
</a> </a>
<p class="nameExecutor"> <p class="nameExecutor">
<a href="{% url 'users:customer-profile-open-projects' project.customer.pk %}">{{ project.customer.get_full_name }} <a href="{% url 'users:customer-profile' project.customer.pk %}">{{ project.customer.get_full_name }}
[{{ project.customer.username }}]</a> [{{ project.customer.username }}]</a>
</p> </p>
<p class="navv2">На сайте {{ project.created|naturaltime }}</p> <p class="navv2">На сайте {{ project.created|naturaltime }}</p>

@ -1,7 +1,7 @@
import json import json
from abc import ABC
from pprint import pformat from pprint import pformat
import natsort
import pydash as _ import pydash as _
from django.conf import settings from django.conf import settings
from django.contrib import messages from django.contrib import messages
@ -10,7 +10,7 @@ from django.core.exceptions import PermissionDenied
from django.core.files.base import ContentFile from django.core.files.base import ContentFile
from django.core.paginator import Paginator, EmptyPage, PageNotAnInteger from django.core.paginator import Paginator, EmptyPage, PageNotAnInteger
from django.core.urlresolvers import reverse, reverse_lazy from django.core.urlresolvers import reverse, reverse_lazy
from django.db.models import Q from django.db.models import Q, Count, Sum
from django.http import HttpResponseForbidden, JsonResponse, HttpResponseRedirect, HttpResponse, Http404 from django.http import HttpResponseForbidden, JsonResponse, HttpResponseRedirect, HttpResponse, 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 DetailView, CreateView, DeleteView, View, UpdateView, TemplateView from django.views.generic import DetailView, CreateView, DeleteView, View, UpdateView, TemplateView
@ -53,8 +53,6 @@ from .forms import (
PortfolioForm, PortfolioForm,
ProjectAnswerForm, ProjectAnswerForm,
ProjectAnswerMessageForm, ProjectAnswerMessageForm,
ProjectFilterForm,
ProjectFilterRealtyForm,
ProjectWorkTypeSuggestionForm, ProjectWorkTypeSuggestionForm,
RealtyForm, RealtyForm,
RealtyFormNew RealtyFormNew
@ -405,86 +403,20 @@ class ProjectFilterView(BaseMixin, View):
return render(request, 'partials/inc-projects-results.html', self.get_context(request.POST)) return render(request, 'partials/inc-projects-results.html', self.get_context(request.POST))
# class CustomerProjectCreateView(BaseMixin, View): class SortRealtyBy(View):
# form_class = CustomerProjectEditForm
# realty_form = RealtyForm def get_context(self):
# work_type_suggestion_form = ProjectWorkTypeSuggestionForm print("request.POST = ", self.request.POST)
# template_name = 'customer_project_create.html' user_id = self.request.POST.get('user_id')
# sort_by = self.request.POST.get('sortBy')
# def dispatch(self, request, *args, **kwargs): state = self.request.POST.get('state')
# if request.user.is_authenticated() and request.user.is_customer(): objects = Realty.objects.filter(user__id=user_id, state=state, is_virtual=False)
# return super().dispatch(request, *args, **kwargs) if sort_by == 'num_orders':
# else: objects = objects.annotate(num_orders=Count('projects'))
# raise PermissionDenied return {"objects": objects.order_by('{}'.format(sort_by))}
#
# def get(self, request, *args, **kwargs): def post(self, *args, **kwargs):
# context = self.get_context_data(**_.merge({}, request.GET, kwargs)) return render(self.request, 'partials/inc-objects.html', self.get_context())
#
# form = self.form_class(request=request)
# realty_form = self.realty_form(request=request, prefix='realty_form')
# work_type_suggestion_form = self.work_type_suggestion_form(request=request, prefix='work_type_suggestion')
#
# context.update({
# 'form': form,
# 'realty_form': realty_form,
# 'work_type_suggestion_form': work_type_suggestion_form,
# })
#
# return render(request, self.template_name, context)
#
# def post(self, request, *args, **kwargs):
# form = self.form_class(request.POST,
# request=request) # Passing `request.FILES` seems unnecessary here. Files are added manually below
#
# form.is_valid()
# realty = form.cleaned_data.get('realty')
#
# if realty:
# realty_form = self.realty_form(request.POST, instance=realty, request=request, prefix='realty_form')
# else:
# realty_form = self.realty_form(request.POST, request=request, prefix='realty_form')
#
# if form.is_valid() and realty_form.is_valid():
# project = form.save(commit=False)
# project.customer = request.user
# project.save()
# form.save_m2m()
#
# Order.objects.create(project=project, secure=project.deal_type == 'secure_deal')
#
# for file in request.FILES.getlist('new_files'):
# ProjectFile.objects.create(file=file, project=project)
#
# if realty:
# realty_form.save()
# else:
# realty = realty_form.save(commit=False)
# realty.user = request.user
# realty.save()
# realty_form.save_m2m()
#
# project.realty = realty # Connect a realty with a project
# project.save()
#
# messages.info(request, 'Проект успешно создан')
# redirect_to = reverse('projects:detail', kwargs={'pk': project.pk})
# return redirect(redirect_to)
# else:
# if form.errors:
# messages.info(request, (
# '<p>Произошла ошибка (form)</p>'
# '<pre>{form}</pre>'
# ).format(form=pformat(form.errors)))
#
# if realty_form and realty_form.errors:
# messages.info(request, (
# '<p>Произошла ошибка (realty_form)</p>'
# '<pre>{realty_form}</pre>'
# ).format(realty_form=pformat(realty_form.errors)))
#
# context = self.get_context_data(**kwargs)
# context.update({'form': form, 'realty_form': realty_form})
# return render(request, self.template_name, context)
class CustomerProjectCreateView(BaseMixin, View): class CustomerProjectCreateView(BaseMixin, View):
@ -493,12 +425,6 @@ class CustomerProjectCreateView(BaseMixin, View):
work_type_suggestion_form = ProjectWorkTypeSuggestionForm work_type_suggestion_form = ProjectWorkTypeSuggestionForm
template_name = 'customer_project_create.html' template_name = 'customer_project_create.html'
# def dispatch(self, request, *args, **kwargs):
# if request.user.is_authenticated() and request.user.is_customer():
# return super().dispatch(request, *args, **kwargs)
# else:
# raise PermissionDenied
def get_context_data(self, **kwargs): def get_context_data(self, **kwargs):
ctx = super().get_context_data() ctx = super().get_context_data()
# ctx['hide_user_type'] = False # ctx['hide_user_type'] = False
@ -745,6 +671,68 @@ class CustomerProjectTrashView(View):
return redirect(redirect_to) return redirect(redirect_to)
class AbcCustomerRealityChangeState(ABC, View):
new_state = ''
message_part = ''
def __init__(self, **kwargs):
if self.new_state not in [el[0] for el in Realty.STATES]:
raise AttributeError('new_state must be in {}'.format([el[0] for el in Realty.STATES]))
super().__init__(**kwargs)
# TODO: dispatch вынести в ABC класс
# def dispatch(self, request, *args, **kwargs):
def post(self, request, *args, **kwargs):
realty = get_object_or_404(Realty, pk=kwargs.get("pk"))
realty.state = self.new_state
realty.save()
realty.projects.all().update(state=self.new_state)
messages.info(request, 'Объект и все, связанные с ним проекты, {}'.format(self.message_part))
redirect_to = request.POST.get('next')
return redirect(redirect_to)
class CustomerRealtyTrashView(AbcCustomerRealityChangeState):
new_state = 'trashed'
message_part = 'перемещёны в корзину'
def dispatch(self, request, *args, **kwargs):
if request.user.is_authenticated() and request.user.is_customer():
num_project_in_process = Project.objects.filter(realty__id=kwargs.get('pk')).filter(order__status="process").count()
if num_project_in_process:
raise PermissionDenied('Один или более Заказ, данного Объекта, уже находятся в работе. '
'Вы не можете переместить его в корзину.')
else:
return super().dispatch(request, *args, **kwargs)
raise PermissionDenied
class CustomerRealtyDeleteView(AbcCustomerRealityChangeState):
new_state = 'deleted'
message_part = 'удалены'
def dispatch(self, request, *args, **kwargs):
if request.user.is_authenticated() and request.user.is_customer():
return super().dispatch(request, *args, **kwargs)
else:
raise PermissionDenied
class CustomerRealtyRestoreView(AbcCustomerRealityChangeState):
new_state = 'active'
message_part = 'восстановлены'
def dispatch(self, request, *args, **kwargs):
if request.user.is_authenticated() and request.user.is_customer():
return super().dispatch(request, *args, **kwargs)
else:
raise PermissionDenied
class CustomerProjectRestoreView(View): class CustomerProjectRestoreView(View):
form_class = CustomerProjectRestoreForm form_class = CustomerProjectRestoreForm

@ -14,6 +14,17 @@ class Specialization(MPTTModel):
def __str__(self): def __str__(self):
return self.name return self.name
def full_path(self):
part = self
path = part.name
while True:
if part.parent.name != '_root':
# print(part.name)
part = part.parent
path = '{} / {}'.format(part.name, path)
else:
return path
class Meta: class Meta:
get_latest_by = 'order' get_latest_by = 'order'
ordering = ['order'] ordering = ['order']

@ -24,7 +24,7 @@
<div class="infoBlock customer"> <div class="infoBlock customer">
{% if request.user.is_authenticated and request.user.is_customer %} {% if request.user.is_authenticated and request.user.is_customer %}
<a class="to-profile" <a class="to-profile"
href="{% url 'users:customer-profile-open-projects' pk=request.user.pk %}">Я заказчик</a> href="{% url 'users:customer-profile' pk=request.user.pk %}">Я заказчик</a>
{% else %} {% else %}
<a class="to-profile" href="{% url 'registration_register' %}?type=customer">Я заказчик</a> <a class="to-profile" href="{% url 'registration_register' %}?type=customer">Я заказчик</a>
{% endif %} {% endif %}
@ -133,7 +133,7 @@
</div> </div>
</div> </div>
</div> </div>
<div style="background-color: #F7F7F7;"> <div class="footer-wrapper">
<div class="container"> <div class="container">
{% include 'partials/footer.html' %} {% include 'partials/footer.html' %}
</div> </div>

@ -0,0 +1,162 @@
<!DOCTYPE html>
{% load staticfiles %}
{% load sass_tags %}
{#{% load compress %}#}
<html lang="ru">
<head>
<meta charset="UTF-8">
<meta http-equiv='X-UA-Compatible' content='IE=edge, chrome=1'>
<meta name='viewport' content='width=device-width, initial-scale=1'>
<!--<meta name='viewport' content='initial-scale=1.0, user-scalable=no, maximum-scale=1'>-->
{% block head %}{% endblock %}
<title>PROEKTON</title>
{% block common_css %}
<link rel='stylesheet' href='{% static "css/bootstrap.css" %}'>
<link rel='stylesheet' href='{% static "css/font-awesome.min.css" %}'>
<link rel="stylesheet" href='{% static "lib/jquery-jgrowl/jquery.jgrowl.min.css" %}'>
<link rel='stylesheet' href='{% static "lib/jquery-ui/jquery-ui.css" %}'>
<link rel='stylesheet' href='{% sass_src "sass/main.sass" %}'>
{% if TEMPLATE_DEBUG %}
<link rel='stylesheet' href='{% static "css/dev-colors.css" %}'> <!-- Dev-time only, temporary!!! -->
{% endif %}
{% endblock %}
{% block personal_css %}
{% endblock %}
<link rel="icon" href="{% static 'img/favicon.jpg' %}" type="image/x-icon">
<link rel="shortcut icon" href="{% static 'img/favicon50.jpg' %}" type="image/x-icon">
<link rel="apple-touch-icon" href="{% static 'img/favicon128.jpg' %}" sizes="128x128">
<link rel="icon" type="image/png" href="{% static 'img/favicon50.jpg' %}" sizes="32x32">
<link rel="icon" type="image/png" href="{% static 'img/favicon18.jpg' %}" sizes="16x16">
{# {% endcompress %}#}
<meta name="keywords" content="">
<meta name="description" content="_TEXT_">
<meta name="yandex-verification" content="58d23691715ef942">
<link rel="canonical" href="_URL_">
</head>
<body>
{% if TEMPLATE_DEBUG %}
{% if messages %}
{% for message in messages %}
<div class="c"
style="position: relative; padding: 10px; margin-bottom: 6px; z-index: 100">{{ message|safe }}</div>
{% endfor %}
{% endif %}
{% endif %}
{% block header %}
{% include 'partials/header.html' %}
{% endblock %}
{% block content %}
<div style="min-height: 400px">
BASE TEMPLATE
</div>
{% endblock %}
{% block footer %}
<div class="container footer-border">
{% include 'partials/footer.html' %}
</div>
{% endblock %}
{% block common_js %}
<script src='{% static "js/jquery-2.2.3.min.js" %}'></script>
<script src='{% static "lib/jquery.cookie/jquery.cookie.min.js" %}'></script>
<script src='{% static "js/bootstrap.min.js" %}'></script>
{% endblock %}
{% block personal_js %}
{% endblock %}
{#{% compress js %}#}
{# <script src='{% static "js/jquery-2.2.3.min.js" %}'></script>#}
{# <script src='{% static "lib/jquery-ui/jquery-ui.js" %}'></script>#}
{# <script src='{% static "lib/jquery-ui/i18n/datepicker-ru.js" %}'></script> <!-- jQueryUI Datepicker i18n -->#}
{# <script src='{% static "js/bootstrap.min.js" %}'></script>#}
{# <script src='{% static "lib/bootstrap-select/js/bootstrap-select.js" %}'></script>#}
{# <script src='{% static "lib/select2/select2.js" %}'></script>#}
{# <script src='{% static "lib/urijs/URI.min.js" %}'></script>#}
{# <script src='{% static "js/jquery.magnific-popup.min.js" %}'></script>#}
{# <script src='{% static "my-libs.js" %}'></script>#}
{% block websocket_js %}
<script src='{% static "lib/jquery-jgrowl/jquery.jgrowl.min.js" %}'></script>
<script>
function getOpenOrdersList() {
$.ajax({
url: '/api/orders?status=created',
type: 'get',
success: function (data) {
$.each(data.results, function (key, value) {
open_order_list.push(parseInt(value.id))
})
}
})
}
function message_count_plus(selector) {
var all_messages = $(selector);
var count = parseInt(all_messages.html()) + 1;
if (count > 99) count = '99+';
all_messages.html(count);
}
var SocketHandlerMain = function (userId) {
var domain = '{{ request.META.HTTP_HOST }}';
var port = '{{ request.META.SERVER_PORT }}';
var queryString = '{{ request.get_full_path }}';
if ((queryString.indexOf('/chat') != 0) && (queryString.indexOf('/users/contractor-office/work-projects') != 0)) {
domain = domain.replace(':' + port, ':8888');
if (window.location.protocol == 'https:') {
var ws = "wss://";
} else {
var ws = "ws://";
}
var url = ws + domain + '/chat/' + userId + '/';
var sock = new WebSocket(url);
var intervalId;
sock.onopen = function () {
intervalId = setInterval(function () {
sock.send('{"dummy": 1}');
}, 15000);
};
sock.onmessage = function (event) {
var notificationData = JSON.parse(event.data);
if (open_order_list.indexOf(parseInt(notificationData.order_id)) != -1) {
{# console.log("in");#}
message_count_plus('#my_office');
}
message_count_plus('.js-all-messages');
var outMessage = "";
if (notificationData.answer_type == 'add_message_contact') {
outMessage += "<a href='/chat/?user_id=" + notificationData.sender_id + "'>" + notificationData.msg + "<a>";
} else if ((notificationData.answer_type == 'approve_stages') || (notificationData.answer_type == 'add_message_order')) {
outMessage += "<a href='/chat/#order" + notificationData.order_id + "'>" + notificationData.msg + "<a>";
}
console.log("Вам пришло новое сообщение!<br />" + outMessage);
$.jGrowl("Вам пришло новое сообщение!<br />" + outMessage, {life: 15000});
};
this.add_message = function (messageData) {
sock.send(JSON.stringify(messageData));
};
}
};
var userId = '{{ request.user.pk }}';
if (userId) {
var socketMain = new SocketHandlerMain(userId);
var open_order_list = [];
getOpenOrdersList();
}
</script>
{% endblock %}
{#{% endcompress %}#}
</body>
</html>

@ -136,7 +136,7 @@
var queryString = '{{ request.get_full_path }}'; var queryString = '{{ request.get_full_path }}';
if ((queryString.indexOf('/chat') != 0) && (queryString.indexOf('/users/contractor-office/work-projects') != 0)) { if ((queryString.indexOf('/chat') != 0) && (queryString.indexOf('/users/contractor-office/work-projects') != 0)) {
domain = domain.replace(':' + port, ''); domain = domain.replace(':' + port, ':8888');
if (window.location.protocol == 'https:') { if (window.location.protocol == 'https:') {
var ws = "wss://"; var ws = "wss://";
} else { } else {

@ -8,7 +8,7 @@
{% if request.user.is_contractor %} {% if request.user.is_contractor %}
{% url 'users:contractor-profile' pk=request.user.pk as profile_url %} {% url 'users:contractor-profile' pk=request.user.pk as profile_url %}
{% elif request.user.is_customer %} {% elif request.user.is_customer %}
{% url 'users:customer-profile-open-projects' pk=request.user.pk as profile_url %} {% url 'users:customer-profile' pk=request.user.pk as profile_url %}
{% endif %} {% endif %}
<link rel='stylesheet' href='{% sass_src "partials/sass/header.sass" %}'> <link rel='stylesheet' href='{% sass_src "partials/sass/header.sass" %}'>

@ -12,32 +12,22 @@ footer
padding: 0 padding: 0
.logoF .logoF
width: 183px width: 183px
height: 36px height: 36px
background: url('#{$static}/img/logoF.png') no-repeat center background: url('#{$static}/img/logoF.png') no-repeat center
background-size: cover background-size: cover
float: left float: left
margin: 41px 0 0 27px margin: 41px 0 0 27px
cursor: pointer cursor: pointer
.linksSoc .linksSoc
width: 100% width: 100%
float: left float: left
margin: 32px 0 0 0 margin: 32px 0 0 0
padding: 0 0 0 23px padding: 0 0 0 23px
> >
a a
width: 46px
height: 46px
opacity: 0.2
display: block
float: left
margin-right: 10px
-webkit-transition: opacity 0.4s ease-out
-moz-transition: opacity 0.4s ease-out
transition: opacity 0.4s ease-out
&:link, &:visited
width: 46px width: 46px
height: 46px height: 46px
opacity: 0.2 opacity: 0.2
@ -47,51 +37,61 @@ footer
-webkit-transition: opacity 0.4s ease-out -webkit-transition: opacity 0.4s ease-out
-moz-transition: opacity 0.4s ease-out -moz-transition: opacity 0.4s ease-out
transition: opacity 0.4s ease-out transition: opacity 0.4s ease-out
.icon_ls1 &:link, &:visited
background: url('#{$static}/img/socSprite.png') no-repeat 0 0 width: 46px
.icon_ls2 height: 46px
background: url('#{$static}/img/socSprite.png') no-repeat -46px 0 opacity: 0.2
.icon_ls3 display: block
background: url('#{$static}/img/socSprite.png') no-repeat -92px 0 float: left
.icon_ls4 margin-right: 10px
background: url('#{$static}/img/socSprite.png') no-repeat -138px 0 -webkit-transition: opacity 0.4s ease-out
.icon_ls5 -moz-transition: opacity 0.4s ease-out
background: url('#{$static}/img/socSprite.png') no-repeat -184px 0 transition: opacity 0.4s ease-out
margin-right: 0 .icon_ls1
a:hover background: url('#{$static}/img/socSprite.png') no-repeat 0 0
opacity: 1 .icon_ls2
background: url('#{$static}/img/socSprite.png') no-repeat -46px 0
.icon_ls3
background: url('#{$static}/img/socSprite.png') no-repeat -92px 0
.icon_ls4
background: url('#{$static}/img/socSprite.png') no-repeat -138px 0
.icon_ls5
background: url('#{$static}/img/socSprite.png') no-repeat -184px 0
margin-right: 0
a:hover
opacity: 1
.copy-rights .copy-rights
float: left float: left
font-size: 16px
font-family: 'pfdintextcomppro-regular', sans-serif
text-transform: uppercase
letter-spacing: 2px
margin: 34px 0 42px 31px
color: #aaa
.listF1
p
font-family: Arial, Verdana, Helvetica, sans-serif
font-size: 16px font-size: 16px
font-family: 'pfdintextcomppro-regular', sans-serif
text-transform: uppercase text-transform: uppercase
color: #2c2c2c letter-spacing: 2px
font-weight: bold margin: 34px 0 42px 31px
margin: 46px 0 20px 0 color: #aaa
ul li
margin-bottom: 6px .listF1
list-style: none p
color: red font-family: Arial, Verdana, Helvetica, sans-serif
&:last-child font-size: 16px
margin-bottom: 0 text-transform: uppercase
a color: #2c2c2c
font-family: 'Arial-MT-Regular', sans-serif font-weight: bold
color: #6c6c6c margin: 46px 0 20px 0
font-size: 15px ul li
&:link, &:visited margin-bottom: 6px
list-style: none
color: red
&:last-child
margin-bottom: 0
a
font-family: 'Arial-MT-Regular', sans-serif font-family: 'Arial-MT-Regular', sans-serif
color: #6c6c6c color: #6c6c6c
font-size: 15px font-size: 15px
&:hover &:link, &:visited
text-decoration: none font-family: 'Arial-MT-Regular', sans-serif
color: #383838 color: #6c6c6c
font-size: 15px
&:hover
text-decoration: none
color: #383838

@ -322,6 +322,19 @@ class ContractorFilterForm(forms.Form):
super().__init__(*args, **kwargs) super().__init__(*args, **kwargs)
class CustomerProfileForm(forms.ModelForm):
class Meta:
model = User
fields = (
'username',
'first_name',
'created',
'avatar',
'rating'
)
class CustomerProfileProjectRealtyForm(forms.Form): class CustomerProfileProjectRealtyForm(forms.Form):
def __init__(self, *args, **kwargs): def __init__(self, *args, **kwargs):
self.request = kwargs.pop('request') self.request = kwargs.pop('request')

@ -167,6 +167,17 @@ class User(AbstractBaseUser, PermissionsMixin):
elif self.location.level == 1: elif self.location.level == 1:
return self.location.name return self.location.name
def country(self):
try:
return self.location.parent.parent.name
except AttributeError:
return 'None'
def city(self):
try:
return self.location.name
except AttributeError:
return 'None'
# @property # @property
# def is_staff(self): # def is_staff(self):
# return self.is_superuser # return self.is_superuser

@ -9,6 +9,7 @@
} }
.avatar { .avatar {
background-color: #F1F1F1;
width: 228px; width: 228px;
height: 228px; height: 228px;
padding: 10px; padding: 10px;

@ -0,0 +1,178 @@
@import "base/variavles"
@import "modules/mods"
//.avatarInset
// //width: 100%
// height: 224px
// img
// width: 100%
// height: 100%
// //padding: 10%
// background-color: #e4e4e4
.count
display: inline-block
width: 32px
height: 32px
border-radius: 100%
text-align: center
line-height: 32px
font-family: 'Arial-MT-Regular', sans-serif
overflow: hidden
color: black
background-color: #ccc
margin-left: 10px
.projects_count
display: inline-block
color: red
margin: 0 15px
.object
.object-header
font-size: 24px
color: #545151
font-weight: bold
a
color: #575454
a:hover
text-decoration: none
color: #000
.user_name
color: #131212
font-size: 16pt
line-height: 100%
.border.add_line:before
content: ''
position: relative
display: block
width: 100px
height: 3px
background-color: black
left: 62px
top: 0
//z-index: 1
//-webkit-transition: all 0.3s ease-out
//-moz-transition: all 0.3s ease-out
//transition: all 0.3s ease-out
.nav-tabs a
color: #0b0b0b
table.ratings
font-size: 14pt
td
padding: 10px
.positive
color: #0b0b0b
.neutral
color: grey
.negative
color: red
table.projects
width: 100%
td
padding: 5px
tr:nth-child(2n)
background-color: #E8E8E8
.cut
display: inline-block
text-overflow: ellipsis
max-width: 550px
overflow: hidden
word-wrap: break-word
white-space: nowrap
%icons
margin-left: 24px
display: flex
align-items: center
&:before
content: ''
display: inline-block
width: 20px
height: 20px
background-size: cover
position: relative
left: -5px
.icon-rating
@extend %icons
&:before
background: url('#{$static}/img/rett.png') no-repeat 0 0
.icon-deals
@extend %icons
&:before
width: 25px
height: 25px
background: url('#{$static}/img/rett.png') no-repeat 0 -19px
.icon-reviews
@extend %icons
&:before
width: 26px
height: 26px
background: url('#{$static}/img/rett.png') no-repeat 0 -44px
.icon-protect
@extend %icons
&:before
width: 26px
height: 26px
background: url('#{$static}/img/cenaList.png') no-repeat 0 0
.icon-trash-red
@extend %icons
&:before
width: 21px
height: 21px
background: url('#{$static}/img/cenaList3.png') no-repeat 0 0
.icon-trash-gray
@extend %icons
&:before
width: 21px
height: 21px
background: url('#{$static}/img/cenaList3.png') no-repeat 0 0
.icon-calendar
@extend %icons
&:before
width: 19px
height: 19px
background: url('#{$static}/img/listPro.png') no-repeat 0 0
.icon-eye
@extend %icons
&:before
width: 26px
height: 18px
background:
image: url('#{$static}/img/icons/icon_eye.png')
repeat: no-repeat
size: 26px 18px
.icon-speach-ball_gray
@extend %icons
&:before
width: 18px
height: 18px
background:
image: url('#{$static}/img/icons/icon_speach-ball_gray.png')
repeat: no-repeat
size: 18px 18px
.icon-certificate
@extend %icons
&:before
width: 18px
height: 18px
background:
image: url('#{$static}/img/icons/icon_сertificate-512.png')
repeat: no-repeat
size: 18px 18px

@ -0,0 +1,42 @@
{% extends 'partials/_base.html' %}
{% load staticfiles %}
{% load sass_tags %}
{% block personal_css %}
<link rel='stylesheet' href='{% sass_src "sass/customer-profile.sass" %}'>
<link rel='stylesheet' href='{% sass_src "sass/old_main.sass" %}'>
<link rel='stylesheet' href='{% sass_src "sass/components/custom-components.sass" %}'>
{# <link rel='stylesheet' href='{% static "css/main.css" %}'>#}
{% endblock %}
{% block content %}
<div class="container main-scope">
<div class="row main-content">
<div class="col-lg-12">
{% include 'partials/inc-customer_profile-info.html' %}
<div class="row">
<div class="col-lg-12">
<div class="tab-content">
<div id="objects" class="tab-pane fade in active">
{% include 'partials/tabs/tab-objects.html' %}
</div>
<div id="open_projects" class="tab-pane fade">
{% include 'partials/tabs/tab-open_projects.html' %}
</div>
<div id="in_work_projects" class="tab-pane fade">
{% include 'partials/tabs/tab-in_work_projects.html' %}
</div>
<div id="rewiews" class="tab-pane fade">
{% include 'partials/tabs/tab-rewiews.html' %}
</div>
</div>
</div>
</div>
</div>
</div>
</div>
{% endblock %}
{% block personal_js %}
<script src="{% static 'js/build/customer_profile.js' %}"></script>
{% endblock %}

@ -0,0 +1,105 @@
{% load thumbnail %}
{% load staticfiles %}
{% load specializtions_tags %}
{% load user_tags %}
<div class="row">
<div class="col-lg-3">
<div class="avatar new-mar">
<div class="avatarInset">
{% if customer.avatar %}
{% thumbnail customer.avatar "235x224" 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>
<div class="col-lg-9">
<div class="row mod-row-eq-height" style="padding-bottom: 40px">
<div class="col-lg-5">
<span class="user_name">{{ customer.get_full_name }} <br>[{{ customer.username }}]</span>
<table style="margin-top: 10px; margin-bottom: 10px">
<tr>
<td style="min-width: 100px">На сайте:</td>
<td>{{ customer.created }}</td>
</tr>
<tr>
<td>Страна:</td>
<td>{{ customer.country }}</td>
</tr>
<tr>
<td>Город:</td>
<td>{{ customer.city }}</td>
</tr>
</table>
{% if request.user == customer %}
<a href="{% url 'users:user-profile-edit' pk=pk %}" class="btn btn-simple mod-align-center-inline"
style="padding: px 20px; font-size: 12pt">
<span type="submit" class="icon-edit"> </span> редактировать профиль
</a>
{% endif %}
</div>
<div class="col-lg-7" style="border-bottom: 1px solid gainsboro; border-top: 1px solid gainsboro">
<table class="ratings" style="float: right">
<tr>
<td>
<div class="icon-rating">Рейтинг:</div>
</td>
<td>
<span> {{ ratings }}</span>
</td>
</tr>
<tr>
<td>
<div class="icon-deals">Безопасные сделки:</div>
</td>
<td>
<span> {{ deals }}</span>
</td>
</tr>
<tr>
<td>
<div class="icon-reviews">Отзывы:</div>
</td>
<td>
<span class="positive"> {{ reviews_p }}</span>
<span class="neutral"> {{ reviews_n }}</span>
<span class="negative"> {{ reviews_m }}</span>
</td>
</tr>
</table>
</div>
</div>
<div class="row">
<div class="col-lg-12">
<div class="profileTabs2 tabs-new">
<ul class="nav nav-tabs nav-justified">
<li class="active">
<a data-toggle="tab" href="#objects">
<div class="mod-align-center-inline"> Объекты <span class="count">{{ objects.count }}</span></div>
</a>
</li>
<li>
<a data-toggle="tab" href="#open_projects">
<div class="mod-align-center-inline"> Открытые заказы <span class="count">{{ open_projects.count }}</span></div>
</a>
</li>
<li>
<a data-toggle="tab" href="#in_work_projects">
<div class="mod-align-center-inline"> Заказы в работе <span class="count">{{ projects_in_work.count }}</span></div>
</a>
</li>
<li>
<a data-toggle="tab" href="#rewiews">
<div class="mod-align-center-inline"> Отзывы <span class="count">{{ reviews.count }}</span></div>
</a>
</li>
</ul>
</div>
</div>
</div>
</div>
</div>

@ -0,0 +1,114 @@
{% for object in objects %}
<div class="row object">
<div class="separator">
<div class="border add_line"></div>
</div>
<div style="margin-bottom: 15px" class="row">
<div class="col-lg-9">
<div class="object-header">{{ object.name }}</div>
</div>
{% if request.user == customer %}
<div class="col-lg-3">
{% if trash %}
<form action="{% url 'customer-object-restore' pk=object.pk %}" method="POST">
{% csrf_token %}
<input type="hidden" name="next" value="{{ request.path }}">
<a href='#' onclick="$(this).closest('form').submit(); return false">
<span class="icon-protect">Восстановить</span>
</a>
</form>
{% else %}
<span class="icon-protect">Редактировать</span>
{% endif %}
</div>
{% endif %}
</div>
<div class="row mod-align-center">
<div class="col-lg-9">
Заказы: <span class="projects_count"> {{ object.projects.count }}</span>
<button class="bnt btn-default btn-up_down -small" type="submit"
value="num_orders"
onclick="toggler(this, 'obj-{{ object.id }}')">
<span class="text">Посмотреть</span>
</button>
{% if request.user == customer %}
<a href="{% url 'projects:customer-project-create' %}"
class="btn btn-simple -small">
Добавить заказ
</a>
{% endif %}
</div>
<div class="col-lg-3">
{% if request.user == customer %}
{% if trash %}
<form action="{% url 'customer-object-delete' pk=object.pk %}" method="POST">
{% csrf_token %}
<input type="hidden" name="next" value="{{ request.path }}">
<a href='#' onclick="$(this).closest('form').submit(); return false">
<span class="icon-trash-red">Удалить навсегда</span>
</a>
</form>
{% else %}
<form action="{% url 'customer-object-trash' pk=object.pk %}"
method="POST" novalidate>
{% csrf_token %}
<input type="hidden" name="next"
value="{{ request.path }}">
<a href="#"
onclick="$(this).closest('form').submit(); return false">
<span class="icon-trash-red">Переместить в корзину</span>
</a>
</form>
{% endif %}
{% endif %}
</div>
</div>
<div class="row" id="obj-{{ object.id }}" style="display: none">
<div class="col-lg-12">
<div class="separator">
<div class="border"></div>
</div>
<table class="projects">
{% for project in object.projects.all %}
<tr>
<td><strong>{{ forloop.counter }}</strong></td>
<td>{{ project.name }}</td>
<td>
<span class="icon-calendar">{{ project.created }}</span>
</td>
<td>
<span class="icon-eye">{{ project.hit_count.hits }}</span>
</td>
<td>
<span class="icon-speach-ball_gray">{{ project.message_count }}</span>
</td>
{# <td>{{ project.answers.count }}</td>#}
<td>
<span class="icon-certificate">
<span class="cut">{{ project.specialization.full_path }}</span>
</span>
</td>
</tr>
{% endfor %}
</table>
</div>
</div>
</div>
<span style="margin: 10px 0" class="icon-calendar">
{{ object.created }}
</span>
{% endfor %}
<div class="row">
<div class="separator">
<div class="border"></div>
</div>
</div>

@ -0,0 +1,99 @@
{% load project_tags %}
<div class="projectsBlock new-pro-block disTab">
{% for proj in open_projects %}
<div class="projectPro clearfix">
<div class="col-lg-9 leftPro">
<p class="titlePro">
<a href="{% url 'projects:detail' proj.pk %}">{{ proj.name }}</a>
</p>
<ul class="desPro">
<li>Объект "{{ proj.realty.name }}"</li>
<li><span>{{ proj.get_team_answers|length }}</span> ответ от имени
группы
</li>
</ul>
{% if request.user == customer %}
<ul class="color-menu">
<li>
<a href="{% url 'projects:detail' proj.pk %}#new-answers">Новые: {{ proj|get_new_answers|length }}</a>
</li>
<li>
<a href="{% url 'projects:detail' proj.pk %}#candidate-answers">Кандидаты: {{ proj|get_candidate_answers|length }}</a>
</li>
<li>
<a href="{% url 'projects:detail' proj.pk %}#rejected-answers">Отказал: {{ proj|get_rejected_answers|length }}</a>
</li>
</ul>
{% endif %}
<p class="textPro">
{{ proj.text }}
</p>
<ul class="listPro">
<li>{{ proj.created }}</li>
<li>{{ proj.hit_count.hits }}</li>
<li>{{ proj.answers.count }}</li>
<li>{{ customer.get_full_name }}</li>
</ul>
</div>
<div class="col-lg-3 rightPro right-pro-red">
<p class="cenaPro">
{{ proj.budget }} <i
class="{% fa_currency_classes proj.currency %}"></i>
</p>
{% if request.user == proj.customer %}
{% if trash %}
<ul>
<li>
<form action="{% url 'projects:customer-project-restore' pk=proj.pk %}" method="POST">
{% csrf_token %}
<input type="hidden" name="next" value="{{ request.path }}">
<a href='#' onclick="$(this).closest('form').submit(); return false">Восстановить из
корзины</a>
</form>
</li>
<li>
<form action="{% url 'projects:customer-project-delete' pk=proj.pk %}" method="POST">
{% csrf_token %}
<input type="hidden" name="next" value="{{ request.path }}">
<a href='#' onclick="$(this).closest('form').submit(); return false">Удалить
навсегда</a>
</form>
</li>
</ul>
{% else %}
<ul>
<li>
<a href='{% url 'projects:customer-project-edit' pk=proj.pk %}?back={{ request.path }}'>Редактировать</a>
</li>
<li>
<form action="{% url 'projects:customer-project-trash' pk=proj.pk %}"
method="POST" novalidate>
{% csrf_token %}
<input type="hidden" name="next"
value="{{ request.path }}">
<a href="#"
onclick="$(this).closest('form').submit(); return false">Переместить
в корзину</a>
</form>
</li>
</ul>
{% endif %}
{% endif %}
</div>
</div>
{% endfor %}
</div>
<div class="col-lg-12 pagin">
{% include 'partials/pagination.html' %}
</div>

@ -0,0 +1,82 @@
{% load project_tags %}
<div class="old-main">
<div class="projectsBlock new-pro-block disTab">
{% for proj in projects_in_work %}
<div class="projectPro clearfix">
<div class="col-lg-9 leftPro">
<p class="titlePro">
<a href="{% url 'projects:detail' proj.pk %}">{{ proj.name }}</a>
</p>
<ul class="desPro">
<li>Объект "{{ proj.realty.name }}"</li>
<li><span>{{ proj.get_team_answers|length }}</span> ответ от имени
группы
</li>
</ul>
{% if request.user == customer %}
<ul class="color-menu">
<li>
<a href="{% url 'projects:detail' proj.pk %}#new-answers">Новые: {{ proj|get_new_answers|length }}</a>
</li>
<li>
<a href="{% url 'projects:detail' proj.pk %}#candidate-answers">Кандидаты: {{ proj|get_candidate_answers|length }}</a>
</li>
<li>
<a href="{% url 'projects:detail' proj.pk %}#rejected-answers">Отказал: {{ proj|get_rejected_answers|length }}</a>
</li>
</ul>
{% endif %}
<p class="textPro">
{{ proj.text }}
</p>
<ul class="listPro">
<li>{{ proj.created }}</li>
<li>{{ proj.hit_count.hits }}</li>
<li>{{ proj.answers.count }}</li>
<li>{{ customer.get_full_name }}</li>
</ul>
</div>
<div class="col-lg-3 rightPro right-pro-red">
<p class="cenaPro">
{{ proj.budget }} <i
class="{% fa_currency_classes proj.currency %}"></i>
</p>
{% if request.user == proj.customer %}
<div class="open-projects-div1">
<ul>
<li>
<a href='{% url 'projects:customer-project-edit' pk=proj.pk %}?back={{ request.path }}'>Редактировать</a>
</li>
<li>
<form action="{% url 'projects:customer-project-trash' pk=proj.pk %}"
method="POST" novalidate>
{% csrf_token %}
<input type="hidden" name="next"
value="{{ request.path }}">
<a href="#"
onclick="$(this).closest('form').submit(); return false">Переместить
в корзину</a>
</form>
</li>
</ul>
</div>
{% endif %}
</div>
</div>
{% endfor %}
</div>
<div class="col-lg-12 pagin">
{% include 'partials/pagination.html' %}
</div>
</div>

@ -0,0 +1,48 @@
<div class="row" style="margin: 35px 0">
{% if request.user == customer %}
<div class="col-lg-12">
<div class="btn-group btn-round">
<a data-toggle="tab" href="#_objects"
class="btn btn-default tab-inserted active">
Текущие объекты
<span>{{ objects.count }}</span>
</a>
<a data-toggle="tab" href="#trashed_objects"
class="btn btn-default tab-inserted">
Удаленные объекты
<span>{{ trashed_objects.count }}</span>
</a>
</div>
<a href="{% url 'projects:customer-project-create' %}"
style="float: right; letter-spacing: 4px; padding-left: 35px; padding-right: 35px"
class="btn btn-simple">
Добавить объект
</a>
</div>
{% endif %}
</div>
<div class="row">
<div class="col-lg-12">
<div class="link-sort">
Сортировать по:
{# name="name" #}
<button class="bnt btn-default" type="submit" onclick="sortRealtyBy({sortBy: 'name', user_id: '{{ customer.id }}', state: 'active'}, '#_objects')">
названию
</button>
<button class="bnt btn-default" type="submit" onclick="sortRealtyBy({sortBy: 'created', user_id: '{{ customer.id }}', state: 'active'}, '#_objects')">
дате создания
</button>
<button class="bnt btn-default" type="submit" onclick="sortRealtyBy({sortBy: 'num_orders', user_id: '{{ customer.id }}', state: 'active'}, '#_objects')">
количеству заказов
</button>
</div>
</div>
</div>
<div class="tab-content">
<div id="_objects" class="tab-pane fade in active">
{% include 'partials/inc-objects.html' with objects=objects %}
</div>
<div id="trashed_objects" class="tab-pane fade">
{% include 'partials/inc-objects.html' with objects=trashed_objects trash=1 %}
</div>
</div>

@ -0,0 +1,39 @@
<div class="old-main">
{% if request.user == customer %}
<div class="row" style="margin: 35px 0;">
<div class="col-lg-12">
<div class="btn-group btn-round">
<a data-toggle="tab" href="#_projects"
class="btn btn-default tab-inserted active">
Текущие объекты
<span>{{ open_projects.count }}</span>
</a>
{% if request.user == customer %}
<a data-toggle="tab" href="#trashed_projects"
class="btn btn-default tab-inserted">
Удаленные объекты
<span>{{ trashed_projects.count }}</span>
</a>
{% endif %}
</div>
{# <div style="display: inline-block;">#}
{# Filter be here#}
{# </div>#}
<a href="{% url 'projects:customer-project-create' %}"
style="float: right; letter-spacing: 4px; padding-left: 35px; padding-right: 35px"
class="btn btn-simple">
Разместить заказ
</a>
</div>
</div>
{% endif %}
<div class="tab-content">
<div id="_projects" class="tab-pane fade in active">
{% include 'partials/inc-projects.html' with open_projects=open_projects %}
</div>
<div id="trashed_projects" class="tab-pane fade">
{% include 'partials/inc-projects.html' with open_projects=trashed_projects trash=1 %}
</div>
</div>
</div>

@ -0,0 +1,29 @@
<div class="old-main">
{% for review in reviews %}
<div class="new-comm-44">
<div class="col-lg-12">
<p class="nameComm">
<a href="#">{{ review.from_contractor.get_full_name }}</a>
</p>
<span class="dateComm44">
{{ review.project.get_deal_type_display }}
</span>
<div class="stars box-sizing">
<a href="#">
{% if review.type == 'positive' %}
Положительный отзыв
{% elif review.type == 'negative' %}
Отрицательный отзыв
{% else %}
Нейтральный отзыв
{% endif %}
</a>
</div>
<p class="textComm44">{{ review.text }}</p>
</div>
</div>
{% endfor %}
</div>

@ -6,7 +6,7 @@
<div class="col-lg-12"> <div class="col-lg-12">
<div class="col-lg-3 divCol3"> <div class="col-lg-3 divCol3">
<div class="avatar new-mar"> <div class="avatar">
<div class="avatarInset"> <div class="avatarInset">
{% if customer.avatar %} {% if customer.avatar %}
{% thumbnail customer.avatar "235x224" crop="center" as im %} {% thumbnail customer.avatar "235x224" crop="center" as im %}
@ -18,31 +18,32 @@
</div> </div>
</div> </div>
</div> </div>
<div class="col-lg-9 divCol9"> <div class="col-lg-9 divCol9">
<div class="col-lg-4"> <div class="col-lg-4">
<p class="nameUser"> <p class="nameUser">
{{ customer.get_full_name }} [{{ customer.username }}] {{ customer.get_full_name }} [{{ customer.username }}]
</p> </p>
<p class="cityUser">{{ customer.location.name }}</p> <p class="cityUser">{{ customer.location.name }}</p>
<p class="navv">На сайте {{ customer.created }}</p> <p class="navv">На сайте {{ customer.created }}</p>
</div> </div>
<div class="col-lg-4 new-er"> <div class="col-lg-4 new-er">
{% ratings_widget customer.pk %} {% ratings_widget customer.pk %}
</div> </div>
<div class="col-lg-4"> <div class="col-lg-4">
{% if request.user.pk != customer.pk %} {% if request.user.pk != customer.pk %}
<a href="javascript:void(0)" class="new-prop new-prop1">показать контакты</a> <a href="javascript:void(0)" class="new-prop new-prop1">показать контакты</a>
<a href="{% url 'chat:chat-user' %}?user_id={{ pk }}#user{{ pk }}" class="new-prop new-prop2">написать сообщение</a> <a href="{% url 'chat:chat-user' %}?user_id={{ pk }}#user{{ pk }}" class="new-prop new-prop2">написать
сообщение</a>
{% else %} {% else %}
<a href="{% url 'users:user-profile-edit' pk=pk %}" class="new-red">редактировать профиль</a> <a href="{% url 'users:user-profile-edit' pk=pk %}" class="new-red">редактировать профиль</a>
{% endif %} {% endif %}
</div> </div>
</div> </div>
<div class="col-lg-9 divCol9 new-mar2"> <div class="col-lg-9 divCol9 new-mar2">
<div class="profileTabs2 tabs-new"> <div class="profileTabs2 tabs-new">
<ul class="nav nav-tabs nav-justified"> <ul class="nav nav-tabs nav-justified">
@ -50,25 +51,25 @@
{% url 'users:customer-profile-trashed-projects' pk=pk as a2 %} {% url 'users:customer-profile-trashed-projects' pk=pk as a2 %}
{% url 'users:customer-profile-current-projects' pk=pk as b %} {% url 'users:customer-profile-current-projects' pk=pk as b %}
{% url 'users:customer-profile-reviews' pk=pk as c %} {% url 'users:customer-profile-reviews' pk=pk as c %}
<li role="presentation" {% if request.path == a or request.path == a2 %}class="active"{% endif %}> <li role="presentation" {% if request.path == a or request.path == a2 %}class="active"{% endif %}>
<a href="{{ a }}">Открытые проекты</a> <a href="{{ a }}">Открытые проекты</a>
</li> </li>
{% if request.user == customer %} {% if request.user == customer %}
<li role="presentation" {% if request.path == b %}class="active"{% endif %}> <li role="presentation" {% if request.path == b %}class="active"{% endif %}>
<a href="{{ b }}">Текущие проекты</a> <a href="{{ b }}">Текущие проекты</a>
<div class="roundsCount"> <div class="roundsCount">
{# <div class="countR">0</div>#} {# <div class="countR">0</div>#}
<div class="countG">{{ num_current_projects }}</div> <div class="countG">{{ num_current_projects }}</div>
</div> </div>
</li> </li>
{% endif %} {% endif %}
<li role="presentation" {% if request.path == c %}class="active"{% endif %}> <li role="presentation" {% if request.path == c %}class="active"{% endif %}>
<a href="{{ c }}">Отзывы</a> <a href="{{ c }}">Отзывы</a>
<div class="roundsCount"> <div class="roundsCount">
<div class="countG">{% get_reviews_count request.user %}</div> <div class="countG">{% get_reviews_count request.user %}</div>
</div> </div>

@ -25,7 +25,7 @@
{% csrf_token %} {% csrf_token %}
{% if request.user.is_customer %} {% if request.user.is_customer %}
<input type="hidden" name="next" value="{% url 'users:customer-profile-open-projects' pk=pk %}"> <input type="hidden" name="next" value="{% url 'users:customer-profile' pk=pk %}">
{% elif request.user.is_contractor %} {% elif request.user.is_contractor %}
<input type="hidden" name="next" value="{% url 'users:contractor-profile' pk=pk %}"> <input type="hidden" name="next" value="{% url 'users:contractor-profile' pk=pk %}">
{% endif %} {% endif %}

@ -1,13 +1,11 @@
{% extends 'partials/base.html' %} {% extends 'partials/_base.html' %}
{% load staticfiles %} {% load staticfiles %}
{% load thumbnail %} {% load thumbnail %}
{% load sass_tags %} {% load sass_tags %}
{% block head_css %} {#{% block old_css %}{% endblock %}#}
{# <link rel='stylesheet' href='{% static "lib/proekton-components/css/fonts.css" %}'>#} {% block personal_css %}
{# <link rel='stylesheet' href='{% static "lib/proekton-components/css/selected-container.css" %}'>#}
{# <link rel='stylesheet' href='{% static "lib/proekton-components/css/editable-container.css" %}'>#}
{# <link rel='stylesheet' href='{% static "lib/proekton-components/css/select-box.css" %}'>#}
<link rel='stylesheet' href='{% sass_src "lib/proekton-components/sass/components.sass" %}'> <link rel='stylesheet' href='{% sass_src "lib/proekton-components/sass/components.sass" %}'>
<link rel='stylesheet' href='{% sass_src "sass/old_main.sass" %}'>
<link rel='stylesheet' href='{% static "css/project_filter.css" %}'>{# other #} <link rel='stylesheet' href='{% static "css/project_filter.css" %}'>{# other #}
<link rel='stylesheet' href='{% static "css/font-awesome.min.css" %}'> <link rel='stylesheet' href='{% static "css/font-awesome.min.css" %}'>
<link rel='stylesheet' href='{% static "css/user_profile_edit.css" %}'> <link rel='stylesheet' href='{% static "css/user_profile_edit.css" %}'>
@ -15,298 +13,308 @@
{% endblock %} {% endblock %}
{% block content %} {% block content %}
{% include 'partials/header.html' %} <div class="container main-scope">
{# {% if request.user.is_customer %}#} <div class="row main-content">
{# <input type="hidden" name="next"#} {# <div class="old-main">#}
{# value="{% url 'users:customer-profile-open-projects' pk=pk %}">#} <form method="POST" enctype="multipart/form-data" novalidate>
{# {% elif request.user.is_contractor %}#} {% csrf_token %}
{# <input type="hidden" name="next" value="{% url 'users:contractor-profile' pk=pk %}">#} {% if request.user.is_customer %}
{# {% endif %}#} <input type="hidden" name="next" value="{% url 'users:customer-profile' pk=pk %}">
{% else %}
<input type="hidden" name="next" value="{% url 'users:contractor-profile' pk=pk %}">
{% endif %}
<div class="container mainScore"> <div class="col-lg-12">
<div class="row row-eq-height">
<div class="col-lg-3 -live-image-avatar-upload-container">
<div class="avatar" style="float: none">
<div class="avatarInset -position-relative-parent">
<a href="#" onclick="return false" class="btn close -live-image-delete"
style="display: none">&times;</a>
<div class="row mainContent"> {% if request.user.avatar %}
<form method="POST" enctype="multipart/form-data" novalidate> {% thumbnail request.user.avatar "208x208" crop="center" as avatar %}
{% csrf_token %} <img src="{{ avatar.url }}" alt="profile-image" class="-avatar-image">
<input type="hidden" name="next" value="{% url 'users:contractor-profile' pk=pk %}"> {% endthumbnail %}
<div class="col-lg-12"> {% else %}
<div class="row row-eq-height"> <img src="{% static 'img/profile.jpg' %}" alt="profile-image"
<div class="col-lg-3 -live-image-avatar-upload-container"> class="-avatar-image">
<div class="avatar" style="float: none"> {% endif %}
<div class="avatarInset -position-relative-parent"> </div>
<a href="#" onclick="return false" class="btn close -live-image-delete"
style="display: none">&times;</a>
{% if request.user.avatar %}
{% thumbnail request.user.avatar "235x224" crop="center" as avatar %}
<img src="{{ avatar.url }}" alt="profile-image" class="-avatar-image">
{% endthumbnail %}
{% else %}
<img src="{% static 'img/profile.jpg' %}" alt="profile-image"
class="-avatar-image">
{% endif %}
</div> </div>
</div> <div style="margin-top: 15px">
<div style="margin-top: 15px"> <div class="upload-new">
<div class="upload-new"> {# <div class="upload2 up-l1">#}
{# <div class="upload2 up-l1">#} <input type="file" name="image" class="-live-image-upload">
<input type="file" name="image" class="-live-image-upload">
<p>Загрузить фотографию</p> <p>Загрузить фотографию</p>
{# </div>#} {# </div>#}
</div>
</div>
<div {% if not TESTING %}style="display: none"{% endif %}>
<input type="text" name="live_image" class="-live-image-id">
</div> </div>
</div> </div>
<div {% if not TESTING %}style="display: none"{% endif %}> <div class="col-lg-9">
<input type="text" name="live_image" class="-live-image-id"> <div class="row">
</div> <div class="col-lg-12">
</div> <div class="bottom-line">
<div class="col-lg-9"> {% if request.user.is_customer %}
<div class="row"> <span class="header">
<div class="col-lg-12"> Полное заполнение профиля влияет на количество откликиков исполнителей и “безопасную сделку”
<div class="bottom-line"> <i class="fa fa-question-circle-o" aria-hidden="true" title=""></i>
<span class="header"> </span>
Параметры заполнения прифоля влияют на фильтр поиска специалистов, ранжирования в списке {% else %}
<i class="fa fa-question-circle-o" aria-hidden="true" title=""></i> <span class="header">
</span> Параметры заполнения прифоля влияют на фильтр поиска специалистов, ранжирования в списке
<i class="fa fa-question-circle-o" aria-hidden="true" title=""></i>
</span>
{% endif %}
</div>
</div> </div>
</div> </div>
</div> <div class="row">
<div class="row"> <div class="col-lg-12" style="padding-bottom: 10px">
<div class="col-lg-12" style="padding-bottom: 10px">
<span class="header block-header"> <span class="header block-header">
Личная информация <i class="fa fa-question-circle-o" aria-hidden="true" Личная информация <i class="fa fa-question-circle-o" aria-hidden="true"
title=""></i> title=""></i>
</span> </span>
</div>
</div>
<div class="row">
<div class="col-lg-4">
<input value="{{ form.last_name.value }}" name="{{ form.last_name.html_name }}"
class="simple-input" placeholder="Фамилия">
</div>
<div class="col-lg-4">
<input value="{{ form.first_name.value }}" name="{{ form.first_name.html_name }}"
class="simple-input" placeholder="Имя">
</div>
<div class="col-lg-4">
<input value="{{ form.patronym.value }}" name="{{ form.patronym.html_name }}"
class="simple-input" placeholder="Отчество">
</div>
<div class="col-lg-4">
<div class="vertical-child" id="sb-location-1">
</div>
</div>
<div class="col-lg-4">
<div class="vertical-child" id="sb-location-2">
</div> </div>
</div> </div>
<div class="col-lg-4">
<div class="vertical-child" id="sb-location-3">
</div>
</div>
<div class="col-lg-8">
<div class="selected-container horizontal vertical-child no-margin"
id="selected-location">
<div class="header">&nbsp;</div>
<input type="hidden" name="location"
value="{{ form.location.value }}">
</div>
</div>
</div>
</div>
</div> <!-- top -->
<div class="row"> <div class="row">
<div style="padding-bottom: 10px" class="col-lg-12"> <div class="col-lg-4">
<div class="row"> <input value="{{ form.last_name.value }}" name="{{ form.last_name.html_name }}"
<div class="col-lg-offset-3 col-lg-9"> class="simple-input" placeholder="Фамилия">
<div class="top-line">
<span class="header block-header">
Мой опыт работы в проектировании / дизайне / сопровождении проектной документации
<i class="fa fa-question-circle-o" aria-hidden="true" title=""></i>
</span>
</div> </div>
</div> <div class="col-lg-4">
</div> <input value="{{ form.first_name.value }}"
<div class="row"> name="{{ form.first_name.html_name }}"
<div class="col-lg-12"> class="simple-input" placeholder="Имя">
<div class="" id="select-box-1">
</div> </div>
</div> <div class="col-lg-4">
</div> <input value="{{ form.patronym.value }}" name="{{ form.patronym.html_name }}"
<div class="row"> class="simple-input" placeholder="Отчество">
<div class="col-lg-3">
<div class="vertical-child" id="select-box-2">
</div> </div>
</div> <div class="col-lg-4">
<div class="col-lg-3"> <div class="vertical-child" id="sb-location-1">
<div class="vertical-child" id="select-box-3"> </div>
</div> </div>
</div> <div class="col-lg-4">
<div class="col-lg-3"> <div class="vertical-child" id="sb-location-2">
<div class="vertical-child" id="select-box-4"> </div>
</div> </div>
</div> <div class="col-lg-4">
<div class="col-lg-3"> <div class="vertical-child" id="sb-location-3">
<div class="vertical-child" id="select-box-5"> </div>
</div> </div>
</div> <div class="col-lg-8">
</div> <div class="selected-container horizontal vertical-child no-margin"
<div class="row"> id="selected-location">
<div class="col-lg-12"> <div class="header">&nbsp;</div>
<div class="selected-container horizontal" id="selected-spec"> <input type="hidden" name="location"
<input type="hidden" name="{{ form.contractor_specializations.html_name }}" value="{{ form.location.value }}">
value="{{ form.contractor_specializations.value }}"> </div>
</div> </div>
</div> </div>
</div> </div>
</div> <!-- top -->
{% if request.user.is_contractor %}
<div class="row"> <div class="row">
<div class="col-lg-3"> <div style="padding-bottom: 10px" class="col-lg-12">
<div class="vertical-child" id="sb-building-classification"> <div class="row">
</div> <div class="col-lg-offset-3 col-lg-9">
<div class="vertical-child" id="sb-building-sub-classification"> <div class="top-line">
</div> <span class="header block-header">
<div class="selected-container" id="selected-building-classification"> Мой опыт работы в проектировании / дизайне / сопровождении проектной документации
<input type="hidden" <i class="fa fa-question-circle-o" aria-hidden="true" title=""></i>
name="{{ form.contractor_building_classifications.html_name }}" </span>
value="{{ form.contractor_building_classifications.value }}"> </div>
</div>
</div> </div>
</div> <div class="row">
<div class="col-lg-3"> <div class="col-lg-12">
<div class="vertical-child" id="sb-construction-type"> <div class="" id="select-box-1">
</div>
</div>
</div> </div>
<div class="selected-container" id="selected-construction-type"> <div class="row">
<input type="hidden" name="{{ form.contractor_construction_types.html_name }}" <div class="col-lg-3">
value="{{ form.contractor_construction_types.value }}"> <div class="vertical-child" id="select-box-2">
</div>
</div>
<div class="col-lg-3">
<div class="vertical-child" id="select-box-3">
</div>
</div>
<div class="col-lg-3">
<div class="vertical-child" id="select-box-4">
</div>
</div>
<div class="col-lg-3">
<div class="vertical-child" id="select-box-5">
</div>
</div>
</div> </div>
</div> <div class="row">
<div class="col-lg-3"> <div class="col-lg-12">
<div class="select-box-header vertical-child"> <div class="selected-container horizontal" id="selected-spec">
<span style="width: 180px" class="header">Требуется допуск (СРО)</span> <input type="hidden"
<i class="fa fa-question-circle-o" aria-hidden="true" name="{{ form.contractor_specializations.html_name }}"
title="bla-bla-bla..."></i> value="{{ form.contractor_specializations.value }}">
</div>
</div>
</div> </div>
<div class="row">
<div class="col-lg-3">
<div class="vertical-child" id="sb-building-classification">
</div>
<div class="vertical-child" id="sb-building-sub-classification">
</div>
<div class="selected-container" id="selected-building-classification">
<input type="hidden"
name="{{ form.contractor_building_classifications.html_name }}"
value="{{ form.contractor_building_classifications.value }}">
</div>
</div>
<div class="col-lg-3">
<div class="vertical-child" id="sb-construction-type">
</div>
<div class="selected-container" id="selected-construction-type">
<input type="hidden"
name="{{ form.contractor_construction_types.html_name }}"
value="{{ form.contractor_construction_types.value }}">
</div>
</div>
<div class="col-lg-3">
<div class="select-box-header vertical-child">
<span style="width: 180px" class="header">Требуется допуск (СРО)</span>
<i class="fa fa-question-circle-o" aria-hidden="true"
title="bla-bla-bla..."></i>
</div>
<div class="custom-check"> <div class="custom-check">
<div class="checked"></div> <div class="checked"></div>
<div style="display: none" class="not-checked"></div> <div style="display: none" class="not-checked"></div>
<input name="{{ form.cro.html_name }}" type="checkbox" hidden <input name="{{ form.cro.html_name }}" type="checkbox" hidden
{% if form.cro.value %} checked{% endif %}> {% if form.cro.value %} checked{% endif %}>
</div> </div>
</div>
</div>
</div>
</div> <!-- center -->
<div class="row">
<div class="col-lg-12">
<div class="row">
<div class="col-lg-12">
<div class="top-line" style="padding-top: 15px">
<div class="btn-group toggle" role="group" aria-label="...">
<a style="z-index: 0" href="#"
{# <a style="z-index: 0" href="{% url 'users:user-profile-edit' pk=pk %}"#}
role="button"
class="btn btn-default active">Общая информация</a>
<a href="#"
class="btn btn-default" role="button">Финансовая информация</a>
</div> </div>
</div> </div>
</div> </div>
</div> </div> <!-- center -->
<div class="row info"> {% endif %}
<div class="col-lg-3"> <div class="row">
<div class="header"> Дата рождения</div> <div class="col-lg-12">
<div class="birth_edit_dat"> <div class="row">
{{ form.date_of_birth }} <div class="col-lg-12">
<div class="top-line" style="padding-top: 15px">
<div class="btn-group toggle" role="group" aria-label="...">
<a style="z-index: 0" href="#"
{# <a style="z-index: 0" href="{% url 'users:user-profile-edit' pk=pk %}"#}
role="button"
class="btn btn-default active">Общая информация</a>
<a href="#"
class="btn btn-default" role="button">Финансовая информация</a>
</div>
</div>
</div> </div>
</div> </div>
<div class="col-lg-3"> <div class="row info">
<div style="position: relative" class="select-box-container custom-select" <div class="col-lg-3">
id="gender"> <div class="header"> Дата рождения</div>
<div class="select-box-header"> <div class="birth_edit_dat">
<div class="header">Пол</div> {{ form.date_of_birth }}
</div> </div>
<input class="simple-select" placeholder="Выберите" </div>
value="{{ form.get_gender_display }}" readonly> <div class="col-lg-3">
<input type="hidden" name="{{ form.gender.html_name }}" value="{{ form.gender.value }}"> <div style="position: relative" class="select-box-container custom-select"
<div class="select-box-options" style="width: 100%; display: none"> id="gender">
<div style="min-width: inherit" class="box-wrapper"> <div class="select-box-header">
<ul> <div class="header">Пол</div>
{% for id, text in form.gender.field.choices %} </div>
<li data-id="{{ id }}">{{ text }}</li> <input class="simple-select" placeholder="Выберите"
{% endfor %} value="{{ form.get_gender_display }}" readonly>
</ul> <input type="hidden" name="{{ form.gender.html_name }}"
value="{{ form.gender.value }}">
<div class="select-box-options" style="width: 100%; display: none">
<div style="min-width: inherit" class="box-wrapper">
<ul>
{% for id, text in form.gender.field.choices %}
<li data-id="{{ id }}">{{ text }}</li>
{% endfor %}
</ul>
</div>
</div> </div>
</div> </div>
</div>
</div> </div>
<div class="col-lg-3"> <div class="col-lg-3">
<div style="position: relative" class="select-box-container custom-select" <div style="position: relative" class="select-box-container custom-select"
id="gender"> id="gender">
<div class="select-box-header"> <div class="select-box-header">
<div class="header">Статус</div> <div class="header">Статус</div>
</div> </div>
<input class="simple-select" placeholder="Выберите" <input class="simple-select" placeholder="Выберите"
value="{{ form.get_status_display }}" readonly> value="{{ form.get_status_display }}" readonly>
<input type="hidden" name="{{ form.contractor_status.html_name }}" value="{{ form.contractor_status.value }}"> <input type="hidden" name="{{ form.contractor_status.html_name }}"
<div class="select-box-options" style="width: 100%; display: none"> value="{{ form.contractor_status.value }}">
<div style="min-width: inherit" class="box-wrapper"> <div class="select-box-options" style="width: 100%; display: none">
<ul> <div style="min-width: inherit" class="box-wrapper">
{% for id, text in form.contractor_status.field.choices %} <ul>
<li data-id="{{ id }}">{{ text }}</li> {% for id, text in form.contractor_status.field.choices %}
{% endfor %} <li data-id="{{ id }}">{{ text }}</li>
</ul> {% endfor %}
</ul>
</div>
</div> </div>
</div> </div>
</div> </div>
<div class="col-lg-3">
<div class="header">Skype</div>
<input name="{{ form.skype.html_name }}" class="simple-input"
placeholder="skype id"
value="{{ form.skype.value }}">
</div>
<div class="clearfix visible-lg"></div>
<div class="col-lg-3 vertical-child">
<div class="header">Сайт</div>
<input name="{{ form.website.html_name }}" class="simple-input"
placeholder="example.com"
value="{{ form.website.value }}">
</div>
<div class="col-lg-3 vertical-child">
<div class="header">Телефон</div>
<input name="{{ form.phone.html_name }}" class="simple-input phone"
placeholder="+7 909 999 00 00"
value="{{ form.phone.value }}"
type="tel">
</div>
<div class="col-lg-3 vertical-child">
<div class="header">Второй телефон</div>
<input name="{{ form.phone2.html_name }}" class="simple-input phone"
placeholder="+7 909 999 00 00"
value="{{ form.phone2.value }}"
type="tel">
</div>
<div class="col-lg-3 vertical-child" style="text-align: center">
<div class="header">&nbsp;</div>
<input type="submit" class="btn btn-simple" value="СОХРАНИТЬ">
</div>
</div> </div>
<div class="col-lg-3">
<div class="header">Skype</div>
<input name="{{ form.skype.html_name }}" class="simple-input" placeholder="skype id"
value="{{ form.skype.value }}">
</div>
<div class="clearfix visible-lg"></div>
<div class="col-lg-3 vertical-child">
<div class="header">Сайт</div>
<input name="{{ form.website.html_name }}" class="simple-input"
placeholder="example.com"
value="{{ form.website.value }}">
</div>
<div class="col-lg-3 vertical-child">
<div class="header">Телефон</div>
<input name="{{ form.phone.html_name }}" class="simple-input phone"
placeholder="+7 909 999 00 00"
value="{{ form.phone.value }}"
type="tel">
</div>
<div class="col-lg-3 vertical-child">
<div class="header">Второй телефон</div>
<input name="{{ form.phone2.html_name }}" class="simple-input phone"
placeholder="+7 909 999 00 00"
value="{{ form.phone2.value }}"
type="tel">
</div>
<div class="col-lg-3 vertical-child" style="text-align: center">
<div class="header">&nbsp;</div>
<input type="submit" class="btn btn-simple" value="СОХРАНИТЬ">
</div>
</div>
</div> </div>
</div> <!-- bottom --> </div> <!-- bottom -->
</div> </div>
</form> </form>
</div> {# </div>#}
<div class="row">
{% include 'partials/footer.html' %}
</div> </div>
</div> </div>
{% endblock %} {% endblock %}
{% block js_block %} {% block personal_js %}
{{ block.super }} {{ block.super }}
<script src='{% static "lib/proekton-components/js/build/init_user_profile.js" %}'></script> <script src='{% static "lib/proekton-components/js/build/init_user_profile.js" %}'></script>
<script src='{% static "projects-filter.js" %}'></script> <script src='{% static "projects-filter.js" %}'></script>

@ -25,7 +25,7 @@
{% csrf_token %} {% csrf_token %}
{% if request.user.is_customer %} {% if request.user.is_customer %}
<input type="hidden" name="next" value="{% url 'users:customer-profile-open-projects' pk=pk %}"> <input type="hidden" name="next" value="{% url 'users:customer-profile' pk=pk %}">
{% elif request.user.is_contractor %} {% elif request.user.is_contractor %}
<input type="hidden" name="next" value="{% url 'users:contractor-profile' pk=pk %}"> <input type="hidden" name="next" value="{% url 'users:contractor-profile' pk=pk %}">
{% endif %} {% endif %}

@ -10,6 +10,7 @@ from .views import (
ContractorProfileView, ContractorProfileView,
ContractorResumeUpdateView, ContractorResumeUpdateView,
CreateTeamInvitation, CreateTeamInvitation,
CustomerProfileView,
CustomerProfileCurrentProjectsView, CustomerProfileCurrentProjectsView,
CustomerProfileOpenProjectsView, CustomerProfileOpenProjectsView,
CustomerProfileReviewsView, CustomerProfileReviewsView,
@ -24,15 +25,9 @@ from .views import (
app_name = 'users' app_name = 'users'
urlpatterns = [ urlpatterns = [
# urls.url(r'^(?P<pk>\d+)/edit/$', UserProfileEditView.as_view(), name='user-profile-edit'),
urls.url(r'^(?P<pk>\d+)/edit/$', UserProfileEditViewFull.as_view(), name='user-profile-edit'), urls.url(r'^(?P<pk>\d+)/edit/$', UserProfileEditViewFull.as_view(), name='user-profile-edit'),
# urls.url(r'^(?P<pk>\d+)/financial-info/edit/$', UserFinancialInfoEditView.as_view(), urls.url(r'^customers/(?P<pk>\d+)/$', CustomerProfileView.as_view(),
# name='user-financial-info-edit'), name='customer-profile'),
# urls.url(r'^(?P<pk>\d+)/experience/edit/$', UserProfileEditView.as_view(), name='user-experience-edit'),
urls.url(r'^customers/(?P<pk>\d+)/$', CustomerProfileOpenProjectsView.as_view(),
name='customer-profile-open-projects'),
urls.url(r'^customers/(?P<pk>\d+)/trashed-projects/$', CustomerProfileTrashedProjectsView.as_view(), urls.url(r'^customers/(?P<pk>\d+)/trashed-projects/$', CustomerProfileTrashedProjectsView.as_view(),
name='customer-profile-trashed-projects'), name='customer-profile-trashed-projects'),
urls.url(r'^customers/(?P<pk>\d+)/current-projects/$', CustomerProfileCurrentProjectsView.as_view(), urls.url(r'^customers/(?P<pk>\d+)/current-projects/$', CustomerProfileCurrentProjectsView.as_view(),

@ -13,18 +13,18 @@ from django.core.paginator import Paginator, EmptyPage, PageNotAnInteger
from django.db.models import Q from django.db.models import Q
from django.http import HttpResponse, JsonResponse, Http404 from django.http import HttpResponse, 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 DetailView, View, UpdateView, CreateView from django.views.generic import DetailView, View, UpdateView, CreateView, TemplateView
_.map = _.map_; _.map = _.map_;
_.filter = _.filter_ _.filter = _.filter_
from .forms import TeamForm, ContractorResumeFilesForm, ContractorResumeForm from .forms import TeamForm, ContractorResumeFilesForm, ContractorResumeForm, CustomerProfileForm
from .models import User, Team, ContractorResume, ContractorResumeFiles, TeamInvitation from .models import User, Team, ContractorResume, ContractorResumeFiles, TeamInvitation
from archilance import util from archilance import util
from archilance.mixins import BaseMixin from archilance.mixins import BaseMixin
from common.mixins import ContractorRequiredMixin, NoCsrfMixin from common.mixins import ContractorRequiredMixin, NoCsrfMixin
from projects.forms import PortfolioForm from projects.forms import PortfolioForm
from projects.models import Order from projects.models import Order, Realty, Project
from reviews.models import Review from reviews.models import Review
from work_sell.forms import WorkSellForm from work_sell.forms import WorkSellForm
from work_sell.models import Picture from work_sell.models import Picture
@ -130,13 +130,13 @@ class UserProfileEditViewFull(BaseMixin, View):
def post(self, request, *args, **kwargs): def post(self, request, *args, **kwargs):
context = self.get_context_data(**kwargs) context = self.get_context_data(**kwargs)
specs = tuple(filter(None, re.split(r'\s|,|;', request.POST.get('contractor_specializations')))) specs = tuple(filter(None, re.split(r'\s|,|;', request.POST.get('contractor_specializations', ''))))
request.POST.setlist('contractor_specializations', specs) request.POST.setlist('contractor_specializations', specs)
builds = tuple(filter(None, re.split(r'\s|,|;', request.POST.get('contractor_building_classifications')))) builds = tuple(filter(None, re.split(r'\s|,|;', request.POST.get('contractor_building_classifications', ''))))
request.POST.setlist('contractor_building_classifications', builds) request.POST.setlist('contractor_building_classifications', builds)
constructs = tuple(filter(None, re.split(r'\s|,|;', request.POST.get('contractor_construction_types')))) constructs = tuple(filter(None, re.split(r'\s|,|;', request.POST.get('contractor_construction_types', ''))))
request.POST.setlist('contractor_construction_types', constructs) request.POST.setlist('contractor_construction_types', constructs)
form = self.form_class(request.POST, request=request, instance=request.user) form = self.form_class(request.POST, request=request, instance=request.user)
@ -316,7 +316,7 @@ class ContractorFilterView(BaseMixin, View):
if build_classif: if build_classif:
contractors = contractors.filter(Q(orders__project__realty__building_classification=build_classif) | contractors = contractors.filter(Q(orders__project__realty__building_classification=build_classif) |
Q(contractor_building_classifications=build_classif)) Q(contractor_building_classifications=build_classif))
if constr_type: if constr_type:
contractors = contractors.filter(Q(orders__project__realty__construction_type=constr_type) | contractors = contractors.filter(Q(orders__project__realty__construction_type=constr_type) |
Q(contractor_construction_types=constr_type)) Q(contractor_construction_types=constr_type))
@ -617,6 +617,56 @@ class ContractorOfficeProjectsView(BaseMixin, View):
return render(request, self.template_name, context) return render(request, self.template_name, context)
class CustomerProfileView(BaseMixin, DetailView):
template_name = 'customer_profile.html'
model = User
context_object_name = 'customer'
def get_object(self, queryset=None):
return get_object_or_404(User, pk=self.kwargs['pk'])
def get_context_data(self, **kwargs):
context = super().get_context_data()
user_id = self.kwargs['pk']
# profile-info
context.update(
{
'ratings': User.objects.get(pk=user_id).rating,
'deals': Order.objects.filter(secure=True, contractor_id=user_id, status=1).count(),
'reviews_n': Review.objects.filter(target_contractor_id=user_id, type='neutral').count(),
'reviews_m': Review.objects.filter(target_contractor_id=user_id, type='negative').count(),
'reviews_p': Review.objects.filter(target_contractor_id=user_id, type='positive').count(),
})
# Realty
context.update({
'objects': Realty.objects.filter(user=self.kwargs['pk'], is_virtual=False, state="active"),
'trashed_objects': Realty.objects.filter(user=self.kwargs['pk'], is_virtual=False, state="trashed"),
})
customer = self.object
open_projects = customer.customer_projects.filter(state='active')
trashed_projects = customer.customer_projects.filter(state='trashed', order__contractor__isnull=True,
order__team__isnull=True)
projects_in_work = customer.customer_projects.filter(state='active').exclude(order__contractor__isnull=True,
order__team__isnull=True)
reviews = Review.objects.filter(target_customer=customer)
context.update({
'customer': customer,
'open_projects': open_projects,
'trashed_projects': trashed_projects,
'projects_in_work': projects_in_work,
'reviews': reviews,
# 'is_paginated': True,
# 'page_obj': projects,
})
return context
class CustomerProfileOpenProjectsView(BaseMixin, View): class CustomerProfileOpenProjectsView(BaseMixin, View):
template_name = 'customer_profile_open_projects.html' template_name = 'customer_profile_open_projects.html'
form_class = CustomerProfileProjectRealtyForm form_class = CustomerProfileProjectRealtyForm
@ -631,7 +681,7 @@ class CustomerProfileOpenProjectsView(BaseMixin, View):
order__team__isnull=True) order__team__isnull=True)
# @Add fast # @Add fast
num_current_projects = customer.customer_projects.filter(state='active').exclude(order__contractor__isnull=True, num_current_projects = customer.customer_projects.filter(state='active').exclude(order__contractor__isnull=True,
order__team__isnull=True).count() order__team__isnull=True).count()
if form.is_valid(): if form.is_valid():
realty = form.cleaned_data.get('realty') realty = form.cleaned_data.get('realty')

@ -16,6 +16,8 @@ module.exports = {
init_create_worksell: './assets/js/src/init_create_worksell.js', init_create_worksell: './assets/js/src/init_create_worksell.js',
//home //home
home_page: "./assets/js/src/home_page.js", home_page: "./assets/js/src/home_page.js",
//profile
customer_profile: "./assets/js/src/customer_profile.js"
}, },

Loading…
Cancel
Save