瀏覽代碼

new menu structure and old pages adaptation for furhter testing

ShariX Developer 6 天之前
父節點
當前提交
6d872b3555

+ 1 - 0
sharix_admin/forms/__init__.py

@@ -1,5 +1,6 @@
 from .auth import *
 from .base import BaseForm
 from .company import *
+from .job_request import *
 from .document import *
 from .service import *

+ 36 - 0
sharix_admin/forms/job_request.py

@@ -0,0 +1,36 @@
+from django import forms
+
+from sharix_admin.forms import BaseForm
+
+class JobRequestMetaserviceForm(BaseForm, forms.Form):
+    
+    #message = forms.CharField(widget=forms.Textarea)
+    CHOICES = [
+        ('METASERVICE-SUPERVISOR', 'Стать модератором Сервиса'),
+        ('METASERVICE-SUPPORT', 'Стать сотрудником Поддержки Сервиса'),
+        ('METASERVICE-TECHSUPPORT', 'Стать сотрудником Техподдержки Сервиса'),
+    ]
+    
+    multiple_choice_field_select = forms.MultipleChoiceField(
+        choices=CHOICES,
+        required=True,
+        label="Выберите виды деятельности",
+        # widget=forms.CheckboxSelectMultiple() # TODO: Fix
+    )
+
+class JobRequestPartnerForm(BaseForm, forms.Form):
+
+    #message = forms.CharField(widget=forms.Textarea)
+    CHOICES = [
+        ('PARTNER-SUPERVISOR', 'Стать модератором Партнера Сервиса'),
+        ('PARTNER-SUPPORT', 'Стать сотрудником Поддержки Партнера Сервиса'),
+        ('PARTNER-TECHSUPPORT', 'Стать сотрудником Техподдержки Партнера Сервиса'),
+        ('PROVIDER', 'Стать Исполнителем'),
+    ]
+
+    multiple_choice_field_select = forms.MultipleChoiceField(
+        choices=CHOICES,
+        required=True,
+        label="Выберите виды деятельности",
+        # widget=forms.CheckboxSelectMultiple() # TODO: Fix
+    )

+ 142 - 9
sharix_admin/tables.py

@@ -145,7 +145,7 @@ class PartnersTable(tables.Table):
             )
 
 
-class ResourceTable(tables.Table):
+class ResourcesTable(tables.Table):
     id = tables.Column(
         verbose_name=_('ID'),
         attrs={
@@ -204,7 +204,7 @@ class ResourceTable(tables.Table):
             )
 
 
-class ProviderTable(tables.Table):
+class ProvidersTable(tables.Table):
     id = tables.Column(
         verbose_name=_('ID'),
         attrs={
@@ -265,7 +265,7 @@ class ProviderTable(tables.Table):
             )
 
 
-class ServiceTariffTable(tables.Table):
+class ServiceTariffsTable(tables.Table):
     id = tables.Column(
         verbose_name=_('ID'),
         attrs={
@@ -273,7 +273,7 @@ class ServiceTariffTable(tables.Table):
         }
     )
     service_category = tables.LinkColumn(
-        'service_tariff/edit/',
+        'sharix_admin:service_tariff/edit/',
         verbose_name=_('Name of the tariff'),
         text=lambda record: record.service_category.caption,
         args=[tables.A('pk')],
@@ -323,10 +323,10 @@ class ServiceTariffTable(tables.Table):
             return format_html('<input class="form-check-input status-toggle" disabled  type="checkbox"')
 
 
-class ServiceCategoryTable(tables.Table):
+class ServiceCategoriesTable(tables.Table):
     id = tables.Column(attrs={"td": {"width": "50px"}})
     codename = tables.LinkColumn(
-        'service_category/edit/',
+        'sharix_admin:service_category/edit/',
         verbose_name='Услуга',
         orderable=False,
         text=lambda record: record.codename,
@@ -338,7 +338,7 @@ class ServiceCategoryTable(tables.Table):
         }
     )
     description = tables.LinkColumn(
-        'service_category/edit/',
+        'sharix_admin:service_category/edit/',
         orderable=False, verbose_name='Описание',
         text=lambda record: record.description,
         args=[tables.A('pk')],
@@ -349,7 +349,7 @@ class ServiceCategoryTable(tables.Table):
         }
     )
     edit = tables.LinkColumn(
-        'service_category/edit/',
+        'sharix_admin:service_category/edit/',
         verbose_name='',
         orderable=False,
         text="E",
@@ -360,7 +360,7 @@ class ServiceCategoryTable(tables.Table):
         }
     )
     deletee = tables.LinkColumn(
-        'service_category/delete/',
+        'sharix_admin:service_category/delete/',
         verbose_name='',
         orderable=False,
         text="D",
@@ -484,3 +484,136 @@ class UserInfoTable(tables.Table):
             'is_superuser',
             'date_joined'
         )
+
+
+class PermissionsTable(tables.Table):
+    id = tables.Column(
+        verbose_name=_('ID'),
+        attrs={
+            "td": {"width": "5%"}
+        }
+    )
+    user = tables.Column(
+        accessor='user.full_name',
+        order_by=('user.first_name', 'user.last_name'),
+        verbose_name=_('User'),
+        attrs={
+            "td": {"width": "15%"}
+        }
+    )
+
+    id_permissions = tables.Column(
+        verbose_name=_('Permission'),
+        attrs={
+            "td": {"width": "15%"}
+        }
+    )
+
+    status = tables.Column(
+        verbose_name=_('Status'),
+        attrs={
+            'th': {'scope': 'col'},
+            "td": {"width": "20%"}
+        }
+    )
+    check = tables.BooleanColumn(
+        verbose_name='',
+        attrs={
+            'th': {'scope': 'col'},
+            "td": {"width": "20%"}
+        }
+    )
+
+    # paginate_by = 10
+    class Meta:
+        model = Permissions
+        attrs = {
+            "class": "table table-layout-fixed"
+        }
+        exclude = (
+            'check_date',
+            'expire_date',
+            'check_level',
+            'checked_by',
+            'ticket_status'
+        )
+
+    def render_check(self, value, record):
+        if record.status == 'active':
+            return format_html(
+                '<input class="form-check-input status-toggle" checked type="checkbox" id="flexCheckDefault" data-resource-id="{}">',
+                record.id
+            )
+        else:
+            return format_html(
+                '<input class="form-check-input status-toggle" type="checkbox" id="flexCheckDefault" data-resource-id="{}">',
+                record.id
+            )
+
+
+class RelationshipTable(tables.Table):
+    id = tables.Column(
+        verbose_name=_('ID'),
+        attrs={
+            "td": {"width": "5%"}
+        }
+    )
+    user_who = tables.Column(
+        accessor='user_who.full_name',
+        order_by=('user_who.first_name', 'user_who.last_name'),
+        verbose_name=_('Initiator'),
+        attrs={
+            "td": {"width": "15%"}
+        }
+    )
+    user_whom = tables.Column(
+        accessor='user_whom.full_name',
+        order_by=('user_whom.first_name', 'user_whom.last_name'),
+        verbose_name=_('Goal'),
+        attrs={
+            "td": {"width": "15%"}
+        }
+    )
+    neg_type = tables.Column(
+        verbose_name=_('Neg Type'),
+        attrs={
+            'th': {'scope': 'col'},
+            "td": {"width": "20%"}
+        }
+    )
+    status = tables.Column(
+        verbose_name=_('Status'),
+        attrs={
+            'th': {'scope': 'col'},
+            "td": {"width": "20%"}
+        }
+    )
+    check = tables.BooleanColumn(
+        verbose_name='',
+        attrs={
+            'th': {'scope': 'col'},
+            "td": {"width": "20%"}
+        }
+    )
+    paginate_by = 10
+
+    class Meta:
+        model = Relationship
+        attrs = {
+            "class": "table table-layout-fixed"
+        }
+        exclude = (
+            'ticket_status',
+        )
+
+    def render_check(self, value, record):
+        if record.status == 'active':
+            return format_html(
+                '<input class="form-check-input status-toggle" checked type="checkbox" id="flexCheckDefault" data-provider-id="{}">',
+                record.id
+            )
+        else:
+            return format_html(
+                '<input class="form-check-input status-toggle" type="checkbox" id="flexCheckDefault" data-provider-id="{}">',
+                record.id
+            )

+ 3 - 1
sharix_admin/templates/sharix_admin/base.html

@@ -11,7 +11,9 @@
     <link rel="stylesheet" href="{% static 'fontawesomefree/css/brands.css' %}">
     
     <link rel="stylesheet" href="{% static 'sharix_admin/css/base.css' %}">
-    
+
+    <link rel="stylesheet" type="text/css" href="https://msg.sharix-app.org/dist/converse.min.css">
+
     <link rel="icon" href="{% static 'sharix_admin/img/favicon.ico' %}" type="image/x-icon">
     <title>
         {% if title %}

+ 240 - 7
sharix_admin/templates/sharix_admin/base_admin.html

@@ -59,7 +59,63 @@
           </div>
         </a>
       </li>
-      {% comment %} <li class="nav-item">
+
+      <!-- STAFF MENU-->
+      <!-- METASERVICE ADMIN OPEN SPECIFIC MENU -->
+
+      {% if "METASERVICE-ADMIN" in user_groups %}
+
+      <li class="nav-item">
+        <a href="{% url 'sharix_admin:service_categories' %}" class="nav-link {% if current_page == "service_categories" %}active rounded{% endif %}">
+          <div class="link d-flex align-items-center">
+            <img
+              class="nav-img"
+              src="
+                {% if current_page == "service_categories" %}
+                  {% static 'sharix_admin/img/menu/briefcase_w.svg' %}
+                {% else %}
+                  {% static 'sharix_admin/img/menu/briefcase.svg' %}
+                {% endif %}">
+            <span class="menu-bar-label">Категории услуг</span>
+          </div>
+        </a>
+      </li>
+
+      <li class="nav-item">
+        <a href="{% url 'sharix_admin:service_category/add/' %}" class="nav-link {% if current_page == "service_category/add/" %}active rounded{% endif %}">
+          <div class="link d-flex align-items-center">
+            <img
+              class="nav-img"
+              src="
+                {% if current_page == "service_category/add/" %}
+                  {% static 'sharix_admin/img/menu/briefcase_w.svg' %}
+                {% else %}
+                  {% static 'sharix_admin/img/menu/briefcase.svg' %}
+                {% endif %}">
+            <span class="menu-bar-label">Добавить категорию услуг</span>
+          </div>
+        </a>
+      </li>
+
+      <!-- TODO - add metaservice supervisor to viewers -->
+      <li class="nav-item">
+        <a href="{% url 'sharix_admin:service_tariffs' %}" class="nav-link {% if current_page == "service_tariffs" %}active rounded{% endif %}">
+          <div class="link d-flex align-items-center">
+            <img
+              class="nav-img"
+              src="
+                {% if current_page == "service_tariffs" %}
+                  {% static 'sharix_admin/img/menu/briefcase_w.svg' %}
+                {% else %}
+                  {% static 'sharix_admin/img/menu/briefcase.svg' %}
+                {% endif %}">
+            <span class="menu-bar-label">Тарифы услуг</span>
+          </div>
+        </a>
+      </li>
+
+      <!-- TODO - add metaservice supervisor to viewers maybe without duplication -->
+      <li class="nav-item">
         <a href="{% url "sharix_admin:partners" %}" class="nav-link {% if current_page == "partners" %}active rounded{% endif %}">
           <div class="link d-flex align-items-center">
             <img
@@ -73,24 +129,179 @@
             <span class="menu-bar-label">Партнеры</span>
           </div>
         </a>
-      </li> {% endcomment %}
+      </li>
+
+            <!-- TODO: Управление правами ADD ALSO CHECK FOR SUPERVISOR-->
+        <a href="{% url 'sharix_admin:access_control' %}" class="nav-link {% if current_page == "access_control" %}active rounded{% endif %}">
+          <div class="link d-flex align-items-center">
+            <img
+              class="nav-img"
+              src="
+                {% if current_page == "access_control" %}
+                  {% static 'sharix_admin/img/menu/hdd-network_w.svg' %}
+                {% else %}
+                  {% static 'sharix_admin/img/menu/hdd-network.svg' %}
+                {% endif %}">
+            <span class="menu-bar-label">Управление правами</span>
+          </div>
+        </a>
+      </li>
+
+      {% endif %}
+
+
+      <!-- METASERVICE SUPERVISOR MENU BLOCK -->
+      {% if "METASERVICE-SUPERVISOR" in user_groups %}
+      <li class="nav-item">
+        <a href="{% url "sharix_admin:partners" %}" class="nav-link {% if current_page == "partners" %}active rounded{% endif %}">
+          <div class="link d-flex align-items-center">
+            <img
+              class="nav-img"
+              src="
+                {% if current_page == "partners" %}
+                  {% static 'sharix_admin/img/menu/people_w.svg' %}
+                {% else %}
+                  {% static 'sharix_admin/img/menu/people.svg' %}
+                {% endif %}">
+            <span class="menu-bar-label">Партнеры</span>
+          </div>
+        </a>
+      </li>
+
+      <li class="nav-item">
+        <a href="{% url "sharix_admin:resources" %}" class="nav-link {% if current_page == "resources" %}active rounded{% endif %}">
+          <div class="link d-flex align-items-center">
+            <img
+              class="nav-img"
+              src="
+                {% if current_page == "resources" %}
+                  {% static 'sharix_admin/img/menu/people_w.svg' %}
+                {% else %}
+                  {% static 'sharix_admin/img/menu/people.svg' %}
+                {% endif %}">
+            <span class="menu-bar-label">Ресурсы</span>
+          </div>
+        </a>
+      </li>
+
+      <li class="nav-item">
+        <a href="{% url "sharix_admin:providers" %}" class="nav-link {% if current_page == "providers" %}active rounded{% endif %}">
+          <div class="link d-flex align-items-center">
+            <img
+              class="nav-img"
+              src="
+                {% if current_page == "providers" %}
+                  {% static 'sharix_admin/img/menu/people_w.svg' %}
+                {% else %}
+                  {% static 'sharix_admin/img/menu/people.svg' %}
+                {% endif %}">
+            <span class="menu-bar-label">Исполнители</span>
+          </div>
+        </a>
+      </li>
+
+      <!-- PARTNER-ADMIN menu block TODO - add customization to list views -->
+
+      <li class="nav-item">
+        <a href="{% url "sharix_admin:resources" %}" class="nav-link {% if current_page == "resources" %}active rounded{% endif %}">
+          <div class="link d-flex align-items-center">
+            <img
+              class="nav-img"
+              src="
+                {% if current_page == "resources" %}
+                  {% static 'sharix_admin/img/menu/people_w.svg' %}
+                {% else %}
+                  {% static 'sharix_admin/img/menu/people.svg' %}
+                {% endif %}">
+            <span class="menu-bar-label">Мои Ресурсы</span>
+          </div>
+        </a>
+      </li>
+
+       <li class="nav-item">
+        <a href="{% url 'sharix_admin:resource/add/' %}" class="nav-link {% if current_page == "resource/add/" %}active rounded{% endif %}">
+          <div class="link d-flex align-items-center">
+            <img
+              class="nav-img"
+              src="
+                {% if current_page == "resource/add/" %}
+                  {% static 'sharix_admin/img/menu/briefcase_w.svg' %}
+                {% else %}
+                  {% static 'sharix_admin/img/menu/briefcase.svg' %}
+                {% endif %}">
+            <span class="menu-bar-label">Добавить ресурс</span>
+          </div>
+        </a>
+      </li>
+
+       <li class="nav-item">
+        <a href="{% url "sharix_admin:providers" %}" class="nav-link {% if current_page == "providers" %}active rounded{% endif %}">
+          <div class="link d-flex align-items-center">
+            <img
+              class="nav-img"
+              src="
+                {% if current_page == "providers" %}
+                  {% static 'sharix_admin/img/menu/people_w.svg' %}
+                {% else %}
+                  {% static 'sharix_admin/img/menu/people.svg' %}
+                {% endif %}">
+            <span class="menu-bar-label">Мои Исполнители</span>
+          </div>
+        </a>
+      </li>
+
+      <li class="nav-item">
+        <a href="{% url 'sharix_admin:provider/add/' %}" class="nav-link {% if current_page == "provider/add/" %}active rounded{% endif %}">
+          <div class="link d-flex align-items-center">
+            <img
+              class="nav-img"
+              src="
+                {% if current_page == "provider/add/" %}
+                  {% static 'sharix_admin/img/menu/briefcase_w.svg' %}
+                {% else %}
+                  {% static 'sharix_admin/img/menu/briefcase.svg' %}
+                {% endif %}">
+            <span class="menu-bar-label">Добавить Исполнителя</span>
+          </div>
+        </a>
+      </li>
+      {% endif %}
+
+
+      <!-- COOPERATE BLOCK -->
       {% if not "PARTNER-ADMIN" in user_groups %}
         <li class="nav-item">
-          <a href="{% url "sharix_admin:cooperate" %}" class="nav-link {% if current_page == "cooperate" %}active rounded{% endif %}">
+          <a href="{% url "sharix_admin:cooperate_request" %}" class="nav-link {% if current_page == "cooperate_request" %}active rounded{% endif %}">
             <div class="link d-flex align-items-center">
               <img
                 class="nav-img"
                 src="
-                  {% if current_page == "cooperate" %}
+                  {% if current_page == "cooperate_request" %}
                     {% static 'sharix_admin/img/menu/handshake_w.svg' %}
                   {% else %}
                     {% static 'sharix_admin/img/menu/handshake.svg' %}
                   {% endif %}">
-              <span class="menu-bar-label">Сотрудничество</span>
+              <span class="menu-bar-label">Стать партнером</span>
             </div>
           </a>
         </li>
       {% endif %}
+
+        <li class="nav-item">
+          <a href="{% url "sharix_admin:job_request_metaservice" %}" class="nav-link {% if current_page == "job_request_metaservice" %}active rounded{% endif %}">
+            <div class="link d-flex align-items-center">
+              <img
+                class="nav-img"
+                src="
+                  {% if current_page == "job_request_metaservice" %}
+                    {% static 'sharix_admin/img/menu/handshake_w.svg' %}
+                  {% else %}
+                    {% static 'sharix_admin/img/menu/handshake.svg' %}
+                  {% endif %}">
+              <span class="menu-bar-label">Работа в Сервисе</span>
+            </div>
+          </a>
+        </li>
       {% comment %} <li class="nav-item">
         <a href="{% url 'sharix_admin:user_information' %}" class="nav-link {% if current_page == "none" %}active rounded{% endif %}">
           <div class="link d-flex align-items-center">
@@ -106,7 +317,9 @@
           </div>
         </a>
       </li> {% endcomment %}
-      {% comment %} <li class="nav-item">
+
+      {% comment %}
+      <li class="nav-item">
         <a href="{% url 'sharix_admin:service_category' %}" class="nav-link {% if current_page == "service_category" %}active rounded{% endif %}">
           <div class="link d-flex align-items-center">
             <img
@@ -183,6 +396,26 @@
           </div>
         </a>
       </li> {% endcomment %}
+
+
+      <!-- Converse integration -->
+      <li class="nav-item">
+        <a href="{% url 'sharix_admin:support_chat' %}" class="nav-link {% if current_page == "support_chat" %}active rounded{% endif %}">
+          <div class="link d-flex align-items-center">
+            <img
+              class="nav-img"
+              src="
+                {% if current_page == "support_chat" %}
+                  {% static 'sharix_admin/img/menu/tickets_w.svg' %}
+                {% else %}
+                  {% static 'sharix_admin/img/menu/tickets.svg' %}
+                {% endif %}">
+            <span class="menu-bar-label">Чат с техподдержкой</span>
+          </div>
+        </a>
+      </li>
+
+
     </ul>
   </nav>
 
@@ -236,4 +469,4 @@
   // Скрыть экран загрузки через 4 секунды
   setTimeout(hideLoader, 400);
 </script>
-{% endblock %}
+{% endblock %}

+ 2 - 2
sharix_admin/templates/sharix_admin/main.html

@@ -38,7 +38,7 @@
                 Стать частью команды
             </a>
             {% if not "PARTNER-ADMIN" in user_groups %}
-                <a href="{% url "sharix_admin:cooperate" %}" class="btn btn-sm btn-primary">
+                <a href="{% url "sharix_admin:cooperate_request" %}" class="btn btn-sm btn-primary">
                     <i class="fa-solid fa-handshake me-1"></i>
                     Стать партнером
                 </a>
@@ -71,4 +71,4 @@
         </ul>
     </div>
 </div>
-{% endblock %}
+{% endblock %}

+ 1 - 1
sharix_admin/templates/sharix_admin/partners.html

@@ -16,7 +16,7 @@
       var partners_id = $(this).data('partners-id');
       var new_status = $(this).prop('checked') ? 'active' : 'deactivated';
       $.ajax({
-        url: '{% url "sharix_admin:partners/change_status" %}',
+        url: '{% url "sharix_admin:partner/change_status" %}',
         type: 'POST',
         data: {
           'partners_id': partners_id,

+ 0 - 0
sharix_admin/templates/sharix_admin/provider.html → sharix_admin/templates/sharix_admin/providers.html


+ 0 - 0
sharix_admin/templates/sharix_admin/cooperate.html → sharix_admin/templates/sharix_admin/requests/cooperate.html


+ 46 - 0
sharix_admin/templates/sharix_admin/requests/job_request.html

@@ -0,0 +1,46 @@
+{% extends 'sharix_admin/base_admin.html' %}
+
+{% block view %}
+<p>
+    
+        Хотите стать частью команды? Отправьте заявку. Наши сотрудники свяжутся с Вами.
+    
+</p>
+
+<form method="post" class="d-flex flex-column align-items-end">
+    {% csrf_token %}
+    {% include 'sharix_admin/include/form.html' %}
+
+    <div class="form-check text-muted w-100">
+        <input type="checkbox" class="form-check-input" id="checkbox-user-agreement">
+        <label class="form-check-label" for="checkbox-user-agreement">
+            Я соглашаюсь с
+            <a class="link-secondary" href="https://wiki.sharix-app.org/doku.php/sxplatform/doc/infrastructure" target="_blank">
+                договором об использовании информационных сервисов
+            </a>
+        </label>
+    </div>
+
+    <div class="form-check text-muted w-100">
+        <input type="checkbox" class="form-check-input" id="checkbox-job-agreement">
+        <label class="form-check-label" for="checkbox-job-agreement">
+            Я соглашаюсь с
+            <a class="link-secondary" href="https://wiki.sharix-app.org/" target="_blank">
+                договором о сотрудничестве
+            </a>
+        </label>
+    </div>
+
+    <button id="btn-submit" class="btn btn-primary" type="submit" disabled>Отправить</button>
+</form>
+{% endblock %}
+
+{% block extra_js %}
+<script>
+    makeCheckboxesMandatory(
+        document.getElementById('btn-submit'),
+        document.getElementById('checkbox-user-agreement'),
+        document.getElementById('checkbox-job-agreement')
+    );
+</script>
+{% endblock %}

+ 0 - 0
sharix_admin/templates/sharix_admin/resource.html → sharix_admin/templates/sharix_admin/resources.html


+ 0 - 0
sharix_admin/templates/sharix_admin/service_category.html → sharix_admin/templates/sharix_admin/service_categories.html


+ 0 - 0
sharix_admin/templates/sharix_admin/service_tariff.html → sharix_admin/templates/sharix_admin/service_tariffs.html


+ 24 - 0
sharix_admin/templates/sharix_admin/staff/access_control.html

@@ -0,0 +1,24 @@
+{% extends 'sharix_admin/base_admin.html' %}
+{% load i18n %}
+
+{% block view %}
+{% block contenthome %}
+<h1 class="mainHeader">{{ title }}</h1>
+<form method="post" style="overflow: auto">
+    {% csrf_token %}
+    <div class="container m-2">
+        {% for field in form %}
+        {{field.errors}}
+        <div class="row">
+            {{field.label_tag}}
+            {{field}}
+            <p class="fs-6 fst-italic">{{field.help_text|truncatewords:20}}</p>
+        </div>
+        {% endfor %}
+    </div>
+    <div class="text-center mt-2 mb-5">
+        <input class="btn btn-primary center" type="submit" name="apply" value="{% trans 'Submit' %}" />
+    </div>
+</form>
+{% endblock contenthome %}
+{% endblock view %}

+ 77 - 0
sharix_admin/templates/sharix_admin/support_chat.html

@@ -0,0 +1,77 @@
+{% extends 'sharix_admin/base_admin.html' %}
+
+{% block view %}
+{% block contenthome %}
+    <p class="description_service">{{ user }}, приветствуем в личном кабинете сервиса ShariX Platform! Тут можно будет поговорить с техподдержкой.</p>
+
+<section class="section-wrapper">
+    <section id="intro" class="intro text-center" class="container">
+        <div class="row">
+            <div class="col-md-12 col-md-offset-2">
+
+
+                <div class="converse-container" style="width: 500px; height: 500px;">
+                    <converse-root></converse-root>
+                </div>
+            </div>
+        </div>
+    </section>
+</section>
+
+
+<!--- /var/www/webapps/converse11/dist/converse.min.js --->
+<script src="https://msg.sharix-app.org/dist/converse.min.js"></script>
+<script>
+  converse.initialize({
+    // Your XMPP server settings here
+    server_url: "msg.sharix-app.org",
+//    view_mode: 'embedded',
+//    singleton: true,
+    bosh_service_url: 'https://msg.sharix-app.org/bosh',
+    //jid: 'me@msg.sharix-app.org',
+//    authentication: 'anonymous',
+    //authentication: 'prebind',
+    //prebind_url: 'http://sharix-app.org/api/converse-prebind',
+//    auto_login: true,
+    allow_logout: false,
+    auto_join_private_chat: ['2101@msg.sharix-app.org'],
+  //  auto_join_rooms: [
+//      'jid': 'room@chat.msg.sharix-app.org',
+        //'nick': 'WizardKing69',
+//      'minimized': false,
+//      ],
+    allow_contact_removal: false,
+    allow_contact_requests: false,
+    //allow_dragresize: false,
+    allow_message_corrections: 'none',
+    allow_message_retraction: 'none',
+    allow_muc_invitations: false,
+    allow_non_roster_messaging: true,
+    allow_registration: false,
+    allow_user_trust_override: false,
+    auto_reconnect: true,
+    auto_join_on_invite: true,
+    chatstate_notification_blacklist: [
+        'django-test@msg.sharix-app.org',
+        ],
+    //default_domain: 'msg.sharix-app.org',
+    hide_offline_users: true,
+    //locked_domain: true,
+    //locked_muc_nickname: true,
+    muc_clear_messages_on_leave: false,
+    //muc_disable_slash_commands: true,
+    //muc_domain: 'chat.msg.sharix-app.org',
+    //nickname: 'Name',
+    notify_all_room_messages: true,
+    //show_background: false,
+    theme: 'dracula',
+    view_mode: 'embedded',
+
+  });
+</script>
+
+
+{% endblock contenthome %}
+
+{% endblock  %}
+

+ 52 - 22
sharix_admin/urls.py

@@ -20,6 +20,8 @@ app_name = "sharix_admin"
 urlpatterns = [
     # Главная
     path('', login_required(MainView.as_view()), name='main'),
+    path('support-chat', login_required(SupportChatView.as_view()), name='support_chat'),
+
 
     # --- Ниже страницы, требующие ревью ---
 
@@ -27,43 +29,76 @@ urlpatterns = [
     path('payment/', login_required(PaymentView.as_view()), name='payment'),
 
     # Страница "Сотрудничество" (запрос на подключение к сервису)
-    path('cooperate/', login_required(CooperateView.as_view()), name='cooperate'),
+    path('cooperate-request/', login_required(CooperateView.as_view()), name='cooperate_request'),
+    path('job-request/', login_required(JobRequestMetaserviceView.as_view()), name='job_request_metaservice'),
+    #path('job-request/<str:partner>', login_required(JobRequestPartnerView.as_view()), name='job_request_partner'),
 
-    # Страница "О партнере"
-    path('partner/', login_required(PartnerDetailView.as_view()), name='partner_detail'),
-    path('partner/edit/', login_required(PartnerEditView.as_view()), name='partner_edit'),
+    # Набор страниц по модели Партнер
+    path('partners/', login_required(PartnersListView.as_view()), name='partners'),
+    path('partner/<str:pk>', login_required(PartnerDetailView.as_view()), name='partner_detail'),
+    path('partner/edit/<int:pk>', login_required(PartnerEditView.as_view()), name='partner_edit'),
     path('partner/doc/<str:doc_code>/upload', login_required(PartnerDocUploadView.as_view()),
          name='partner_doc_upload'),
     path('partner/doc/<str:doc_code>', login_required(PartnerDocView.as_view()), name='partner_doc'),
+    path('partner/change_status/', change_partner_status, name='partner/change_status'),
+    
+    #Набор страниц по модели Ресурс
+    path('resources/', login_required(ResourcesListView.as_view()), name='resources'),
+    #path('resource/<str:pk>', login_required(ResourceDetailView.as_view()), name='resource_detail'),
+#    path('resource/edit/<int:pk>', login_required(ResourceEditView.as_view()), name='resource_edit'),
+#    path('resource/doc/<str:doc_code>/upload', login_required(ResourceDocUploadView.as_view()),
+#         name='partner_doc_upload'),
+#    path('resource/doc/<str:doc_code>', login_required(ResourceDocView.as_view()), name='resource_doc'),
+    path('resource/change_status/', change_resource_status, name='resource/change_status'),
 
-    path('partners/', login_required(PartnersListView.as_view()), name='partners'),
-
-    path('resource/', login_required(ResourceListView.as_view()), name='resource'),
-
-    path('provider/', login_required(ProviderListView.as_view()), name='provider'),
+    #Набор страниц по модели Исполнитель
+    path('providers/', login_required(ProvidersListView.as_view()), name='providers'),
+    #path('provider/<str:pk>', login_required(ProviderDetailView.as_view()), name='provider_detail'),
+#    path('provider/edit/<int:pk>', login_required(ProviderEditView.as_view()), name='provider_edit'),
+#    path('provider/doc/<str:doc_code>/upload', login_required(ProviderDocUploadView.as_view()),
+#         name='partner_doc_upload'),
+#    path('provider/doc/<str:doc_code>', login_required(ProviderDocView.as_view()), name='provider_doc'),
+    path('provider/change_status/', change_provider_status, name='provider/change_status'),
 
-    path('service_tariff/', login_required(ServiceTariffListView.as_view()), name='service_tariff'),
+    path('service_tariffs/', login_required(ServiceTariffsListView.as_view()), name='service_tariffs'),
+    #path('service_tariff/<int:pk>', login_required(ServiceTariffDetailView.as_view()), name='service_tariff_detail'),
     path('service_tariff/add/', login_required(ServiceTariffCreate.as_view()), name='service_tariff/add/'),
     path('service_tariff/edit/<int:pk>', login_required(ServiceTariffUpdateView.as_view()),
          name='service_tariff/edit/'),
+    path('service_tariff/change_status/', change_service_status, name='service_tariff/change_status'),
 
-    path('service_category/', login_required(ServiceCategoryListView.as_view()), name='service_category'),
+    path('service_categories/', login_required(ServiceCategoriesListView.as_view()), name='service_categories'),
+    #path('service_category/<int:pk>', login_required(ServiceCategoryDetailView.as_view()), name='service_category'),
     path('service_category/edit/<int:pk>', login_required(ServiceCategoryUpdateView.as_view()), name='service_category/edit/'),
     path('service_category/add/', login_required(ServiceCategoryCreate.as_view()), name='service_category/add/'),
     path('service_category/delete/<int:pk>', login_required(ServiceCategoryDelete.as_view()), name='service_category/delete/'),
+    path('service_category/change_status/', change_service_status, name='service_category/change_status'),
+
+#CHECK Maybe obsolete
+    #path('service_information/add/', login_required(ServiceInformationCreate.as_view()),
+    #     name='service_information-add'),
+    #path('service_information/edit/<int:pk>', login_required(ServiceInformationUpdateView.as_view()),
+    #     name='service_information/edit/'),
+
+    #path('service/', ServiceListView.as_view(), name='service'),
 
-    path('service_information/add/', login_required(ServiceInformationCreate.as_view()),
-         name='service_information-add'),
-    path('service_information/edit/<int:pk>', login_required(ServiceInformationUpdateView.as_view()),
-         name='service_information/edit/'),
+#TODO - take from platform
+    path('access-control', login_required(AccessControlListView.as_view()), name='access_control'),
+#    path('access_control/change_status/', change_access_status, name='access_control/change_status'),
+#    path('relationship', login_required(RelationshipListView.as_view()), name='relationship'),    
+#    path('relationship/change_status/', change_access_status, name='relationship/change_status'),
+#    path('active_users', login_required(ActiveUsersListView.as_view()), name='active_users'),
+#    path('active_users/change_status/', change_access_status, name='active_users/change_status'),
+#    path('changelog', login_required(ChangelogListView.as_view()), name='changelog'),
+#    path('closing-documents', login_required(ClosingDocumentsListView.as_view()), name='closing_documents'),
 
-    path('service/', ServiceListView.as_view(), name='service'),
 
+#TODO - check what is better
     # path('partner_information/', login_required(PartnerInfoView.as_view()), name='partner_information/'),
     # path('partner_information/add/', login_required(PartnerInformationCreate.as_view()), name='partner_information/add/'),
     # path('partner_information/edit/<int:pk>', login_required(PartnerInformationUpdateView.as_view()), name='partner_information/edit/'),
 
-    path('user_information', login_required(UserListView.as_view()), name='user_information'),
+    #path('user_information', login_required(UserListView.as_view()), name='user_information'),
 
     # TODO: Посмотреть, может тоже нужно переместить
     path('senderphone/', PhoneSender.as_view()),
@@ -87,11 +122,6 @@ urlpatterns = [
     path('transactions/<int:trans_id>/', trans_id, name='transid'),
     path('balance/', balance, name='balance'),
 
-    path('partners/change_status/', change_partners_status, name='partners/change_status'),
-    path('resource/change_status/', change_resource_status, name='resource/change_status'),
-    path('provider/change_status/', change_provider_status, name='provider/change_status'),
-    path('service/change_status/', change_service_status, name='service/change_status'),
-
     path('api/v1/auth/', include('djoser.urls.authtoken'), name="api-auth"),
     path('api/v1/platform/', include(router.urls), name="api-platform"),
     path('by_phone/<phone_number>/', get_user_by_phone_number, name='get_user_by_phone_number'),

+ 1 - 0
sharix_admin/views/__init__.py

@@ -2,6 +2,7 @@ from .auth import *
 from .balance import *
 from .cooperate import *
 from .get_userid import *
+from .staff import *
 from .main import *
 from .partner import *
 from .partner_info import *

+ 91 - 2
sharix_admin/views/cooperate.py

@@ -12,10 +12,15 @@ from sharix_admin.utils import *
 from dbsynce.lib.data import *
 from .base import BaseView
 
+from dbsynce.lib.ticket_gen import *
+from datetime import datetime, timedelta
+from sharix_admin.forms import JobRequestPartnerForm
+from sharix_admin.forms import JobRequestMetaserviceForm
+
 
 class CooperateView(BaseView, FormView):
     form_class = CompanyForm
-    template_name = "sharix_admin/cooperate.html"
+    template_name = "sharix_admin/requests/cooperate.html"
     success_url = reverse_lazy("sharix_admin:main")
     page_title = 'Сотрудничество'
     page_name = 'cooperate'
@@ -40,7 +45,23 @@ class CooperateView(BaseView, FormView):
             instance.ticket_status = create_ticket_company_activation(self.request.user, instance)
 
             # Создание тикета на утверждение прав пользователя
-            create_ticket_role_activation_partner_admin(self.request.user, instance)
+
+            Permissions.objects.create(
+                id_permissions=permissions_type["partner_admin"],
+                check_level=permissions_type["metaservice_admin"],
+                status=activity_status["deactivated"],
+                ticket_status=create_ticket_role_activation_partner_admin(self.request.user, instance)
+            )
+
+            Relationship.objects.create(
+                user_who=get_user_model().objects.filter(groups__name='METASERVICE-ADMIN').first(),
+                user_whom=self.request.user,
+                neg_type=neg_type["contract"],
+                #проверить корректность requirements
+                requirements="DS01y04y05y06y07yMPUCS13MPUB",
+                status=activity_status["deactivated"],
+                ticket_status=create_ticket_contract_with_metaservice(self.request.user, instance)
+            )
 
             # Сохраняем новые изменения
             instance.save()
@@ -63,3 +84,71 @@ class CooperateView(BaseView, FormView):
         )
 
         return super().form_valid(form)  # Возвращаем успешный ответ
+
+
+class JobRequestMetaserviceView(BaseView, FormView):
+    form_class = JobRequestMetaserviceForm
+    template_name = "sharix_admin/requests/job_request.html"
+    success_url = reverse_lazy("sharix_admin:main")
+    page_title = 'Заявка на работу в Сервисе'
+    page_name = 'main'
+
+    #def test_func(self):
+    #FIXME! Check is not valid
+    #    return not Practice.objects.filter(created_by=self.request.user).exists()
+
+    def form_valid(self, form):
+        with transaction.atomic():
+            selected_roles = form.cleaned_data['multiple_choice_field_select']
+
+            if 'METASERVICE-SUPERVISOR' in selected_roles:
+                create_ticket_role_activation_metaservice_supervisor(self.request.user)
+            if 'METASERVICE-SUPPORT' in selected_roles:
+                create_ticket_role_activation_metaservice_support(self.request.user)
+            if 'METASERVICE-TECHSUPPORT' in selected_roles:
+                create_ticket_role_activation_metaservice_techsupport(self.request.user)
+
+        #send_notify_mail(
+        #    f'Новая заявка на прохождение практики ({instance.created_by})',
+        #    "sharix_admin/emails/team_request.html",
+        #    ["info@sharix-app.org"],
+        #    {"ticket": ticket}
+        #)
+
+        messages.success(self.request, 'Ваша заявка успешно отправлена и теперь проходит проверку!')
+        return super().form_valid(form)
+
+class JobRequestPartnerView(BaseView, FormView):
+    form_class = JobRequestPartnerForm
+    template_name = "sharix_admin/requests/job_request.html"
+    success_url = reverse_lazy("sharix_admin:main")
+    #TODO FIXME! This page should be about particular partner!
+    page_title = 'Заявка на сотрудничество с Партнером Сервиса'
+    page_name = 'main'
+    
+    #def test_func(self):
+    #FIXME! Check is not valid
+    #    return not Practice.objects.filter(created_by=self.request.user).exists()
+    
+    def form_valid(self, form):
+        with transaction.atomic():
+            selected_roles = form.cleaned_data['multiple_choice_field_select']
+            
+            if 'PARTNER-SUPERVISOR' in selected_roles:
+                create_ticket_role_activation_partner_supervisor(self.request.user)
+            if 'PARTNER-SUPPORT' in selected_roles:
+                create_ticket_role_activation_partner_support(self.request.user)
+            if 'PARTNER-TECHSUPPORT' in selected_roles:
+                create_ticket_role_activation_partner_techsupport(self.request.user)    
+            if 'PROVIDER' in selected_roles:
+                create_ticket_role_activation_provider(self.request.user)
+                
+        #send_notify_mail(
+        #    f'Новая заявка на прохождение практики ({instance.created_by})',
+        #    "sharix_admin/emails/team_request.html",
+        #    ["info@sharix-app.org"],
+        #    {"ticket": ticket}
+        #)
+        
+        messages.success(self.request, 'Ваша заявка успешно отправлена и теперь проходит проверку!')
+        return super().form_valid(form)

+ 5 - 0
sharix_admin/views/main.py

@@ -8,3 +8,8 @@ class MainView(BaseView, TemplateView):
     page_title = 'Добро пожаловать!'
     page_name = 'main'
     template_name = 'sharix_admin/main.html'
+
+class SupportChatView(BaseView, TemplateView):
+    page_title = 'Добро пожаловать! Чат с техподдержкой'
+    page_name = 'support_chat'
+    template_name = 'sharix_admin/support_chat.html'

+ 25 - 0
sharix_admin/views/partner.py

@@ -11,6 +11,9 @@ from sharix_admin.forms import CompanyForm, DocumentUploadForm
 from sharix_admin.utils import *
 from .base import BaseView
 
+from django.contrib.auth.mixins import UserPassesTestMixin
+from django_tables2 import SingleTableView
+from sharix_admin.tables import PartnersTable
 
 class PartnerBaseView(BaseView):
     page_name = 'partner'
@@ -156,3 +159,25 @@ class PartnerDocView(PartnerBaseView, DetailView):
         doc_files = DocumentFile.objects.filter(document=self.doc)
         context.update({"doc_files": doc_files})
         return context
+
+
+class PartnersListView(UserPassesTestMixin, SingleTableView):
+    table_class = PartnersTable
+    queryset = Company.objects.all()
+    template_name = 'sharix_admin/service_tariffs.html'
+
+    def get_context_data(self, **kwargs):
+        context = super().get_context_data(**kwargs)
+        context.update(get_context(self.request, {
+            'title': _('Performers'),
+            'object_list': context['object_list'],
+        }))
+        return context
+
+    def test_func(self) -> bool or None:
+        group_names = ('PARTNER-ADMIN')
+        if bool(self.request.user.groups.filter(name=group_names)) or self.request.user.is_superuser:
+            return True
+        return False
+
+

+ 1 - 1
sharix_admin/views/partners.py

@@ -32,7 +32,7 @@ class PartnersListView(BaseView, SingleTableView):
 
 @login_required
 @group_required('METASERVICE-ADMIN')
-def change_partners_status(request):
+def change_partner_status(request):
     if request.method == 'POST':
         partners_id = request.POST.get('partners_id')
         new_status = request.POST.get('new_status')

+ 4 - 4
sharix_admin/views/provider.py

@@ -5,14 +5,14 @@ from django.http import JsonResponse
 from django.utils.translation import gettext as _
 from django_tables2 import SingleTableView
 
-from sharix_admin.tables import ProviderTable
+from sharix_admin.tables import ProvidersTable
 from sharix_admin.utils import group_required
 
 
-class ProviderListView(UserPassesTestMixin, SingleTableView):
-    table_class = ProviderTable
+class ProvidersListView(UserPassesTestMixin, SingleTableView):
+    table_class = ProvidersTable
     queryset = Provider.objects.all()
-    template_name = 'sharix_admin/provider.html'
+    template_name = 'sharix_admin/providers.html'
 
     def get_context_data(self, **kwargs):
         context = super().get_context_data(**kwargs)

+ 4 - 4
sharix_admin/views/resource.py

@@ -5,14 +5,14 @@ from django.http import JsonResponse
 from django.utils.translation import gettext as _
 from django_tables2 import SingleTableView
 
-from sharix_admin.tables import ResourceTable
+from sharix_admin.tables import ResourcesTable
 from sharix_admin.utils import group_required
 
 
-class ResourceListView(UserPassesTestMixin, SingleTableView):
-    table_class = ResourceTable
+class ResourcesListView(UserPassesTestMixin, SingleTableView):
+    table_class = ResourcesTable
     queryset = Resource.objects.all()
-    template_name = 'sharix_admin/resource.html'
+    template_name = 'sharix_admin/resources.html'
 
     def get_context_data(self, **kwargs):
         context = super().get_context_data(**kwargs)

+ 4 - 4
sharix_admin/views/service_category.py

@@ -5,7 +5,7 @@ from django.views.generic.edit import UpdateView, CreateView, DeleteView
 from django_tables2 import SingleTableView
 
 from sharix_admin.forms import ServiceCategoryCreateForm, ServiceCategoryUpdateForm
-from sharix_admin.tables import ServiceCategoryTable
+from sharix_admin.tables import ServiceCategoriesTable
 from .base import BaseView
 
 
@@ -33,12 +33,12 @@ class ServiceCategoryCreate(BaseView, CreateView):
         return False
 
 
-class ServiceCategoryListView(BaseView, SingleTableView):
+class ServiceCategoriesListView(BaseView, SingleTableView):
     page_title = _('Услуги сервиса')
     page_name = 'service_category'
-    table_class = ServiceCategoryTable
+    table_class = ServiceCategoriesTable
     queryset = ServiceCategory.objects.all()
-    template_name = 'sharix_admin/service_category.html'
+    template_name = 'sharix_admin/service_categories.html'
 
     def get_context_data(self, **kwargs):
         context = super().get_context_data(**kwargs)

+ 4 - 4
sharix_admin/views/service_tariff.py

@@ -6,7 +6,7 @@ from django.views.generic.edit import UpdateView, CreateView
 from django_tables2 import SingleTableView
 
 from sharix_admin.forms import ServiceTariffCreateForm, ServiceTariffUpdateForm
-from sharix_admin.tables import ServiceTariffTable
+from sharix_admin.tables import ServiceTariffsTable
 
 
 class ServiceTariffCreate(UserPassesTestMixin, CreateView):
@@ -32,10 +32,10 @@ class ServiceTariffCreate(UserPassesTestMixin, CreateView):
         return False
 
 
-class ServiceTariffListView(UserPassesTestMixin, SingleTableView):
-    table_class = ServiceTariffTable
+class ServiceTariffsListView(UserPassesTestMixin, SingleTableView):
+    table_class = ServiceTariffsTable
     queryset = Service.objects.all()
-    template_name = 'sharix_admin/service_tariff.html'
+    template_name = 'sharix_admin/service_tariffs.html'
 
     def get_context_data(self, **kwargs):
         context = super().get_context_data(**kwargs)

+ 82 - 0
sharix_admin/views/staff.py

@@ -0,0 +1,82 @@
+from dbsynce.models import Company
+from dbsynce.models import Relationship
+from dbsynce.models import Permissions
+
+
+from django.contrib.auth.decorators import login_required
+from django.http import JsonResponse
+from django.utils.translation import gettext as _
+from django_tables2 import SingleTableView
+from django.views.generic import TemplateView, DetailView
+
+from sharix_admin.tables import PartnersTable
+from sharix_admin.tables import PermissionsTable
+from sharix_admin.tables import RelationshipTable
+from sharix_admin.utils import group_required
+from .base import BaseView
+
+from django.contrib.auth import get_user_model
+from django.contrib.auth.mixins import UserPassesTestMixin
+from django.contrib.auth.models import Group
+from django.utils.translation import gettext as _
+
+
+
+#TODO This is abslutely incorrect, custom page needed!
+class AccessControlListView(UserPassesTestMixin, SingleTableView):
+    table_class = PermissionsTable
+    queryset = Permissions.objects.all()
+    template_name = 'sharix_admin/staff/access_control.html'
+
+    def get_context_data(self, **kwargs):
+        context = super().get_context_data(**kwargs)
+        context.update({
+            'title': _('User roles Management'),
+            'object_list': context['object_list'],
+            'groups': Group.objects.all()
+        })
+        return context
+
+    def test_func(self) -> bool or None:
+        group_names = ('PLATFORM-ADMIN')
+        if bool(self.request.user.groups.filter(name=group_names)) or self.request.user.is_superuser:
+            return True
+        return False
+
+class RelationshipListView(BaseView, SingleTableView):
+    page_title = _('Relationship')
+    page_name = 'relationship'
+    table_class = RelationshipTable
+    queryset = Relationship.objects.all()
+    template_name = 'sharix_admin/staff/relationship.html'
+
+    def get_context_data(self, **kwargs):
+        context = super().get_context_data(**kwargs)
+        context.update({
+            'object_list': context['object_list'],
+        })
+        return context
+
+    def test_func(self):
+        group_names = ('PLATFORM-ADMIN')
+        if bool(self.request.user.groups.filter(name=group_names)) or self.request.user.is_superuser:
+            return True
+        return False
+
+
+@login_required
+@group_required('PLATFORM-ADMIN')
+def change_relationship_status(request):
+    if request.method == 'POST':
+        relationship_id = request.POST.get('relationship')
+        new_status = request.POST.get('new_status')
+        relationship = SXRelationship.objects.get(pk=relationship)
+        relationship.status = new_status
+        relationship.save()
+        return JsonResponse({'status': 'success'})
+    else:
+        return JsonResponse({'status': 'error'})
+
+
+
+