Эх сурвалжийг харах

Merge branch 'master' into unstable

blezz-tech 10 цаг өмнө
parent
commit
c0e319568b
41 өөрчлөгдсөн 2820 нэмэгдсэн , 617 устгасан
  1. 2 0
      sharix_admin/forms/__init__.py
  2. 37 0
      sharix_admin/forms/order.py
  3. 17 0
      sharix_admin/forms/resource.py
  4. 131 35
      sharix_admin/forms/service.py
  5. 1 0
      sharix_admin/lib/__init__.py
  6. 203 0
      sharix_admin/lib/menu.py
  7. BIN
      sharix_admin/locale/ru/LC_MESSAGES/django.mo
  8. 1 1
      sharix_admin/locale/ru/LC_MESSAGES/django.po
  9. 35 0
      sharix_admin/static/sharix_admin/css/base.css
  10. 146 17
      sharix_admin/tables.py
  11. 13 392
      sharix_admin/templates/sharix_admin/base_admin.html
  12. 465 0
      sharix_admin/templates/sharix_admin/base_admin_menu.html
  13. 461 0
      sharix_admin/templates/sharix_admin/base_admin_old_example.html
  14. 12 0
      sharix_admin/templates/sharix_admin/orders.html
  15. 21 2
      sharix_admin/templates/sharix_admin/partners.html
  16. 23 0
      sharix_admin/templates/sharix_admin/provider_form.html
  17. 29 2
      sharix_admin/templates/sharix_admin/providers.html
  18. 9 0
      sharix_admin/templates/sharix_admin/resource.html
  19. 81 0
      sharix_admin/templates/sharix_admin/resource_list.html
  20. 0 40
      sharix_admin/templates/sharix_admin/resources.html
  21. 57 6
      sharix_admin/templates/sharix_admin/service_categories.html
  22. 0 3
      sharix_admin/templates/sharix_admin/service_category_form.html
  23. 0 1
      sharix_admin/templates/sharix_admin/service_tariff_form.html
  24. 57 6
      sharix_admin/templates/sharix_admin/service_tariffs.html
  25. 62 1
      sharix_admin/templates/sharix_admin/staff/access_control.html
  26. 26 17
      sharix_admin/urls.py
  27. 5 4
      sharix_admin/views/__init__.py
  28. 4 1
      sharix_admin/views/base.py
  29. 4 0
      sharix_admin/views/cooperate.py
  30. 2 2
      sharix_admin/views/depr_partner_info.py
  31. 1 1
      sharix_admin/views/depr_partners.py
  32. 0 0
      sharix_admin/views/depr_service_info.py
  33. 3 3
      sharix_admin/views/depr_service_tariff.py
  34. 140 0
      sharix_admin/views/order.py
  35. 58 9
      sharix_admin/views/partner.py
  36. 99 6
      sharix_admin/views/provider.py
  37. 139 6
      sharix_admin/views/resource.py
  38. 195 5
      sharix_admin/views/service.py
  39. 193 51
      sharix_admin/views/service_category.py
  40. 44 6
      sharix_admin/views/staff.py
  41. 44 0
      sharix_admin/views/user_info.py

+ 2 - 0
sharix_admin/forms/__init__.py

@@ -4,3 +4,5 @@ from .company import *
 from .job_request import *
 from .document import *
 from .service import *
+from .resource import *
+from .order import *

+ 37 - 0
sharix_admin/forms/order.py

@@ -0,0 +1,37 @@
+from django import forms
+from dbsynce.models import Orders
+
+class OrderForm(forms.ModelForm):
+    def __init__(self, *args, **kwargs):
+        super(ResourceForm, self).__init__(*args, **kwargs)
+        # Добавляем класс .form-control для всех полей формы
+        for field in iter(self.fields):
+            if 'class' not in self.fields[field].widget.attrs:
+                self.fields[field].widget.attrs.update({'class': 'form-control'})
+                
+    class Meta:
+        model = Orders
+        fields = [
+            'status', 'title', 'note', 'time_placed', 'time_start', 'time_start_real',
+            'time_start_predicted', 'time_finish_real', 'time_finish_predicted',
+            'real_price', 'predicted_price', 'asap', 'ticket', 'service',
+            'service_category', 'client', 'provider', 'receiver', 'company'
+        ]
+        widgets = {
+            'time_placed': forms.DateTimeInput(attrs={'type': 'datetime-local'}),
+            'time_start': forms.DateTimeInput(attrs={'type': 'datetime-local'}),
+            'time_start_real': forms.DateTimeInput(attrs={'type': 'datetime-local'}),
+            'time_start_predicted': forms.DateTimeInput(attrs={'type': 'datetime-local'}),
+            'time_finish_real': forms.DateTimeInput(attrs={'type': 'datetime-local'}),
+            'time_finish_predicted': forms.DateTimeInput(attrs={'type': 'datetime-local'}),
+        }
+
+    def __init__(self, *args, **kwargs):
+        super().__init__(*args, **kwargs)
+        self.fields['receiver'].queryset = get_user_model().objects.all()
+        self.fields['client'].queryset = Client.objects.all()
+        self.fields['company'].queryset = Company.objects.all()
+        self.fields['provider'].queryset = Provider.objects.all()
+        self.fields['service'].queryset = Service.objects.all()
+        self.fields['service_category'].queryset = ServiceCategory.objects.all()
+        self.fields['ticket'].queryset = Ticket.objects.all()

+ 17 - 0
sharix_admin/forms/resource.py

@@ -0,0 +1,17 @@
+from dbsynce.models import Resource
+from django import forms
+
+
+class ResourceForm(forms.ModelForm):
+    def __init__(self, *args, **kwargs):
+        super(ResourceForm, self).__init__(*args, **kwargs)
+        # Добавляем класс .form-control для всех полей формы
+        for field in iter(self.fields):
+            if 'class' not in self.fields[field].widget.attrs:
+                self.fields[field].widget.attrs.update({'class': 'form-control'})
+
+    class Meta:
+        model = Resource
+        fields = [
+            'resource_type'
+        ]

+ 131 - 35
sharix_admin/forms/service.py

@@ -1,6 +1,18 @@
-from dbsynce.models import ServiceCategory, Service, Company
+from dbsynce.models import ServiceCategory
+from dbsynce.models import Service
+from dbsynce.models import Company
+from dbsynce.models import Provider
 from django import forms
+from sharix_admin.forms import BaseForm
 
+#RESOURCE_TYPE_CHOICES = [
+#    ('1', 'Только время'),
+#    ('2', 'Только расстояние'),
+#    ('3', 'За единицу услуги'),
+#    ('4', 'Время за расстояние'),
+#    ('5', 'Единицы за расстояние'),
+#    ('6', 'Единицы за время'),
+#]
 
 class ServiceTariffUpdateForm(forms.ModelForm):
     def __init__(self, *args, **kwargs):
@@ -12,15 +24,18 @@ class ServiceTariffUpdateForm(forms.ModelForm):
                 self.fields[field].widget.attrs.update({'class': 'form-control'})
 
     class Meta:
-
         model = Service
         fields = [
-            'status',
-            'ticket_status',
+            #'status',
+            #'ticket_status',
             'service_category',
-            'resource',
             'requirements',
-            'price_type',
+            'company_comission',
+            'codename',
+            'caption',
+            'description',
+            'resource_type',
+#            'price_type',
             'price_km',
             'price_min',
             'price_amount',
@@ -30,13 +45,28 @@ class ServiceTariffUpdateForm(forms.ModelForm):
         widgets = {
             'status': forms.TextInput(attrs={'readonly': True}, ),
             'ticket_status': forms.TextInput(attrs={'readonly': True}),
+            'requirements': forms.TextInput(attrs={'readonly': True}),
+            'resource_type': forms.TextInput(attrs={'readonly': True}),
+#            'price_type': forms.TextInput(attrs={'readonly': True}),
 
-            'service_category': forms.Select(attrs={'class': 'form-select'}),
-            'resource': forms.Select(attrs={'class': 'form-select'}),
+            'service_category': forms.Select(attrs={'class': 'form-select', 'readonly': True}),
+            #'resource': forms.Select(attrs={'class': 'form-select'}),
         }
 
 
 class ServiceTariffCreateForm(forms.ModelForm):
+    company_comission = forms.FloatField(label="Комиссия Партнера")
+    resource_type = forms.CharField(label="Необходимый тип ресурса")
+    #resource_type = forms.ChoiceField(choices=RESOURCE_TYPE_CHOICES, label="Необходимый тип ресурса")
+    codename = forms.CharField(label="Кодовое короткое название тарифа услуги")
+    caption = forms.CharField(label="Название тарифа услуги")
+    #requirements = forms.CharField(label="Требования")
+    #price_type = forms.ChoiceField(choices=PRICE_CHOICES, label="Ценообразование")
+    description = forms.CharField(label="Описание")
+
+#    is_global = forms.BooleanField(label="Доступно во всех сервисах", required=False)
+#    is_visible = forms.BooleanField(label="Доступно для планирования цепочек во всех сервисах", required=False)
+
     def __init__(self, *args, **kwargs):
         super(ServiceTariffCreateForm, self).__init__(*args, **kwargs)
         # Добавляет стиль бутстрапа form-control всем полям таблицы если у них нет своих стилей
@@ -47,53 +77,73 @@ class ServiceTariffCreateForm(forms.ModelForm):
     class Meta:
 
         model = Service
-        fields = '__all__'
+        #fields = '__all__'
+        fields = [
+            'service_category',
+            'company_comission',
+            'codename',
+            'caption',
+            'description',
+            'resource_type',
+        ]
+
+        #company - использовать ту, у которой сейчас отображаются услуги
+        #resource - показывать только те, которые имеют отношение к компании
 
         widgets = {
             'service_category': forms.Select(attrs={'class': 'form-select'}),
-            'resource': forms.Select(attrs={'class': 'form-select'}),
+            #'resource': forms.Select(attrs={'class': 'form-select'}),
             'ticket_status': forms.TextInput(attrs={'readonly': True}),
         }
 
+#TODO Merge with dicts!
+PRICE_CHOICES = [
+    ('1', 'Только время'),
+    ('2', 'Только расстояние'),
+    ('3', 'За единицу услуги'),
+    ('4', 'Время за расстояние'),
+    ('5', 'Единицы за расстояние'),
+    ('6', 'Единицы за время'),
+]
+
+
+class ServiceCategoryUpdateForm(BaseForm, forms.ModelForm):
+    price_type = forms.ChoiceField(choices=PRICE_CHOICES, label="Ценообразование")
 
-class ServiceCategoryUpdateForm(forms.ModelForm):
     def __init__(self, *args, **kwargs):
         super(ServiceCategoryUpdateForm, self).__init__(*args, **kwargs)
 
     class Meta:
         model = ServiceCategory
         fields = [
-            'status',
-            'ticket_status',
-            'id_metaservice',
+            #'status',
+            #'ticket_status',
+            #'id_metaservice',
             'codename',
+            'caption',
             'description',
-            'requirements',
+            #'requirements',
             'price_type',
             'link_agreement',
             'is_global',
             'is_visible'
         ]
-        widgets = {
-            'status': forms.TextInput(attrs={'readonly': True}),
-            'ticket_status': forms.TextInput(attrs={'readonly': True}),
-        }
+        #widgets = {
+        #    'status': forms.TextInput(attrs={'readonly': True}),
+        #    'ticket_status': forms.TextInput(attrs={'readonly': True}),
+        #}
 
 
-PRICE_CHOICES = [
-    ('one', 'text #1'),
-    ('two', 'text #2'),
-    ('three', 'text #3'),
-]
-
-
-class ServiceCategoryCreateForm(forms.ModelForm):
-    codename = forms.CharField(label="Название услуги")
-    requirements = forms.CharField(label="Требования")
+class ServiceCategoryCreateForm(BaseForm, forms.ModelForm):
+    codename = forms.CharField(label="Кодовое короткое название услуги")
+    caption = forms.CharField(label="Название услуги")
+    #requirements = forms.CharField(label="Требования")
     price_type = forms.ChoiceField(choices=PRICE_CHOICES, label="Ценообразование")
     description = forms.CharField(label="Описание")
-    is_global = forms.BooleanField(label="Доступно во всех сервисах", required=False)
-    is_visible = forms.BooleanField(label="Доступно для планирования цепочек во всех сервисах", required=False)
+    link_agreement = forms.CharField(label="Ссылка на договор-оферту")
+    metaservice_comission = forms.FloatField(label="Комиссия Сервиса")
+#    is_global = forms.BooleanField(label="Доступно во всех сервисах", required=False)
+#    is_visible = forms.BooleanField(label="Доступно для планирования цепочек во всех сервисах", required=False)
 
     def __init__(self, *args, **kwargs):
         super(ServiceCategoryCreateForm, self).__init__(*args, **kwargs)
@@ -102,11 +152,14 @@ class ServiceCategoryCreateForm(forms.ModelForm):
         model = ServiceCategory
         fields = [
             'codename',
-            'requirements',
+            'caption',
+            #'requirements',
             'price_type',
             'description',
-            'is_global',
-            'is_visible',
+            'link_agreement',
+            'metaservice_comission',
+ #           'is_global',
+ #           'is_visible',
         ]
 
         widgets = {
@@ -114,7 +167,7 @@ class ServiceCategoryCreateForm(forms.ModelForm):
         }
 
 
-class ServiceInformationUpdateForm(forms.ModelForm):
+class ServiceInformationUpdateForm(BaseForm, forms.ModelForm):
 
     def __init__(self, *args, **kwargs):
         super(ServiceInformationUpdateForm, self).__init__(*args, **kwargs)
@@ -222,3 +275,46 @@ class PartnerInformationCreateForm(forms.ModelForm):
 
         #     username = forms.CharField(label="Номер телефона",
         # widget=forms.TextInput(attrs={'class':'form-control'}))
+
+
+class ProviderCreateForm(forms.ModelForm):
+    gap = forms.CharField(label="Промежуток времени до готовности приступить к выполнению")
+    #gap = forms.DateTimeField(label="Промежуток времени до готовности приступить к выполнению")
+    location_type = forms.CharField(label="Способ отображения геолокации")
+    default_location = forms.CharField(label="Геолокация по умолчанию")
+    #resource_type = forms.ChoiceField(choices=RESOURCE_TYPE_CHOICES, label="Необходимый тип ресурса")
+    #requirements = forms.CharField(label="Требования")
+
+#    is_global = forms.BooleanField(label="Доступно во всех сервисах", required=False)
+#    is_visible = forms.BooleanField(label="Доступно для планирования цепочек во всех сервисах", required=False)
+
+    def __init__(self, *args, **kwargs):
+        super(ProviderCreateForm, self).__init__(*args, **kwargs)
+        # Добавляет стиль бутстрапа form-control всем полям таблицы если у них нет своих стилей
+        for field in iter(self.fields):
+            if 'class' not in self.fields[field].widget.attrs:
+                self.fields[field].widget.attrs.update({'class': 'form-control'})
+
+    class Meta:
+
+        model = Provider
+        #fields = '__all__'
+        fields = [
+            'gap',
+            'location_type',
+            'default_location',
+            'service',
+            'resource',
+        ]
+
+        #company - использовать ту, у которой сейчас отображаются услуги
+        #resource - показывать только те, которые имеют отношение к компании
+
+        widgets = {
+            'service': forms.Select(attrs={'class': 'form-select'}),
+            'resource': forms.Select(attrs={'class': 'form-select'}),
+            #'resource': forms.Select(attrs={'class': 'form-select'}),
+            #'ticket_status': forms.TextInput(attrs={'readonly': True}),
+        }
+
+

+ 1 - 0
sharix_admin/lib/__init__.py

@@ -0,0 +1 @@
+from .menu import *

+ 203 - 0
sharix_admin/lib/menu.py

@@ -0,0 +1,203 @@
+from webservice_running.lib.menu import *
+from webservice_running.lib.menu import MENU_SCHEME_LIST
+
+#Same idea as vvv, maybe some custom pages for example for reports later 
+METASERVICE_ADMIN_ALL = ['partners', 'orders', 'access_control', 'resources', 'providers']
+#note: delete 'delete' operation from urlpatterns! Question - should be edit and change status apart or not?
+METASERVICE_ADMIN_OPERATIONS = ['service_category/add', 'service_category/edit', 'service_category/change_status']
+#TODO - page to add money to client balance manually based on manual b2b payments! And add logic connected to platform if possible later. 2 balances - platform and manual local.
+#Add pages similar to platform's for payment reports for manual payments.
+
+METASERVICE_SUPERVISOR_ALL = ['partners', 'resources', 'providers', 'orders', 'access_control']
+
+METASERVICE_SUPPORT_ALL = ['partners', 'resources', 'providers', 'orders', 'orders/edit']
+METASERVICE_TECHSUPPORT_ALL = ['partners', 'resources', 'providers']
+
+#LOCAL - same idea except access_control that is only in open by default
+PARTNER_ADMIN_MY = ['resources', 'providers', 'access_control']
+PARTNER_ADMIN_OPERATIONS = ['service_tariff/add', 'service_tariff/edit', 'service_tariff/change_status']
+
+PARTNER_SUPERVISOR_MY = ['resources', 'providers', 'access_control']
+
+PARTNER_SUPPORT_MY = ['resources', 'providers', 'orders', 'orders/edit']
+PARTNER_TECHSUPPORT_MY = ['resources', 'providers']
+
+#LOCAL - same idea +local
+#CHECK Documentation - it seems provider should be able to add service_tariffs that he want to appy to himself based on partner's restrictions
+#order change_status or edit - based on handlers logic. Provider should be able to tell system he wants to process the order or customize it
+PROVIDER_MY_OPERATIONS = ['resource/add', 'resource/edit', 'resource', 'order/change_status']
+PROVIDER_MY = ['resources', 'orders']
+#on partners page provider might make a connection with another partner - does that mean PARTNERS list should be in ALL category?
+
+CLIENT_MY = ['order', 'orders']
+CLIENT_MY_OPERATIONS = ['order/edit', 'order/add']
+#TODO should be something for transactions
+
+#READ MENU DESCRIPTION STARTS HERE!!! vvv
+#Idea - Menu categories
+
+#GLOBAL_MENU - same for all users, info on forms may vary according to roles, but view is one for all
+#MENU_GLOBAL = ['service_categories', 'support_chat', 'job_request_metaservice']
+MENU_GLOBAL = ['tickets_list_list', 'service_categories', 'support_chat', 'job_request_metaservice']
+MENU_OPEN = ['main', 'service_tariffs', 'cooperate_request']
+
+#Thus menu points for all staff roles is the same
+STAFF_METASERVICE_MENU_GLOBAL = ['access_control', 'relationship', 'partners']
+STAFF_METASERVICE_MENU_OPEN = ['resources', 'providers', 'orders']
+#Another set of pages that lists only MY PARTNER objects - needed for the situation for users with multiple roles. For each Partner connection - same set of pages, maybe it's good idea to hide it
+STAFF_MY_PARTNER_MENU_GLOBAL = ['access_control', 'partners']
+STAFF_MY_PARTNER_MENU_OPEN = ['resources', 'providers', 'orders']
+
+STAFF_MY_PROVIDER_MENU_OPEN = ['resources', 'orders']
+
+CLIENT_MY_MENU_GLOBAL = ['transactions']
+CLIENT_MY_MENU_OPEN = ['orders']
+
+
+#3 variants to show customizable pages, it depends on settings of a project ALL (PURE), ALL + CUSTOMIZABLE (REPLACE) replaced, ALL + CUSTOMIZABLE added (APPEND)
+#function to check if menu should be visible:
+# function that get roles by userid
+
+STAFF_METASERVICE_ROLES = ['METASERVICE-ADMIN', 'METASERVICE-SUPERVISOR', 'METASERVICE-SUPPORT', 'METASERVICE-TECHSUPPORT']
+STAFF_PARTNER_ROLES = ['PARTNER-ADMIN', 'PARTNER-SUPERVISOR', 'PARTNER-SUPPORT', 'PARTNER-TECHSUPPORT', 'PROVIDER']
+CLIENT_ROLES = ['CLIENT']
+
+#if user role in list provided and page name in a connected list then menu item is visible
+#so we have to know user_id and page type and MENU_ALG algorythm
+
+MENU_ALG = 'APPEND'
+global visible_pages
+visible_pages = []
+
+if MENU_ALG == 'PURE':
+    visible_pages.extend(MENU_GLOBAL)
+    visible_pages.extend(MENU_OPEN)
+    
+if MENU_ALG == 'REPLACE':
+    visible_pages.extend(MENU_GLOBAL)
+    visible_pages.extend(MENU_GLOBAL_CUSTOMIZABLE)
+    
+if MENU_ALG == 'APPEND':
+    visible_pages.extend(MENU_GLOBAL)
+    visible_pages.extend(MENU_GLOBAL_CUSTOMIZABLE)
+    visible_pages.extend(MENU_OPEN)
+
+#TODO - change menu template to FOR loop with parameters - name, link, icon
+# menu structure should base on config file with menu structure as settings
+
+MENU_SCHEME = True
+
+MENU_SCHEME_LIST_OPEN = {
+    'main': ['sharix_admin', 'house', 'Главная'],
+    'service_categories': ['sharix_admin', 'briefcase', 'Категории услуг'],
+    'service_tariffs': ['sharix_admin', 'briefcase', 'Тарифы'],
+    'partners': ['sharix_admin', 'handshake', 'Партнеры'],
+    'resources': ['sharix_admin', 'hdd-network', 'Ресурсы'],
+    'providers': ['sharix_admin', 'person', 'Исполнители'],
+    'orders': ['sharix_admin', 'clock-history', 'Заказы'],
+    'access_control': ['sharix_admin', 'hdd-network', 'Права доступа'],
+    'tickets_list_list': ['tickets', 'tickets', 'Заявки'],
+    'support_chat': ['sharix_admin', 'tickets', 'Чат техподдержки'],
+    'job_request_metaservice': ['sharix_admin', 'credit-card', 'Вакансии'],
+    'cooperate_request': ['sharix_admin', 'credit-card', 'Стать партнером'],
+    }
+
+
+def gen_avaliable_pages(roles):
+#any(x in role for x in STAFF_METASERVICE_ROLES):
+    #global visible_pages
+    global MENU_SCHEME_LIST
+
+    visible_pages = []
+
+    if MENU_ALG == 'PURE':
+        visible_pages.extend(MENU_GLOBAL)
+        visible_pages.extend(MENU_OPEN)
+
+    if MENU_ALG == 'REPLACE':
+        visible_pages.extend(MENU_GLOBAL)
+        visible_pages.extend(MENU_GLOBAL_CUSTOMIZABLE)
+
+    if MENU_ALG == 'APPEND':
+        visible_pages.extend(MENU_GLOBAL)
+        visible_pages.extend(MENU_GLOBAL_CUSTOMIZABLE)
+        visible_pages.extend(MENU_OPEN)
+
+
+    if any(x in roles for x in STAFF_METASERVICE_ROLES):
+        if MENU_ALG == 'PURE':
+            visible_pages.extend(STAFF_METASERVICE_MENU_GLOBAL)
+            visible_pages.extend(STAFF_METASERVICE_MENU_OPEN)
+
+        if MENU_ALG == 'REPLACE':
+            visible_pages.extend(STAFF_METASERVICE_MENU_GLOBAL)
+            visible_pages.extend(STAFF_METASERVICE_MENU_CUSTOMIZABLE)
+        if MENU_ALG == 'APPEND':
+            visible_pages.extend(STAFF_METASERVICE_MENU_GLOBAL)
+            visible_pages.extend(STAFF_METASERVICE_MENU_CUSTOMIZABLE)
+            visible_pages.extend(STAFF_METASERVICE_MENU_OPEN)
+
+    if any(x in roles for x in STAFF_PARTNER_ROLES):
+#if role in STAFF_PARTNER_ROLES:
+        if MENU_ALG == 'PURE':
+            visible_pages.extend(STAFF_MY_PARTNER_MENU_GLOBAL)
+            visible_pages.extend(STAFF_MY_PARTNER_MENU_OPEN)
+            visible_pages.extend(STAFF_MY_PROVIDER_MENU_OPEN)
+
+        if MENU_ALG == 'REPLACE':
+            visible_pages.extend(STAFF_MY_PARTNER_MENU_GLOBAL)
+            visible_pages.extend(STAFF_MY_PARTNER_MENU_CUSTOMIZABLE)
+            visible_pages.extend(STAFF_MY_PROVIDER_MENU_CUSTOMIZABLE)
+
+        if MENU_ALG == 'APPEND':
+            visible_pages.extend(STAFF_MY_PARTNER_MENU_GLOBAL)
+            visible_pages.extend(STAFF_MY_PARTNER_MENU_CUSTOMIZABLE)
+            visible_pages.extend(STAFF_MY_PARTNER_MENU_OPEN)
+            visible_pages.extend(STAFF_MY_PROVIDER_MENU_CUSTOMIZABLE)
+            visible_pages.extend(STAFF_MY_PROVIDER_MENU_OPEN)
+
+    if any(x in roles for x in CLIENT_ROLES):
+#if role in CLIENT_ROLES:
+        if MENU_ALG == 'PURE':
+            visible_pages.extend(CLIENT_MY_MENU_GLOBAL)
+            visible_pages.extend(CLIENT_MY_MENU_OPEN)
+    
+        if MENU_ALG == 'REPLACE':
+            visible_pages.extend(CLIENT_MY_MENU_GLOBAL)
+            visible_pages.extend(CLIENT_MY_MENU_CUSTOMIZABLE)
+            visible_pages.extend(WSR_EXTENDED)
+            visible_pages.extend(WSR_EXTENDED_MY)
+
+        if MENU_ALG == 'APPEND':
+            visible_pages.extend(CLIENT_MY_MENU_GLOBAL)
+            visible_pages.extend(CLIENT_MY_MENU_CUSTOMIZABLE)
+            visible_pages.extend(CLIENT_MY_MENU_OPEN)
+            visible_pages.extend(WSR_EXTENDED)
+            visible_pages.extend(WSR_EXTENDED_MY)
+    
+
+#MAYBE REMOVE DUPLICATES?
+    visible_pages = list(dict.fromkeys(visible_pages))
+
+    menu_result = []
+    if not MENU_SCHEME:
+        MENU_SCHEME_LIST=MENU_SCHEME_LIST_OPEN
+
+    for key, value in MENU_SCHEME_LIST.items():
+        if key in visible_pages:
+            menu_item=[]
+            menu_item.append(value[0]+':'+key)
+            menu_item=menu_item+value
+            menu_result.append(menu_item)
+
+    #print (roles, menu_result)
+    return menu_result
+
+#gen_avaliable_pages('METASERVICE-ADMIN')
+#gen_avaliable_pages('METASERVICE-SUPERVISOR')
+#gen_avaliable_pages('METASERVICE-SUPPORT')
+#gen_avaliable_pages('PARTNER-ADMIN')
+#gen_avaliable_pages('PARTNER-SUPERVISOR')
+#gen_avaliable_pages('PARTNER-SUPPORT')
+#gen_avaliable_pages('PROVIDER')
+#gen_avaliable_pages('CLIENT')

BIN
sharix_admin/locale/ru/LC_MESSAGES/django.mo


+ 1 - 1
sharix_admin/locale/ru/LC_MESSAGES/django.po

@@ -47,7 +47,7 @@ msgstr "Успешно, не успешно"
 #: .\tables.py:30 .\tables.py:53 .\tables.py:73 .\tables.py:94 .\tables.py:117
 #: .\tables.py:139 .\tables.py:166
 msgid "ID"
-msgstr "ИД"
+msgstr ""
 
 #: .\tables.py:31
 msgid "Legal entity"

+ 35 - 0
sharix_admin/static/sharix_admin/css/base.css

@@ -222,6 +222,41 @@ a:hover {
     opacity: 0.5;
 }
 
+/* Table */
+
+.table {
+    border-collapse: collapse;
+    width: 100%;
+    border: 1px solid #E3E4E7; 
+    border-radius: 0.5rem; 
+}
+
+.table th,
+.table td {
+    border: 1px solid #E3E4E7; 
+    padding: 8px; 
+    text-align: left; 
+}
+
+.table th {
+    font-weight: bold; 
+}
+
+.table .status-toggle {
+    margin: 0; 
+}
+
+/* Active-button */
+
+.activation-btn img {
+    margin-right: 10px; 
+    cursor: pointer; 
+}
+
+.activation-btn:last-child img {
+    margin-right: 0; /* Убираем отступ для последней кнопки */
+}
+
 /* Drop files input */
 .drop-container {
     display: flex;

+ 146 - 17
sharix_admin/tables.py

@@ -144,6 +144,64 @@ class PartnersTable(tables.Table):
                 record.id
             )
 
+class OrdersTable(tables.Table):
+    id = tables.Column(
+        verbose_name=_('ID'),
+        attrs={
+                "td": {"width": "5%"}
+        }
+    )
+    title = tables.Column(
+        verbose_name=_('Title'), 
+        attrs={
+            "td": {"width": "20%"}
+        }
+    )
+    status = tables.Column(
+        verbose_name=_('Status'), 
+        attrs={
+            "td": {"width": "15%"}
+        }
+    )
+    receiver = tables.Column(
+        accessor='receiver.get_full_name',
+        verbose_name=_('Receiver'),
+        attrs={
+            "td": {"width": "20%"}
+        }
+    )
+    time_created = tables.DateTimeColumn(
+        verbose_name=_('Created'),
+        attrs={
+            "td": {"width": "20%"}
+        }
+    )
+
+    class Meta:
+        model = Orders
+        attrs = {
+            "class": "table table-layout-fixed"
+        }
+        exclude = (
+            'id_metaservice', 
+            'note', 
+            'time_placed', 
+            'time_start', 
+            'time_start_real', 
+            'time_start_predicted', 
+            'time_finish_real', 
+            'time_finish_predicted', 
+            'real_price', 
+            'predicted_price', 
+            'asap', 
+            'is_global', 
+            'is_visible', 
+            'ticket', 
+            'service', 
+            'service_category', 
+            'client', 
+            'provider', 
+            'company')
 
 class ResourcesTable(tables.Table):
     id = tables.Column(
@@ -154,7 +212,7 @@ class ResourcesTable(tables.Table):
     )
     # В user ссылка LinkColumn на страницу Аси "Информация о партнере" страница partner_information_form
     user = tables.Column(
-        accessor='user.full_name',
+        accessor='user.get_full_name',
         order_by=('user.first_name', 'user.last_name'),
         verbose_name=_('Responsible'),
         attrs={
@@ -172,7 +230,7 @@ class ResourcesTable(tables.Table):
         verbose_name='',
         attrs={
             'th': {'scope': 'col'},
-            "td": {"width": "20%"}
+            "td": {"width": "40%"}
         }
     )
 
@@ -184,7 +242,7 @@ class ResourcesTable(tables.Table):
         }
         exclude = (
             'id_metaservice',
-            'resoure_type',
+            'resource_type',
             'requirements',
             'is_global',
             'is_visible',
@@ -203,7 +261,6 @@ class ResourcesTable(tables.Table):
                 record.id
             )
 
-
 class ProvidersTable(tables.Table):
     id = tables.Column(
         verbose_name=_('ID'),
@@ -272,23 +329,43 @@ class ServiceTariffsTable(tables.Table):
             "td": {"width": "5%"}
         }
     )
-    service_category = tables.LinkColumn(
+    codename = tables.LinkColumn(
         'sharix_admin:service_tariff/edit/',
-        verbose_name=_('Name of the tariff'),
+        verbose_name=_('Кодовое название'),
+        text=lambda record: record.caption,
+        args=[tables.A('pk')],
+        attrs={
+            'th': {'scope': 'col'},
+            "td": {"width": "15%"}
+        }
+    )
+    #service_category = tables.Column(
+    service_category = tables.LinkColumn(
+        'sharix_admin:service_category/edit/',
+        verbose_name=_('Название схемы услуги'),
         text=lambda record: record.service_category.caption,
         args=[tables.A('pk')],
+        attrs={
+            'th': {'scope': 'col'},
+            "td": {"width": "15%"}
+        }
+    )
+    resource_type = tables.Column(
+        verbose_name=_('Тип ресурса'),
         attrs={
             'th': {'scope': 'col'},
             "td": {"width": "20%"}
         }
     )
-    ticket_status = tables.Column(
-        verbose_name=_('Name of the service scheme'),
+
+    company_comission = tables.Column(
+        verbose_name=_('Комиссия партнера'),
         attrs={
             'th': {'scope': 'col'},
             "td": {"width": "20%"}
         }
     )
+
     check = tables.BooleanColumn(
         verbose_name=_('Activity'),
         orderable=False,
@@ -305,11 +382,15 @@ class ServiceTariffsTable(tables.Table):
         }
         exclude = (
             'resource',
+            'company',
+            'caption',
+            'description',
             'price_type',
             'price_min',
             'price_amount',
             'id_metaservice',
             'requirements',
+            'ticket_status',
             'price_km',
             'is_global',
             'is_visible',
@@ -325,11 +406,12 @@ class ServiceTariffsTable(tables.Table):
 
 class ServiceCategoriesTable(tables.Table):
     id = tables.Column(attrs={"td": {"width": "50px"}})
-    codename = tables.LinkColumn(
+
+    caption = tables.LinkColumn(
         'sharix_admin:service_category/edit/',
         verbose_name='Услуга',
         orderable=False,
-        text=lambda record: record.codename,
+        text=lambda record: record.caption,
         args=[tables.A('pk')],
         attrs={
             "a": {"style": "pointer-events: none;"},
@@ -337,6 +419,19 @@ class ServiceCategoriesTable(tables.Table):
             "td": {"class": "name_col"}
         }
     )
+
+    #codename = tables.LinkColumn(
+    #    'sharix_admin:service_category/edit/',
+    #    verbose_name='Тех.название',
+    #    orderable=False,
+    #    text=lambda record: record.codename,
+    #    args=[tables.A('pk')],
+    #    attrs={
+    #        "a": {"style": "pointer-events: none;"},
+    #        'th': {'scope': 'col'},
+    #        "td": {"class": "name_col"}
+    #    }
+    #)
     description = tables.LinkColumn(
         'sharix_admin:service_category/edit/',
         orderable=False, verbose_name='Описание',
@@ -348,6 +443,14 @@ class ServiceCategoriesTable(tables.Table):
             "td": {"class": "description_col"}
         }
     )
+
+    metaservice_comission = tables.Column(
+        verbose_name=_('Комиссия Сервиса'),
+        attrs={
+            'th': {'scope': 'col'},
+            "td": {"width": "15%"}}
+    )
+
     edit = tables.LinkColumn(
         'sharix_admin:service_category/edit/',
         verbose_name='',
@@ -359,17 +462,27 @@ class ServiceCategoriesTable(tables.Table):
             "td": {"class": "edit_col"}
         }
     )
-    deletee = tables.LinkColumn(
-        'sharix_admin:service_category/delete/',
-        verbose_name='',
+    
+    check = tables.BooleanColumn(
+        verbose_name=_('Activity'),
         orderable=False,
-        text="D",
-        args=[tables.A('pk')],
         attrs={
             'th': {'scope': 'col'},
-            "td": {"class": "delete_col"}
+            "td": {"width": "5%"}
         }
     )
+    #TODO change to 'change status!'
+    #deletee = tables.LinkColumn(
+    #    'sharix_admin:service_category/delete/',
+    #    verbose_name='',
+    #    orderable=False,
+    #    text="D",
+    #    args=[tables.A('pk')],
+    #    attrs={
+    #        'th': {'scope': 'col'},
+    #        "td": {"class": "delete_col"}
+    #    }
+    #)
 
     class Meta:
         model = ServiceCategory
@@ -385,9 +498,25 @@ class ServiceCategoriesTable(tables.Table):
             'link_agreement',
             'is_global',
             'is_visible',
-            'caption'
+            'codename',
         )
 
+    def render_check(self, value, record):
+        if record.status == '0':
+            #if record.status == 'active':
+            return format_html(
+                '<input class="form-check-input status-toggle" checked type="checkbox" id="flexCheckDefault" data-service_category-id="{}">',
+                record.id
+            )
+            #return format_html('<input class="form-check-input status-toggle" checked type="checkbox" id="flexCheckDefault" data-service_category-id="{}">')
+            #return format_html('<input class="form-check-input status-toggle" disabled  checked type="checkbox"')
+        else:
+            return format_html(
+                '<input class="form-check-input status-toggle" type="checkbox" id="flexCheckDefault" data-service_category-id="{}">',
+                record.id
+            )
+            #return format_html('<input class="form-check-input status-toggle" disabled  type="checkbox"')
+
     # def render_delete(self, value, record):
     #     return format_html('<a href="/service_category/delete" class="btn btn-outline-danger">_(Delete)</a>')
 

+ 13 - 392
sharix_admin/templates/sharix_admin/base_admin.html

@@ -14,410 +14,31 @@
     </button>
 
     <ul class="d-flex flex-column nav nav-pills rounded box-shadow border p-2 bg-white">
-      <li class="nav-item">
-        <a href="{% url "sharix_admin:main" %}" class="nav-link {% if current_page == "main" %}active rounded{% endif %}">
-          <div class="link d-flex align-items-center">
-            <img
-              class="nav-img"
-              src="
-                {% if current_page == "main" %}
-                  {% static 'sharix_admin/img/menu/house_w.svg' %}
-                {% else %}
-                  {% static 'sharix_admin/img/menu/house.svg' %}
-                {% endif %}">
-            <span class="menu-bar-label">Главная</span>
-          </div>
-        </a>
-      </li>
-      <li class="nav-item">
-        <a href="{% url 'tickets:ticket_list_list' %}" class="nav-link {% if current_page == "tickets" %}active rounded{% endif %}">
-          <div class="link d-flex align-items-center">
-            <img
-              class="nav-img"
-              src="
-                {% if current_page == "tickets" %}
-                  {% 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>
-      <li class="nav-item">
-        <a href="http://study.reversea.net/" class="nav-link {% if current_page == "education" %}active rounded{% endif %}">
-          <div class="link d-flex align-items-center">
-            <img
-              class="nav-img"
-              src="
-                {% if current_page == "education" %}
-                  {% static 'sharix_admin/img/menu/education_w.svg' %}
-                {% else %}
-                  {% static 'sharix_admin/img/menu/education.svg' %}
-                {% endif %}">
-            <span class="menu-bar-label">Курсы</span>
-          </div>
-        </a>
-      </li>
-
-      <!-- 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
-              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>
-
-            <!-- 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 %}">
+      
+    {% for page in avaliable_pages %}
+    <li class="nav-item">
+	    <a href="{% url page.0 %}" class="nav-link {% if current_page == "{{ page.0 }}" %}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' %}
+                {% if current_page == page.0 %}
+		{% get_static_prefix %}{{ page.1 }}/img/menu/{{ page.2 }}_w.svg
                 {% else %}
-                  {% static 'sharix_admin/img/menu/briefcase.svg' %}
-                {% endif %}">
-            <span class="menu-bar-label">Добавить Исполнителя</span>
+                {% get_static_prefix %}{{ page.1 }}/img/menu/{{ page.2 }}.svg
+		{% endif %}">
+	    <span class="menu-bar-label">{{ page.3 }}</span>
           </div>
         </a>
       </li>
-      {% endif %}
-
-
-      <!-- COOPERATE BLOCK -->
-      {% if not "PARTNER-ADMIN" in user_groups %}
-        <li class="nav-item">
-          <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_request" %}
-                    {% 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>
-      {% 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">
-            <img
-              class="nav-img"
-              src="
-                {% if current_page == "none" %}
-                  {% 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> {% endcomment %}
+      {% endfor %}
 
       {% 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
-              class="nav-img"
-              src="
-                {% if current_page == "service_category" %}
-                  {% 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> {% endcomment %}
-      {% comment %} <li class="nav-item">
-        <a href="{% url 'sharix_admin:transactions' %}" class="nav-link {% if current_page == "transactions" %}active rounded{% endif %}">
-          <div class="link d-flex align-items-center">
-            <img
-              class="nav-img"
-              src="
-                {% if current_page == "transactions" %}
-                  {% static 'sharix_admin/img/menu/clock-history_w.svg' %}
-                {% else %}
-                  {% static 'sharix_admin/img/menu/clock-history.svg' %}
-                {% endif %}">
-            <span class="menu-bar-label">История заказов</span>
-          </div>
-        </a>
-      </li> {% endcomment %}
-      {% if "PARTNER-ADMIN" in user_groups %}
-        <li class="nav-item">
-          <a href="{% url 'sharix_admin:partner_detail_my' %}" class="nav-link {% if current_page == 'partner' %}active rounded{% endif %}">
-            <div class="link d-flex align-items-center">
-              <img
-                class="nav-img"
-                src="
-                  {% if current_page == 'partner' %}
-                    {% static 'sharix_admin/img/menu/person_w.svg' %}
-                  {% else %}
-                    {% static 'sharix_admin/img/menu/person.svg' %}
-                  {% endif %}">
-              <span class="menu-bar-label">О партнере</span>
-            </div>
-          </a>
-        </li>
-      {% endif %}
-      {% comment %} <li class="nav-item">
-        <a href="{% url 'sharix_admin:service_information-add' %}" class="nav-link {% if current_page == "service_info" %}active rounded{% endif %}">
-          <div class="link d-flex align-items-center">
-            <img
-              class="nav-img"
-              src="
-                {% if current_page == "service_info" %}
-                  {% static 'sharix_admin/img/menu/person_w.svg' %}
-                {% else %}
-                  {% static 'sharix_admin/img/menu/person.svg' %}
-                {% endif %}">
-            <span class="menu-bar-label">Информация о сервисе</span>
-          </div>
-        </a>
-      </li> {% endcomment %}
-      {% comment %} <li class="nav-item">
-        <a href="{% url 'sharix_admin:payment' %}" class="nav-link {% if current_page == "payment" %}active rounded{% endif %}">
-          <div class="link d-flex align-items-center">
-            <img
-              class="nav-img"
-              src="
-                {% if current_page == "payment" %}
-                  {% static 'sharix_admin/img/menu/credit-card_w.svg' %}
-                {% else %}
-                  {% static 'sharix_admin/img/menu/credit-card.svg' %}
-                {% endif %}">
-            <span class="menu-bar-label">Реквизиты</span>
-          </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>
-
       
       {% include 'webservice_running/metaservice_menu.html' %}
-     
+      {% endcomment %}
+
+      
     </ul>
   </nav>
 

+ 465 - 0
sharix_admin/templates/sharix_admin/base_admin_menu.html

@@ -0,0 +1,465 @@
+{% extends 'sharix_admin/base.html' %}
+{% load i18n %}
+{% load static %}
+
+{% block content %}
+<div id="loader-wrapper">
+  <div id="loader"></div>
+</div>
+
+<div class="content p-4 mx-auto d-flex flex-column justify-content-between">
+  <nav id="menu-bar">
+    <button class="bg-white border box-shadow rounded mb-2 px-4 py-1" onclick="menuBarSwitch()">
+        <img id="menu-bar-img-arrow" src="{% static 'sharix_admin/img/menu/arrow-right.svg' %}">
+    </button>
+
+    <ul class="d-flex flex-column nav nav-pills rounded box-shadow border p-2 bg-white">
+      
+    {% for page in avaliable_pages %}
+    <li class="nav-item">
+	    <a href="{% url page %}" class="nav-link {% if current_page == "{{ page }}" %}active rounded{% endif %}">
+          <div class="link d-flex align-items-center">
+            <img
+              class="nav-img"
+              src="
+                {% if current_page == "main" %}
+                  {% static 'sharix_admin/img/menu/house_w.svg' %}
+                {% else %}
+                  {% static 'sharix_admin/img/menu/house.svg' %}
+                {% endif %}">
+	    <span class="menu-bar-label">{{ page }}</span>
+          </div>
+        </a>
+      </li>
+      {% endfor %}
+
+
+      <li class="nav-item">
+        <a href="{% url 'tickets:ticket_list_list' %}" class="nav-link {% if current_page == "tickets" %}active rounded{% endif %}">
+          <div class="link d-flex align-items-center">
+            <img
+              class="nav-img"
+              src="
+                {% if current_page == "tickets" %}
+                  {% 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>
+      <li class="nav-item">
+        <a href="http://study.reversea.net/" class="nav-link {% if current_page == "education" %}active rounded{% endif %}">
+          <div class="link d-flex align-items-center">
+            <img
+              class="nav-img"
+              src="
+                {% if current_page == "education" %}
+                  {% static 'sharix_admin/img/menu/education_w.svg' %}
+                {% else %}
+                  {% static 'sharix_admin/img/menu/education.svg' %}
+                {% endif %}">
+            <span class="menu-bar-label">Курсы</span>
+          </div>
+        </a>
+      </li>
+
+      <!-- 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
+              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>
+
+            <!-- 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>
+
+      {% endif %}
+
+
+      <!-- COOPERATE BLOCK -->
+      {% if not "PARTNER-ADMIN" in user_groups %}
+        <li class="nav-item">
+          <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_request" %}
+                    {% 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>
+      {% 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">
+            <img
+              class="nav-img"
+              src="
+                {% if current_page == "none" %}
+                  {% 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> {% endcomment %}
+
+      {% 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
+              class="nav-img"
+              src="
+                {% if current_page == "service_category" %}
+                  {% 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> {% endcomment %}
+      {% comment %} <li class="nav-item">
+        <a href="{% url 'sharix_admin:transactions' %}" class="nav-link {% if current_page == "transactions" %}active rounded{% endif %}">
+          <div class="link d-flex align-items-center">
+            <img
+              class="nav-img"
+              src="
+                {% if current_page == "transactions" %}
+                  {% static 'sharix_admin/img/menu/clock-history_w.svg' %}
+                {% else %}
+                  {% static 'sharix_admin/img/menu/clock-history.svg' %}
+                {% endif %}">
+            <span class="menu-bar-label">История заказов</span>
+          </div>
+        </a>
+      </li> {% endcomment %}
+      {% if "PARTNER-ADMIN" in user_groups %}
+        <li class="nav-item">
+          <a href="{% url 'sharix_admin:partner_detail_my' %}" class="nav-link {% if current_page == 'partner' %}active rounded{% endif %}">
+            <div class="link d-flex align-items-center">
+              <img
+                class="nav-img"
+                src="
+                  {% if current_page == 'partner' %}
+                    {% static 'sharix_admin/img/menu/person_w.svg' %}
+                  {% else %}
+                    {% static 'sharix_admin/img/menu/person.svg' %}
+                  {% endif %}">
+              <span class="menu-bar-label">О партнере</span>
+            </div>
+          </a>
+        </li>
+      {% endif %}
+      {% comment %} <li class="nav-item">
+        <a href="{% url 'sharix_admin:service_information-add' %}" class="nav-link {% if current_page == "service_info" %}active rounded{% endif %}">
+          <div class="link d-flex align-items-center">
+            <img
+              class="nav-img"
+              src="
+                {% if current_page == "service_info" %}
+                  {% static 'sharix_admin/img/menu/person_w.svg' %}
+                {% else %}
+                  {% static 'sharix_admin/img/menu/person.svg' %}
+                {% endif %}">
+            <span class="menu-bar-label">Информация о сервисе</span>
+          </div>
+        </a>
+      </li> {% endcomment %}
+      {% comment %} <li class="nav-item">
+        <a href="{% url 'sharix_admin:payment' %}" class="nav-link {% if current_page == "payment" %}active rounded{% endif %}">
+          <div class="link d-flex align-items-center">
+            <img
+              class="nav-img"
+              src="
+                {% if current_page == "payment" %}
+                  {% static 'sharix_admin/img/menu/credit-card_w.svg' %}
+                {% else %}
+                  {% static 'sharix_admin/img/menu/credit-card.svg' %}
+                {% endif %}">
+            <span class="menu-bar-label">Реквизиты</span>
+          </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>
+
+      
+      {% include 'webservice_running/metaservice_menu.html' %}
+     
+
+    </ul>
+  </nav>
+
+  <div id="user-workspace" class="p-5 border rounded box-shadow">
+      <h1>{{ title }}</h1>
+      {% if messages %}
+        {% for message in messages %}
+          <div class="alert {% if message.tags %}alert-{{ message.tags }}{% endif %}">{{ message }}</div>
+        {% endfor %}
+      {% endif %}
+      
+      {% block view %}{% endblock view %}
+  </div>
+
+  <footer class="d-flex justify-content-between mt-3 p-2 align-items-center border rounded box-shadow">
+    <div class="d-flex align-items-center">
+        <div class="d-flex justify-content-center align-items-center rounded-circle bg-secondary-subtle p-3">
+          <i class="fa-solid fa-user"></i>
+        </div>
+        <span class="mx-2 text-nowrap text-muted">{{ user }}</span>
+    </div>
+
+    <div class="d-flex gap-3 mx-2">
+        {% comment %} <a href="{% url 'contact' %}">{% trans 'Contacts' %}</a> {% endcomment %}
+        <a href="https://wiki.sharix-app.org/doku.php/sharix/legal/soglashenie_s_servisom_na_ispolzovanie_platformy_sharix">{% trans 'Terms of use' %}</a>
+        <a href="https://wiki.sharix-app.org/doku.php/sharix/legal/politika_konfidencialnosti_platformy_sharix">{% trans 'Privacy policy' %}</a>
+        <a href="https://wiki.sharix-app.org/doku.php">Помощь</a>
+    </div>
+
+    <form method="post" action="{% url "sharix_admin:auth_logout" %}">
+      {% csrf_token %}
+      <button class="btn btn-sm btn-outline-secondary text-nowrap" type="submit">
+        Выйти
+        <i class="fa-solid fa-right-from-bracket ms-1"></i>
+      </button>
+    </form>
+  </footer>
+</div>
+
+<script src="{% static 'sharix_admin/js/menu-bar.js' %}"></script>
+
+<script>
+  // Запуск некоторых функций после загрузки страницы
+  document.addEventListener('DOMContentLoaded', function() {
+    menuBarControll();
+  });
+
+  // Функция для скрытия экрана загрузки
+  function hideLoader() { document.getElementById("loader-wrapper").style.display = "none"; }
+
+  // Скрыть экран загрузки через 4 секунды
+  setTimeout(hideLoader, 400);
+</script>
+{% endblock %}

+ 461 - 0
sharix_admin/templates/sharix_admin/base_admin_old_example.html

@@ -0,0 +1,461 @@
+{% extends 'sharix_admin/base.html' %}
+{% load i18n %}
+{% load static %}
+
+{% block content %}
+<div id="loader-wrapper">
+  <div id="loader"></div>
+</div>
+
+<div class="content p-4 mx-auto d-flex flex-column justify-content-between">
+  <nav id="menu-bar">
+    <button class="bg-white border box-shadow rounded mb-2 px-4 py-1" onclick="menuBarSwitch()">
+        <img id="menu-bar-img-arrow" src="{% static 'sharix_admin/img/menu/arrow-right.svg' %}">
+    </button>
+
+    <ul class="d-flex flex-column nav nav-pills rounded box-shadow border p-2 bg-white">
+      <li class="nav-item">
+        <a href="{% url "sharix_admin:main" %}" class="nav-link {% if current_page == "main" %}active rounded{% endif %}">
+          <div class="link d-flex align-items-center">
+            <img
+              class="nav-img"
+              src="
+                {% if current_page == "main" %}
+                  {% static 'sharix_admin/img/menu/house_w.svg' %}
+                {% else %}
+                  {% static 'sharix_admin/img/menu/house.svg' %}
+                {% endif %}">
+            <span class="menu-bar-label">Главная</span>
+          </div>
+        </a>
+      </li>
+      <li class="nav-item">
+        <a href="{% url 'tickets:ticket_list_list' %}" class="nav-link {% if current_page == "tickets" %}active rounded{% endif %}">
+          <div class="link d-flex align-items-center">
+            <img
+              class="nav-img"
+              src="
+                {% if current_page == "tickets" %}
+                  {% 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>
+      <li class="nav-item">
+        <a href="http://study.reversea.net/" class="nav-link {% if current_page == "education" %}active rounded{% endif %}">
+          <div class="link d-flex align-items-center">
+            <img
+              class="nav-img"
+              src="
+                {% if current_page == "education" %}
+                  {% static 'sharix_admin/img/menu/education_w.svg' %}
+                {% else %}
+                  {% static 'sharix_admin/img/menu/education.svg' %}
+                {% endif %}">
+            <span class="menu-bar-label">Курсы</span>
+          </div>
+        </a>
+      </li>
+
+      <!-- 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
+              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>
+
+            <!-- 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>
+
+      
+      {% endif %}
+
+
+      <!-- COOPERATE BLOCK -->
+      {% if not "PARTNER-ADMIN" in user_groups %}
+        <li class="nav-item">
+          <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_request" %}
+                    {% 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>
+      {% 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">
+            <img
+              class="nav-img"
+              src="
+                {% if current_page == "none" %}
+                  {% 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> {% endcomment %}
+
+      {% 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
+              class="nav-img"
+              src="
+                {% if current_page == "service_category" %}
+                  {% 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> {% endcomment %}
+      {% comment %} <li class="nav-item">
+        <a href="{% url 'sharix_admin:transactions' %}" class="nav-link {% if current_page == "transactions" %}active rounded{% endif %}">
+          <div class="link d-flex align-items-center">
+            <img
+              class="nav-img"
+              src="
+                {% if current_page == "transactions" %}
+                  {% static 'sharix_admin/img/menu/clock-history_w.svg' %}
+                {% else %}
+                  {% static 'sharix_admin/img/menu/clock-history.svg' %}
+                {% endif %}">
+            <span class="menu-bar-label">История заказов</span>
+          </div>
+        </a>
+      </li> {% endcomment %}
+      {% if "PARTNER-ADMIN" in user_groups %}
+        <li class="nav-item">
+          <a href="{% url 'sharix_admin:partner_detail_my' %}" class="nav-link {% if current_page == 'partner' %}active rounded{% endif %}">
+            <div class="link d-flex align-items-center">
+              <img
+                class="nav-img"
+                src="
+                  {% if current_page == 'partner' %}
+                    {% static 'sharix_admin/img/menu/person_w.svg' %}
+                  {% else %}
+                    {% static 'sharix_admin/img/menu/person.svg' %}
+                  {% endif %}">
+              <span class="menu-bar-label">О партнере</span>
+            </div>
+          </a>
+        </li>
+      {% endif %}
+      {% comment %} <li class="nav-item">
+        <a href="{% url 'sharix_admin:service_information-add' %}" class="nav-link {% if current_page == "service_info" %}active rounded{% endif %}">
+          <div class="link d-flex align-items-center">
+            <img
+              class="nav-img"
+              src="
+                {% if current_page == "service_info" %}
+                  {% static 'sharix_admin/img/menu/person_w.svg' %}
+                {% else %}
+                  {% static 'sharix_admin/img/menu/person.svg' %}
+                {% endif %}">
+            <span class="menu-bar-label">Информация о сервисе</span>
+          </div>
+        </a>
+      </li> {% endcomment %}
+      {% comment %} <li class="nav-item">
+        <a href="{% url 'sharix_admin:payment' %}" class="nav-link {% if current_page == "payment" %}active rounded{% endif %}">
+          <div class="link d-flex align-items-center">
+            <img
+              class="nav-img"
+              src="
+                {% if current_page == "payment" %}
+                  {% static 'sharix_admin/img/menu/credit-card_w.svg' %}
+                {% else %}
+                  {% static 'sharix_admin/img/menu/credit-card.svg' %}
+                {% endif %}">
+            <span class="menu-bar-label">Реквизиты</span>
+          </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>
+
+      
+      {% include 'webservice_running/metaservice_menu.html' %}
+     
+
+    </ul>
+  </nav>
+
+  <div id="user-workspace" class="p-5 border rounded box-shadow">
+      <h1>{{ title }}</h1>
+      {% if messages %}
+        {% for message in messages %}
+          <div class="alert {% if message.tags %}alert-{{ message.tags }}{% endif %}">{{ message }}</div>
+        {% endfor %}
+      {% endif %}
+      
+      {% block view %}{% endblock view %}
+  </div>
+
+  <footer class="d-flex justify-content-between mt-3 p-2 align-items-center border rounded box-shadow">
+    <div class="d-flex align-items-center">
+        <div class="d-flex justify-content-center align-items-center rounded-circle bg-secondary-subtle p-3">
+          <i class="fa-solid fa-user"></i>
+        </div>
+        <span class="mx-2 text-nowrap text-muted">{{ user }}</span>
+    </div>
+
+    <div class="d-flex gap-3 mx-2">
+        {% comment %} <a href="{% url 'contact' %}">{% trans 'Contacts' %}</a> {% endcomment %}
+        <a href="https://wiki.sharix-app.org/doku.php/sharix/legal/soglashenie_s_servisom_na_ispolzovanie_platformy_sharix">{% trans 'Terms of use' %}</a>
+        <a href="https://wiki.sharix-app.org/doku.php/sharix/legal/politika_konfidencialnosti_platformy_sharix">{% trans 'Privacy policy' %}</a>
+        <a href="https://wiki.sharix-app.org/doku.php">Помощь</a>
+    </div>
+
+    <form method="post" action="{% url "sharix_admin:auth_logout" %}">
+      {% csrf_token %}
+      <button class="btn btn-sm btn-outline-secondary text-nowrap" type="submit">
+        Выйти
+        <i class="fa-solid fa-right-from-bracket ms-1"></i>
+      </button>
+    </form>
+  </footer>
+</div>
+
+<script src="{% static 'sharix_admin/js/menu-bar.js' %}"></script>
+
+<script>
+  // Запуск некоторых функций после загрузки страницы
+  document.addEventListener('DOMContentLoaded', function() {
+    menuBarControll();
+  });
+
+  // Функция для скрытия экрана загрузки
+  function hideLoader() { document.getElementById("loader-wrapper").style.display = "none"; }
+
+  // Скрыть экран загрузки через 4 секунды
+  setTimeout(hideLoader, 400);
+</script>
+{% endblock %}

+ 12 - 0
sharix_admin/templates/sharix_admin/orders.html

@@ -0,0 +1,12 @@
+{% extends 'sharix_admin/base_admin.html' %}
+{% load render_table from django_tables2 %}
+{% load i18n %}
+{% load static %}
+
+{% block view %}
+{% block contenthome %}
+
+{% render_table table %}
+    
+{% endblock contenthome %}
+{% endblock view %}

+ 21 - 2
sharix_admin/templates/sharix_admin/partners.html

@@ -3,8 +3,27 @@
 
 {% block view %}
 {% block contenthome %}
-  <p class="description_service">Это система управления государством, источником власти в которой является сам народ. Именно народ решает, какие законы и нормы необходимы для гармоничного существования и развития государства. Таким образом, каждый человек в демократическом обществе 
-    Получает определенный набор свобод и обязательств сформированных с учетом интересов всего сообщества. Исходя из вышесказанного, можно заключить, что демократия – это возможность для каждого человека свободно участвовать в непосредственном управлении своим государством, обществом и личной судьбой в конечном счете.</p>
+  <p class="description_service">
+Это список партнеров Сервиса. Просто посмотреть.
+</p>
+
+<div class="dropdown mb-3">
+        <button class="btn btn-secondary dropdown-toggle" type="button" id="howToUseDropdown" data-bs-toggle="dropdown" aria-expanded="false">
+            Как пользоваться?
+        </button>
+        <div class="dropdown-menu" aria-labelledby="howToUseDropdown">
+            <p class="dropdown-item-text custom-dropdown-text">
+	    Активация происходит через заявки, отправленные на платформу, или, если Сервис не подключен к платформе - вручную.
+	    </p>
+        </div>
+</div>
+
+    <div class="mb-3 d-flex justify-content-between align-items-center">
+      <form method="get" action="" class="d-flex align-items-center">
+          <input type="text" name="q" class="form-control" placeholder="Поиск" value="{{ request.GET.q }}" style="width: 300px; height: 38px;">
+          <button type="submit" class="btn btn-primary ms-2" style="height: 38px;">Поиск</button>
+      </form>
+      </div>
 
   <div class="container text-center mt-2">
     {% render_table table %}

+ 23 - 0
sharix_admin/templates/sharix_admin/provider_form.html

@@ -0,0 +1,23 @@
+{% extends 'sharix_admin/base_admin.html' %}
+{% load i18n %}
+
+{% block view %}
+<div class="container">
+<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="submit" value="{% trans 'Submit' %}"/>
+    </div>
+</form>
+</div>
+{% endblock view %}

+ 29 - 2
sharix_admin/templates/sharix_admin/providers.html

@@ -1,9 +1,36 @@
 {% extends 'sharix_admin/base_admin.html' %}
 {% load render_table from django_tables2 %}
-
+{% load i18n %}
 {% block view %}
 {% block contenthome %}
-    <h1 class="mainHeader">{{ title }}</h1>
+
+<p>
+На данной странице представлен список исполнителей по конкретным услугам.
+</p>
+
+<div class="dropdown mb-3">
+        <button class="btn btn-secondary dropdown-toggle" type="button" id="howToUseDropdown" data-bs-toggle="dropdown" aria-expanded="false">
+            Как пользоваться?
+        </button>
+        <div class="dropdown-menu" aria-labelledby="howToUseDropdown">
+            <p class="dropdown-item-text custom-dropdown-text">
+	    Активация происходит через заявки, отправленные на платформу, или, если Сервис не подключен к платформе - вручную.
+	    </p>
+        </div>
+</div>
+
+    <div class="mb-3 d-flex justify-content-between align-items-center">
+      <form method="get" action="" class="d-flex align-items-center">
+          <input type="text" name="q" class="form-control" placeholder="Поиск" value="{{ request.GET.q }}" style="width: 300px; height: 38px;">
+          <button type="submit" class="btn btn-primary ms-2" style="height: 38px;">Поиск</button>
+      </form>
+      </div>
+
+{% if "PROVIDER" in user_groups %}
+  <div class="container text-end mt-2">
+          <a class="btn btn-primary" id="bord" href={% url "sharix_admin:provider/add/" %}>{% trans 'Add' %}</a>
+  </div>
+{% endif %}
 
     <div class="container text-center mt-2">
       {% render_table table %}

+ 9 - 0
sharix_admin/templates/sharix_admin/resource.html

@@ -0,0 +1,9 @@
+{% extends 'sharix_admin/base_admin.html' %}
+
+{% block view %}
+<form method="post" class="d-flex flex-column align-items-end">
+    {% csrf_token %}
+    {% include 'sharix_admin/include/form.html' %}
+    <button class="btn btn-primary" type="submit">Отправить</button>
+</form>
+{% endblock %}

+ 81 - 0
sharix_admin/templates/sharix_admin/resource_list.html

@@ -0,0 +1,81 @@
+{% extends 'sharix_admin/base_admin.html' %}
+{% load render_table from django_tables2 %}
+{% load i18n %}
+{% load static %}
+
+{% block view %}
+{% block contenthome %}
+
+<style>
+  a {
+    color: black;
+    text-decoration: none;
+  }
+  a:hover {
+    color: black;
+  }
+</style>
+
+<p class="description_service">
+        На этой странице представлены список средств и объектов, необходимых для обеспечения функционирования сервиса. 
+        Активация ресурсов происходит через <a href="{% url 'tickets:ticket_list_list' %}" class="text-primary">заявки</a>.
+    </p>
+
+    <div class="dropdown mb-3">
+        <button class="btn btn-secondary dropdown-toggle" type="button" id="howToUseDropdown" data-bs-toggle="dropdown" aria-expanded="false">
+            Как пользоваться?
+        </button>
+        <div class="dropdown-menu" aria-labelledby="howToUseDropdown">
+            <p class="dropdown-item-text custom-dropdown-text">
+	    На этой странице представлены список средств и объектов, необходимых для обеспечения функционирования сервиса. Активация ресурсов происходит через заявки. На этой странице представлены список средств и объектов, необходимых для обеспечения функционирования сервиса. Активация ресурсов происходит через заявки.
+	    </p>
+	</div>
+    </div>
+
+    <div class="mb-3 d-flex justify-content-between align-items-center">
+      <form method="get" action="" class="d-flex align-items-center">
+          <input type="text" name="q" class="form-control" placeholder="Поиск" value="{{ request.GET.q }}" style="width: 300px; height: 38px;">
+          <button type="submit" class="btn btn-primary ms-2" style="height: 38px;">Поиск</button>
+      </form>
+      </div>
+ 
+    <div class="container text-end mt-2">
+      <a href="{% url 'sharix_admin:resource/add/' %}" class="btn btn-primary" style="height: 38px;">Добавить ресурс</a>
+    </div>
+
+    <div class="row justify-content-start">
+          <div class="maintable" id="maintable">
+            {% render_table table %}
+          </div>     
+      </div>
+
+
+    <script>
+      // Запрос на изменения статуса ресурса
+      $('.status-toggle').change(function() {
+        var resource = $(this).data('resource-id');
+        var new_status = $(this).prop('checked') ? 'active' : 'deactivated';
+        $.ajax({
+          url: '{% url "sharix_admin:resource/change_status" %}',
+          type: 'POST',
+          data: {
+            'resource': resource,
+            'new_status': new_status,
+            'csrfmiddlewaretoken': '{{ csrf_token }}'
+          },
+          success: function(response) {
+            var scrollTop = window.pageYOffset;
+            location.reload();
+            window.scrollTo(0, scrollTop);
+          },
+          error: function(xhr, status, error) {
+            console.log(xhr.responseText);
+          }
+        });
+      });
+    </script> 
+    
+
+    
+{% endblock contenthome %}
+{% endblock %}

+ 0 - 40
sharix_admin/templates/sharix_admin/resources.html

@@ -1,40 +0,0 @@
-{% extends 'sharix_admin/base_admin.html' %}
-{% load render_table from django_tables2 %}
-
-{% block view %}
-{% block contenthome %}
-    <h1 >{{ title }}</h1>
-
-    <div class="container text-center mt-2">
-      {% render_table table %}
-    </div>
-    <script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
-    <script>
-      // Запрос на изменения статуса ресурса
-      $('.status-toggle').change(function() {
-        var resource = $(this).data('resource-id');
-        var new_status = $(this).prop('checked') ? 'active' : 'deactivated';
-        $.ajax({
-          url: '{% url "sharix_admin:resource/change_status" %}',
-          type: 'POST',
-          data: {
-            'resource': resource,
-            'new_status': new_status,
-            'csrfmiddlewaretoken': '{{ csrf_token }}'
-          },
-          success: function(response) {
-            var scrollTop = window.pageYOffset;
-            location.reload();
-            window.scrollTo(0, scrollTop);
-          },
-          error: function(xhr, status, error) {
-            console.log(xhr.responseText);
-          }
-        });
-      });
-    </script> 
-    
-
-    
-{% endblock contenthome %}
-{% endblock view %}

+ 57 - 6
sharix_admin/templates/sharix_admin/service_categories.html

@@ -15,17 +15,68 @@
   }
 </style>
 
-<p class="description_service">Это система управления государством, источником власти в которой является сам народ. Именно народ решает, какие законы и нормы необходимы для гармоничного существования и развития государства. Таким образом, каждый человек в демократическом обществе 
-        Получает определенный набор свобод и обязательств сформированных с учетом интересов всего сообщества. Исходя из вышесказанного, можно заключить, что демократия – это возможность для каждого человека свободно участвовать в непосредственном управлении своим государством, обществом и личной судьбой в конечном счете.</p>
-      <div class="row justify-content-start">
+<p class="description_service">
+На данной странице можно посмотреть имеющиеся Категории сервиса. Это глобальные виды услуг для Сервиса, которые активируются на платформе (при наличии подключения к ней). Партнеры и исполнители могут добавлять свои услуги и ресурсы только в контексте данных категорий. 
+</p>
+
+<div class="dropdown mb-3">
+        <button class="btn btn-secondary dropdown-toggle" type="button" id="howToUseDropdown" data-bs-toggle="dropdown" aria-expanded="false">
+            Как пользоваться?
+        </button>
+        <div class="dropdown-menu" aria-labelledby="howToUseDropdown">
+            <p class="dropdown-item-text custom-dropdown-text">
+	    Активация происходит через заявки, отправленные на платформу, или, если Сервис не подключен к платформе - вручную.
+	    </p>
+        </div>
+</div>
+
+    <div class="mb-3 d-flex justify-content-between align-items-center">
+      <form method="get" action="" class="d-flex align-items-center">
+          <input type="text" name="q" class="form-control" placeholder="Поиск" value="{{ request.GET.q }}" style="width: 300px; height: 38px;">
+          <button type="submit" class="btn btn-primary ms-2" style="height: 38px;">Поиск</button>
+      </form>
+      </div>
+
+{% if "METASERVICE-ADMIN" in user_groups %}
+<h1></h1>
+  <div class="container text-end mt-2">
+          <a class="btn btn-primary" id="bord" href={% url "sharix_admin:service_category/add/" %}>{% trans 'Add' %}</a>
+  </div>
+{% endif %}
+
+    <div class="row justify-content-start">
           <div class="maintable" id="maintable">
             {% render_table table %}
           </div>     
       </div>
 
-  <div class="container text-end mt-2">
-    <a class="btn btn-primary" id="bord" href="/service_category/add">{% trans 'Add' %}</a>
-  </div>
+<script>
+
+// Запрос на изменения статуса категории сервиса
+      $('.status-toggle').change(function() {
+        var service_category = $(this).data('service_category-id');
+        var new_status = $(this).prop('checked') ? '0' : '1';
+        $.ajax({
+          url: '{% url "sharix_admin:service_category/change_status" %}',
+          type: 'POST',
+          data: {
+            'service_category': service_category,
+            'new_status': new_status,
+            'csrfmiddlewaretoken': '{{ csrf_token }}'
+          },
+          success: function(response) {
+            var scrollTop = window.pageYOffset;
+            location.reload();
+            window.scrollTo(0, scrollTop);
+          },
+          error: function(xhr, status, error) {
+            console.log(xhr.responseText);
+          }
+        });
+      });
+
+</script>
+
 {% endblock contenthome %}
 {% endblock %}
 

+ 0 - 3
sharix_admin/templates/sharix_admin/service_category_form.html

@@ -2,9 +2,7 @@
 {% load i18n %}
 
 {% block view %}
-{% block contenthome %}
 <div class="container">
-<h1 class="mainHeader">{{ title }}</h1>
 <form method="post" style="overflow: auto">
     {% csrf_token %}
     <div class="container m-2">
@@ -22,5 +20,4 @@
     </div>
 </form>
 </div>
-{% endblock contenthome %}
 {% endblock view %}

+ 0 - 1
sharix_admin/templates/sharix_admin/service_tariff_form.html

@@ -3,7 +3,6 @@
 
 {% block view %}
 {% block contenthome %}
-<h1 class="mainHeader">{{ title }}</h1>
 <form method="post" style="overflow: auto">
     {% csrf_token %}
     <div class="container m-2">

+ 57 - 6
sharix_admin/templates/sharix_admin/service_tariffs.html

@@ -4,9 +4,34 @@
 
 {% block view %}
 {% block contenthome %}
-    <h1 class="mainHeader">{{ title }}</h1>
-    <p class="description_service">Это система управления государством, источником власти в которой является сам народ. Именно народ решает, какие законы и нормы необходимы для гармоничного существования и развития государства. Таким образом, каждый человек в демократическом обществе 
-      Получает определенный набор свобод и обязательств сформированных с учетом интересов всего сообщества. Исходя из вышесказанного, можно заключить, что демократия – это возможность для каждого человека свободно участвовать в непосредственном управлении своим государством, обществом и личной судьбой в конечном счете.</p>
+    <p class="description_service">
+    На этой странице отображаются доступные в Сервисе тарифы на основе имеющихся категорий тарифов.
+    </p>
+
+<div class="dropdown mb-3">
+        <button class="btn btn-secondary dropdown-toggle" type="button" id="howToUseDropdown" data-bs-toggle="dropdown" aria-expanded="false">
+            Как пользоваться?
+        </button>
+        <div class="dropdown-menu" aria-labelledby="howToUseDropdown">
+            <p class="dropdown-item-text custom-dropdown-text">
+	    Активация происходит через заявки (активирует модератор Сервиса), которые отправляются автоматически при выполнении различных действий через интерфейс.
+	    </p>
+        </div>
+</div>
+
+    <div class="mb-3 d-flex justify-content-between align-items-center">
+      <form method="get" action="" class="d-flex align-items-center">
+          <input type="text" name="q" class="form-control" placeholder="Поиск" value="{{ request.GET.q }}" style="width: 300px; height: 38px;">
+          <button type="submit" class="btn btn-primary ms-2" style="height: 38px;">Поиск</button>
+      </form>
+      </div>
+
+{% if "PARTNER-ADMIN" or "PARTNER-SUPERVISOR" in user_groups %}
+    <div class="container text-end mt-2">
+	    <a class="btn btn-primary" href={% url "sharix_admin:service_tariff/add/" %}>{% trans 'Add' %}</a>
+    </div>
+{% endif %}
+
     <div class="container text-center mt-2">
           {% render_table table %}
 
@@ -46,9 +71,35 @@
             </nav>
           {% endif %} {% endcomment %}
     </div>
-    <div class="container text-end mt-2">
-      <a class="btn btn-primary" href="/service_tariff/add">{% trans 'Add' %}</a>
-    </div>
+
+<script>
+
+// Запрос на изменения статуса тарифа сервиса
+      $('.status-toggle').change(function() {
+        var service = $(this).data('service-id');
+        var new_status = $(this).prop('checked') ? '0' : '1';
+        $.ajax({
+          url: '{% url "sharix_admin:service_tariff/change_status" %}',
+          type: 'POST',
+          data: {
+            'service': service,
+            'new_status': new_status,
+            'csrfmiddlewaretoken': '{{ csrf_token }}'
+          },
+          success: function(response) {
+            var scrollTop = window.pageYOffset;
+            location.reload();
+            window.scrollTo(0, scrollTop);
+          },
+          error: function(xhr, status, error) {
+            console.log(xhr.responseText);
+          }
+        });
+      });
+
+</script>
+
+
 {% endblock contenthome %}
 {% endblock view %}
 

+ 62 - 1
sharix_admin/templates/sharix_admin/staff/access_control.html

@@ -1,9 +1,40 @@
 {% extends 'sharix_admin/base_admin.html' %}
 {% load i18n %}
 
+{% load render_table from django_tables2 %}
+{% load static %}
+
 {% block view %}
 {% block contenthome %}
-<h1 class="mainHeader">{{ title }}</h1>
+<p>
+Список прав и разрешений внутри сервиса в целом.
+</p>
+
+<div class="dropdown mb-3">
+        <button class="btn btn-secondary dropdown-toggle" type="button" id="howToUseDropdown" data-bs-toggle="dropdown" aria-expanded="false">
+            Как пользоваться?
+        </button>
+        <div class="dropdown-menu" aria-labelledby="howToUseDropdown">
+            <p class="dropdown-item-text custom-dropdown-text">
+	    Активация происходит через заявки, отправленные на платформу, или, если Сервис не подключен к платформе - вручную.
+	    </p>
+        </div>
+</div>
+
+    <div class="mb-3 d-flex justify-content-between align-items-center">
+      <form method="get" action="" class="d-flex align-items-center">
+          <input type="text" name="q" class="form-control" placeholder="Поиск" value="{{ request.GET.q }}" style="width: 300px; height: 38px;">
+          <button type="submit" class="btn btn-primary ms-2" style="height: 38px;">Поиск</button>
+      </form>
+      </div>
+
+    <div class="row justify-content-start">
+          <div class="maintable" id="maintable">
+            {% render_table table %}
+          </div>     
+      </div>
+
+{% comment %}
 <form method="post" style="overflow: auto">
     {% csrf_token %}
     <div class="container m-2">
@@ -20,5 +51,35 @@
         <input class="btn btn-primary center" type="submit" name="apply" value="{% trans 'Submit' %}" />
     </div>
 </form>
+{% endcomment %}
+
+<script>
+// Запрос на изменения статуса категории сервиса
+      $('.status-toggle').change(function() {
+        var service_category = $(this).data('service_category-id');
+        var new_status = $(this).prop('checked') ? '0' : '1';
+        $.ajax({
+          url: '{% url "sharix_admin:service_category/change_status" %}',
+          type: 'POST',
+          data: {
+            'service_category': service_category,
+            'new_status': new_status,
+            'csrfmiddlewaretoken': '{{ csrf_token }}'
+          },
+          success: function(response) {
+            var scrollTop = window.pageYOffset;
+            location.reload();
+            window.scrollTo(0, scrollTop);
+          },
+          error: function(xhr, status, error) {
+            console.log(xhr.responseText);
+          }
+        });
+      });
+
+</script>
+
 {% endblock contenthome %}
 {% endblock view %}
+
+

+ 26 - 17
sharix_admin/urls.py

@@ -33,6 +33,13 @@ urlpatterns = [
     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'),
 
+        #Order model SHOULD HAVE at least LIST, ADD, DETAIL, EDIT if that corresponds service idea, othervice Open models and pages might be enough
+    path('orders/', login_required(OrdersListView.as_view()), name='orders'),
+    path('order/<int:pk>', login_required(OrdersDetailView.as_view()), name='order_detail'),
+        # todo - move from views.order_reg to this one
+    path('order/add/', login_required(OrdersCreate.as_view()), name='order/add/'),
+    path('order/edit/<int:pk>', login_required(OrdersEditView.as_view()), name='order/edit'),
+
     # Набор страниц по модели Партнер
     path('partners/', login_required(PartnersListView.as_view()), name='partners'),
     path('partner/', login_required(PartnerDetailView.as_view()), name='partner_detail_my'),
@@ -46,24 +53,26 @@ urlpatterns = [
     #Набор страниц по модели Ресурс
     path('resources/', login_required(ResourcesListView.as_view()), name='resources'),
     #path('resource/<str:pk>', login_required(ResourceDetailView.as_view()), name='resource_detail'),
-#    path('resource/add/', login_required(ResourceCreate.as_view()), name='resource/add/'),
-#    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/add/', login_required(ResourceCreate.as_view()), name='resource/add/'),
+    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('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/<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/add', login_required(ProviderCreate.as_view()), name='provider/add'),
+    # 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_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_tariffs/my/', login_required(ServiceTariffsMyListView.as_view()), name='service_tariffs/my'),
+    # 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/'),
@@ -73,8 +82,7 @@ urlpatterns = [
     #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'),
+    path('service_category/change_status/', change_service_category_status, name='service_category/change_status'),
 
 #CHECK Maybe obsolete
     #path('service_information/add/', login_required(ServiceInformationCreate.as_view()),
@@ -86,10 +94,11 @@ urlpatterns = [
 
 #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('access_control/change_status/', change_permissions_status, name='access_control/change_status'),
+    path('relationship', login_required(RelationshipListView.as_view()), name='relationship'),    
+    path('relationship/change_status/', change_relationship_status, name='relationship/change_status'),
 #    path('active_users', login_required(ActiveUsersListView.as_view()), name='active_users'),
+#    path('user/detail/<int:pk>', login_required(UserDetailView.as_view()), name='user_detail'),
 #    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'),

+ 5 - 4
sharix_admin/views/__init__.py

@@ -5,16 +5,17 @@ from .get_userid import *
 from .staff import *
 from .main import *
 from .partner import *
-from .partner_info import *
-from .partners import *
+#from .partner_info import *
+#from .partners import *
 from .payment import *
 from .provider import *
 from .resource import *
 from .schema import *
 from .service import *
-from .service_info import *
-from .service_tariff import *
+#from .service_info import *
+#from .service_tariff import *
 from .service_category import *
 from .trans_id import *
 from .transactions import *
 from .user_info import *
+from .order import *

+ 4 - 1
sharix_admin/views/base.py

@@ -1,6 +1,8 @@
 from django.contrib.auth.mixins import UserPassesTestMixin
 from django.views import View
 
+from sharix_admin.lib import *
+
 
 class BaseView(UserPassesTestMixin, View):
     """
@@ -24,7 +26,8 @@ class BaseView(UserPassesTestMixin, View):
         context.update({
             'title': self.page_title,
             'current_page': self.page_name,
-            'user_groups': self.user_groups
+            'user_groups': self.user_groups,
+            'avaliable_pages': gen_avaliable_pages(self.user_groups),
         })
 
         return context

+ 4 - 0
sharix_admin/views/cooperate.py

@@ -1,6 +1,8 @@
 from datetime import datetime, timedelta
 from dbsynce.lib.core import parse_requirements, get_admin_url
 from dbsynce.models import Documents
+from dbsynce.models import Permissions
+from dbsynce.models import Relationship
 from django.contrib import messages
 from django.db import transaction
 from django.urls import reverse_lazy
@@ -10,6 +12,7 @@ from tickets.models import Ticket, TicketList
 from sharix_admin.forms import CompanyForm
 from sharix_admin.utils import *
 from dbsynce.lib.data import *
+from dbsynce.lib.dicts import *
 from .base import BaseView
 
 from dbsynce.lib.ticket_gen import *
@@ -17,6 +20,7 @@ from datetime import datetime, timedelta
 from sharix_admin.forms import JobRequestPartnerForm
 from sharix_admin.forms import JobRequestMetaserviceForm
 
+from django.contrib.auth import get_user_model
 
 class CooperateView(BaseView, FormView):
     form_class = CompanyForm

+ 2 - 2
sharix_admin/views/partner_info.py → sharix_admin/views/depr_partner_info.py

@@ -20,7 +20,7 @@ import xmpp
 from xmpp import cli
 
 
-class PartnerInformationCreate(UserPassesTestMixin, CreateView):
+class DeprPartnerInformationCreate(UserPassesTestMixin, CreateView):
     model = Company
     form_class = PartnerInformationCreateForm
     template_name = "sharix_admin/partner_information_form.html"
@@ -62,7 +62,7 @@ class PartnerInformationCreate(UserPassesTestMixin, CreateView):
         return False
 
 
-class PartnerInformationUpdateView(UserPassesTestMixin, UpdateView):
+class DeprPartnerInformationUpdateView(UserPassesTestMixin, UpdateView):
     model = Company
     form_class = PartnerInformationUpdateForm
     template_name = "sharix_admin/partner_information_form.html"

+ 1 - 1
sharix_admin/views/partners.py → sharix_admin/views/depr_partners.py

@@ -9,7 +9,7 @@ from sharix_admin.utils import group_required
 from .base import BaseView
 
 
-class PartnersListView(BaseView, SingleTableView):
+class DeprPartnersListView(BaseView, SingleTableView):
     page_title = _('Partners')
     page_name = 'partners'
     table_class = PartnersTable

+ 0 - 0
sharix_admin/views/service_info.py → sharix_admin/views/depr_service_info.py


+ 3 - 3
sharix_admin/views/service_tariff.py → sharix_admin/views/depr_service_tariff.py

@@ -9,7 +9,7 @@ from sharix_admin.forms import ServiceTariffCreateForm, ServiceTariffUpdateForm
 from sharix_admin.tables import ServiceTariffsTable
 
 
-class ServiceTariffCreate(UserPassesTestMixin, CreateView):
+class DeprServiceCreate(UserPassesTestMixin, CreateView):
     model = Service
     form_class = ServiceTariffCreateForm
     template_name = "sharix_admin/service_tariff_form.html"
@@ -32,7 +32,7 @@ class ServiceTariffCreate(UserPassesTestMixin, CreateView):
         return False
 
 
-class ServiceTariffsListView(UserPassesTestMixin, SingleTableView):
+class DeprServiceListView(UserPassesTestMixin, SingleTableView):
     table_class = ServiceTariffsTable
     queryset = Service.objects.all()
     template_name = 'sharix_admin/service_tariffs.html'
@@ -52,7 +52,7 @@ class ServiceTariffsListView(UserPassesTestMixin, SingleTableView):
         return False
 
 
-class ServiceTariffUpdateView(UserPassesTestMixin, UpdateView):
+class DeprServiceUpdateView(UserPassesTestMixin, UpdateView):
     model = Service
     form_class = ServiceTariffUpdateForm
     template_name = "sharix_admin/service_tariff_form.html"

+ 140 - 0
sharix_admin/views/order.py

@@ -0,0 +1,140 @@
+from dbsynce.models import Orders
+from django.contrib.auth.decorators import login_required
+from django.contrib.auth.mixins import UserPassesTestMixin
+from django.http import JsonResponse
+from django.utils.translation import gettext as _
+from django_tables2 import SingleTableView
+from sharix_admin.tables import OrdersTable
+from sharix_admin.utils import group_required
+from datetime import datetime, timedelta
+from dbsynce.lib.core import parse_requirements, get_admin_url
+from dbsynce.models import Documents
+from django.contrib import messages
+from django.db import transaction
+from django.urls import reverse_lazy
+from django.views.generic.edit import FormView
+from django.views.generic import DetailView
+from tickets.models import Ticket, TicketList
+from sharix_admin.forms import OrderForm
+from sharix_admin.utils import *
+from dbsynce.lib.data import *
+from .base import BaseView
+from django.db.models import Q
+
+class OrdersListView(BaseView, SingleTableView):
+#class OrdersListView(UserPassesTestMixin, SingleTableView):
+    table_class = OrdersTable
+    queryset = Orders.objects.all()
+    template_name = 'sharix_admin/orders.html'
+    page_title = 'Заказы'
+    page_name = 'orders'
+
+    def get_context_data(self, **kwargs):
+        context = super().get_context_data(**kwargs)
+        context.update({
+            'title': _('Orders'),
+            'object_list': context['object_list'],
+        })
+        return context
+
+    def get_queryset(self):
+        queryset = super().get_queryset()
+        search_query = self.request.GET.get('q', '').strip()
+        if search_query:
+            queryset = queryset.filter(
+                Q(id__icontains=search_query) |
+                Q(user__first_name__icontains=search_query) | 
+                Q(user__first_name__icontains=search_query) |
+                Q(status__icontains=search_query)
+            ).distinct()
+        return queryset
+
+    def testing(self, queryset, is_descending):
+        queryset = queryset.annotate.order_by("-" if is_descending else "")
+        return (queryset, True)
+
+    def test_func(self) -> bool or None:
+        return True
+
+@login_required
+@group_required('PARTNER-SUPERVISOR')
+def change_order_local_status(request):
+    if request.method == 'POST':
+        order_id = request.POST.get('order_local') 
+        new_status = request.POST.get('new_status')
+
+        try:
+            order = Orders.objects.get(pk=order_id)
+            order.status = new_status
+            order.save()
+            return JsonResponse({'status': 'success'})
+        except Orders.DoesNotExist:
+            return JsonResponse({'status': 'error', 'message': 'Order not found'}, status=404)
+    return JsonResponse({'status': 'error'}, status=400)
+
+class OrdersEditView(BaseView, FormView):
+    form_class = OrderForm
+    template_name = "sharix_admin/order.html"
+    success_url = reverse_lazy("sharix_admin:order")
+    page_title = 'Изменить заказ'
+    page_name = 'order_edit'
+
+    def test_func(self):
+        return "CLIENT" in self.user_groups
+
+    def form_valid(self, form):
+        with transaction.atomic():
+            instance = form.save(commit=False)
+            instance.repr = self.request.user
+            instance.save()
+            instance.ticket_status = create_ticket_order_local_activation_by_metaservice_supervisor(self.request.user, instance)
+            instance.save()
+            doc_codes = parse_requirements(instance.requirements)
+            Documents.objects.bulk_create([
+                Documents(
+                    order_local=instance, 
+                    user=self.request.user,
+                    doc_type=doc_code
+                ) for doc_code in doc_codes
+            ])
+        messages.success(self.request, 'Заказ успешно обновлён!')
+        return super().form_valid(form)
+
+class OrdersCreate(BaseView, FormView):
+    form_class = OrderForm
+    template_name = "sharix_admin/order.html"
+    success_url = reverse_lazy("sharix_admin:order")
+    page_title = 'Добавить заказ'
+    page_name = 'order/add/'
+
+    def test_func(self):
+        return not "CLIENT" in self.user_groups
+
+    def form_valid(self, form):
+        with transaction.atomic():
+            instance = form.save(commit=False)
+            instance.repr = self.request.user
+            instance.save()
+            instance.ticket_status = create_ticket_order_local_activation_by_metaservice_supervisor(self.request.user, instance)
+            create_ticket_order_local_activation_by_partner_admin(self.request.user, instance)
+            instance.save()
+            doc_codes = parse_requirements(instance.requirements)
+            Documents.objects.bulk_create([
+                Documents(
+                    order_local=instance,
+                    user=self.request.user,
+                    doc_type=doc_code
+                ) for doc_code in doc_codes
+            ])
+        messages.success(self.request, 'Заказ успешно создан!')
+        return super().form_valid(form)
+
+class OrdersDetailView(BaseView, DetailView):
+    model = Orders
+    template_name = 'sharix_admin/order.html'
+    context_object_name = 'order'
+
+    def get_context_data(self, **kwargs):
+        context = super().get_context_data(**kwargs)
+        context['title'] = _('Order Details')
+        return context

+ 58 - 9
sharix_admin/views/partner.py

@@ -15,6 +15,14 @@ from django.contrib.auth.mixins import UserPassesTestMixin
 from django_tables2 import SingleTableView
 from sharix_admin.tables import PartnersTable
 
+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 sharix_admin.tables import PartnersTable
+from sharix_admin.utils import group_required
+
 class PartnerBaseView(BaseView):
     page_name = 'partner'
 
@@ -172,23 +180,64 @@ class PartnerDocView(PartnerBaseView, DetailView):
         return context
 
 
-class PartnersListView(UserPassesTestMixin, SingleTableView):
+class PartnersListView(PartnerBaseView, UserPassesTestMixin, SingleTableView):
+    page_title = _('Партнеры')
+    page_name = 'partners'
     table_class = PartnersTable
     queryset = Company.objects.all()
-    template_name = 'sharix_admin/service_tariffs.html'
+    template_name = 'sharix_admin/partners.html'
+
+    def get_queryset(self):
+        queryset = super().get_queryset()
+        search_query = self.request.GET.get('q', '').strip()
+        if search_query:
+            queryset = queryset.filter(
+                Q(id__icontains=search_query) |
+                Q(legalname__icontains=search_query) |
+                Q(inn__icontains=search_query) |
+                Q(orgn__icontains=search_query) |
+                Q(address__icontains=search_query)
+            ).distinct()
+        return queryset
 
     def get_context_data(self, **kwargs):
         context = super().get_context_data(**kwargs)
-        context.update(get_context(self.request, {
-            'title': _('Performers'),
+        context.update({
             'object_list': context['object_list'],
-        }))
+        })
         return context
 
+    def testing(self, queryset, is_descending):
+        queryset = queryset.annotate.order_by("-" if is_descending else "")
+        return (queryset, True)
+
+
+#    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
+    #    group_names = ('PARTNER-ADMIN')
+    #    if bool(self.request.user.groups.filter(name=group_names)) or self.request.user.is_superuser:
+    #        return True
+    #    return False
+        return True
+
+@login_required
+@group_required('METASERVICE-ADMIN')
+def change_partner_status(request):
+    if request.method == 'POST':
+        partners_id = request.POST.get('partners_id')
+        new_status = request.POST.get('new_status')
+        partners = Company.objects.get(pk=partners_id)
+        partners.status = new_status
+        partners.save()
+        return JsonResponse({'status': 'success'})
+    else:
+        return JsonResponse({'status': 'error'})
 
 

+ 99 - 6
sharix_admin/views/provider.py

@@ -8,12 +8,105 @@ from django_tables2 import SingleTableView
 from sharix_admin.tables import ProvidersTable
 from sharix_admin.utils import group_required
 
+from .base import BaseView
 
-class ProvidersListView(UserPassesTestMixin, SingleTableView):
+from sharix_admin.utils import group_required
+from django.contrib.auth.decorators import login_required
+from django.urls import reverse_lazy
+from django.views.generic.edit import FormView
+from django.db import transaction
+from django.contrib import messages
+
+
+from tickets.models import Ticket, TicketList
+
+from sharix_admin.forms import CompanyForm
+from sharix_admin.utils import *
+from dbsynce.lib.data import *
+from dbsynce.lib.dicts import *
+
+from sharix_admin.forms import ProviderCreateForm
+#from sharix_admin.forms import ProviderUpdateForm
+
+class ProviderCreate(BaseView, FormView):
+    form_class = ProviderCreateForm
+    template_name = "sharix_admin/provider_form.html"
+    success_url = reverse_lazy("sharix_admin:providers")
+    page_title = 'Добавить услугу к исполнению'
+    page_name = 'providers/add/'
+
+    # Проверяем не состояит ли текущий пользователь в группе METASERVICE-ADMIN
+    def test_func(self):
+        group_names = ('PROVIDER')
+        if bool(self.request.user.groups.filter(name=group_names)): #or self.request.user.is_superuser:
+            return True
+        return False
+            #return not "METASERVICE-ADMIN" in self.user_groups
+
+    def form_valid(self, form):
+        with transaction.atomic():
+            # Сохраняем форму, чтобы получить объект компании
+            instance = form.save(commit=False)
+
+            # Присваиваем полю repr идентификатор текущего пользователя
+            #instance.repr = self.request.user
+
+            # Создаем новую запись в БД, чтобы иметь доступ к ID
+            instance.save()
+
+            #TODO ADD INTEGRATION WITH PLATFORM!
+            # Создание тикета на активацию Категории услуг на Платформе.
+            # Создаем объект тикета и присваиваем его полю ticket_status
+            #instance.ticket_status = create_ticket_company_activation(self.request.user, instance)
+            instance.ticket_status = create_ticket_provider_activation_by_partner_admin(self.request.user, instance)
+
+            # Создание тикета на утверждение прав пользователя
+            #create_ticket_role_activation_partner_admin(self.request.user, instance)
+
+            # Сохраняем новые изменения
+            instance.save()
+
+            #TODO! Это делать на платформе!
+            # Создаем необходимые объекты документов по requirements указанных в созданной company
+            # Используем bulk_create для создания всех объектов одновременно
+            #doc_codes = parse_requirements(instance.requirements)
+            #Documents.objects.bulk_create([
+            #    Documents(
+            #        company=instance,
+            #        user=self.request.user,
+            #        doc_type=doc_code
+            #    ) for doc_code in doc_codes
+            #])
+
+        # Отправляем пользователю уведомление на страницу о успехе операции
+        messages.success(
+            self.request,
+            'Ваша заявка на добавление категории услуг успешно отправлена на Платформу и теперь проходит проверку! Если Сервис не подключен к Платформе, можете активировать категорию услуг в списке вручную.'
+        )
+
+        return super().form_valid(form)  # Возвращаем успешный ответ
+
+
+class ProvidersListView(BaseView, UserPassesTestMixin, SingleTableView):
+
+    page_title = _('Исполнители по видам услуг')
+    page_name = 'providers'
     table_class = ProvidersTable
     queryset = Provider.objects.all()
     template_name = 'sharix_admin/providers.html'
 
+    def get_queryset(self):
+        queryset = super().get_queryset()
+        search_query = self.request.GET.get('q', '').strip()
+        if search_query:
+            queryset = queryset.filter(
+                Q(id__icontains=search_query) |
+                Q(service_status__icontains=search_query) |
+                Q(service__icontains=search_query) |
+                Q(resource__icontains=search_query)
+            ).distinct()
+        return queryset
+
     def get_context_data(self, **kwargs):
         context = super().get_context_data(**kwargs)
         context.update({
@@ -23,11 +116,11 @@ class ProvidersListView(UserPassesTestMixin, SingleTableView):
         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
-
+    #    group_names = ('PARTNER-ADMIN')
+    #    if bool(self.request.user.groups.filter(name=group_names)) or self.request.user.is_superuser:
+    #        return True
+    #    return False
+        return True
 
 @login_required
 @group_required('PARTNER-ADMIN')

+ 139 - 6
sharix_admin/views/resource.py

@@ -9,10 +9,27 @@ from sharix_admin.tables import ResourcesTable
 from sharix_admin.utils import group_required
 
 
-class ResourcesListView(UserPassesTestMixin, SingleTableView):
+from datetime import datetime, timedelta
+from dbsynce.lib.core import parse_requirements, get_admin_url
+from dbsynce.models import Documents
+from django.contrib import messages
+from django.db import transaction
+from django.urls import reverse_lazy
+from django.views.generic.edit import FormView
+from tickets.models import Ticket, TicketList
+
+from sharix_admin.forms import ResourceForm
+from sharix_admin.utils import *
+from dbsynce.lib.data import *
+from .base import BaseView
+from django.db.models import Q
+
+class ResourcesListView(BaseView, UserPassesTestMixin, SingleTableView):
     table_class = ResourcesTable
     queryset = Resource.objects.all()
-    template_name = 'sharix_admin/resources.html'
+    template_name = 'sharix_admin/resource_list.html'
+    page_title = 'Ресурсы'
+    page_name = 'resources'
 
     def get_context_data(self, **kwargs):
         context = super().get_context_data(**kwargs)
@@ -22,11 +39,24 @@ class ResourcesListView(UserPassesTestMixin, SingleTableView):
         })
         return context
 
+    def get_queryset(self):
+        queryset = super().get_queryset()
+        search_query = self.request.GET.get('q', '').strip()
+        if search_query:
+            queryset = queryset.filter(
+                Q(id__icontains=search_query) |
+                Q(user__first_name__icontains=search_query) |
+                Q(user__last_name__icontains=search_query) |
+                Q(status__icontains=search_query)
+            ).distinct()
+        return queryset
+
     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
+        #group_names = ('PARTNER-ADMIN')
+        #if bool(self.request.user.groups.filter(name=group_names)) or self.request.user.is_superuser:
+        #    return True
+        #return False
+        return True
 
 
 @login_required
@@ -42,3 +72,106 @@ def change_resource_status(request):
         return JsonResponse({'status': 'success'})
     else:
         return JsonResponse({'status': 'error'})
+
+class ResourceEditView(BaseView, FormView):
+    form_class = ResourceForm
+    template_name = "sharix_admin/resource.html"
+    success_url = reverse_lazy("sharix_admin:resource_list")
+    page_title = 'Изменить ресурс'
+    page_name = 'resource_edit'
+
+    # Проверяем состояит ли текущий пользователь в группе PARTNER-ADMIN
+    def test_func(self):
+        return "PARTNER-ADMIN" in self.user_groups
+
+    def form_valid(self, form):
+        with transaction.atomic():
+            # Сохраняем форму, чтобы получить объект ресурса
+            instance = form.save(commit=False)
+
+            # Присваиваем полю repr идентификатор текущего пользователя
+            instance.repr = self.request.user
+
+            # Создаем новую запись в БД, чтобы иметь доступ к ID
+            instance.save()
+
+            # Создание тикета на активацию ресурса.
+            # Создаем объект тикета и присваиваем его полю ticket_status
+            instance.ticket_status = create_ticket_resource_activation_by_metaservice_supervisor(self.request.user, instance)
+
+            # Создание тикета на утверждение прав пользователя
+            # create_ticket_role_activation_partner_admin(self.request.user, instance)
+
+            # Сохраняем новые изменения
+            instance.save()
+
+            # Создаем необходимые объекты документов по requirements указанных в созданной company
+            # Используем bulk_create для создания всех объектов одновременно
+            doc_codes = parse_requirements(instance.requirements)
+            Documents.objects.bulk_create([
+                Documents(
+                    company=instance,
+                    user=self.request.user,
+                    doc_type=doc_code
+                ) for doc_code in doc_codes
+            ])
+
+        # Отправляем пользователю уведомление на страницу о успехе операции
+        messages.success(
+            self.request,
+            'Ваша заявка на становление партнером успешно отправлена и теперь проходит проверку!'
+        )
+
+        return super().form_valid(form)  # Возвращаем успешный ответ
+
+class ResourceCreate(BaseView, FormView):
+    form_class = ResourceForm
+    template_name = "sharix_admin/resource.html"
+    success_url = reverse_lazy("sharix_admin:main")
+    page_title = 'Добавить ресурс'
+    page_name = 'resource/add/'
+
+    # Проверяем не состояит ли текущий пользователь в группе PARTNER-ADMIN
+    def test_func(self):
+        return not "PARTNER-ADMIN" in self.user_groups
+
+    def form_valid(self, form):
+        with transaction.atomic():
+            # Сохраняем форму, чтобы получить объект компании
+            instance = form.save(commit=False)
+
+            # Присваиваем полю repr идентификатор текущего пользователя
+            instance.repr = self.request.user
+
+            # Создаем новую запись в БД, чтобы иметь доступ к ID
+            instance.save()
+
+            # Создание тикета на активацию ресурса.
+            # Создаем объект тикета и присваиваем его полю ticket_status
+            instance.ticket_status = create_ticket_resource_activation_by_metaservice_supervisor(self.request.user, instance)
+
+            # Создание тикета на утверждение прав пользователя
+            create_ticket_resource_activation_by_partner_admin(self.request.user, instance)
+
+            # Сохраняем новые изменения
+            instance.save()
+
+            # Создаем необходимые объекты документов по requirements указанных в созданной company
+            # Используем bulk_create для создания всех объектов одновременно
+            doc_codes = parse_requirements(instance.requirements)
+            Documents.objects.bulk_create([
+                Documents(
+                    #TODO add info about company
+                    resource=instance,
+                    user=self.request.user,
+                    doc_type=doc_code
+                ) for doc_code in doc_codes
+            ])
+
+        # Отправляем пользователю уведомление на страницу о успехе операции
+        messages.success(
+            self.request,
+            'Ваша заявка на становление партнером успешно отправлена и теперь проходит проверку!'
+        )
+
+        return super().form_valid(form)  # Возвращаем успешный ответ

+ 195 - 5
sharix_admin/views/service.py

@@ -7,10 +7,200 @@ from django_tables2 import SingleTableView
 from sharix_admin.tables import ServiceTable
 from sharix_admin.utils import group_required
 
+from django.views.generic.edit import UpdateView, CreateView, DeleteView
+from sharix_admin.forms import ServiceTariffCreateForm, ServiceTariffUpdateForm
+from sharix_admin.tables import ServiceTariffsTable
+from .base import BaseView
 
-class ServiceListView(UserPassesTestMixin, SingleTableView):
-    table_class = ServiceTable
+from sharix_admin.utils import group_required
+from django.contrib.auth.decorators import login_required
+from django.urls import reverse_lazy
+from django.views.generic.edit import FormView
+from django.db import transaction
+from django.contrib import messages
+
+from django.db.models import Q
+from django.contrib.auth.mixins import UserPassesTestMixin
+
+from tickets.models import Ticket, TicketList
+
+from sharix_admin.utils import *
+from dbsynce.lib.data import *
+
+class ServiceTariffCreate(BaseView, FormView):
+    form_class = ServiceTariffCreateForm
+    template_name = "sharix_admin/service_tariff_form.html"
+    success_url = reverse_lazy("sharix_admin:service_tariffs")
+    page_title = 'Добавить тариф к категории услуг'
+    page_name = 'service_tariff/add/'
+
+    # Проверяем не состояит ли текущий пользователь в группе METASERVICE-ADMIN
+    def test_func(self):
+        group_names = ('PARTNER-ADMIN')
+        #group_names = ('PARTNER-ADMIN', 'PARTNER-SUPERVISOR')
+        if bool(self.request.user.groups.filter(name=group_names)): #or self.request.user.is_superuser:
+            return True
+        return False
+            #return not "METASERVICE-ADMIN" in self.user_groups
+
+    def form_valid(self, form):
+        with transaction.atomic():
+            # Сохраняем форму, чтобы получить объект компании
+            instance = form.save(commit=False)
+            
+            #TODO Присвоить по аналогии company?
+            # Присваиваем полю repr идентификатор текущего пользователя
+            #instance.repr = self.request.user
+
+            # Создаем новую запись в БД, чтобы иметь доступ к ID
+            instance.save()
+
+            #TODO ADD INTEGRATION WITH PLATFORM!
+            # Создание тикета на активацию Категории услуг на Платформе.
+            # Создаем объект тикета и присваиваем его полю ticket_status
+            instance.ticket_status = create_ticket_service_activation(self.request.user, instance)
+
+            # Создание тикета на утверждение прав пользователя
+            #create_ticket_role_activation_partner_admin(self.request.user, instance)
+
+            # Сохраняем новые изменения
+            instance.save()
+
+            #TODO! Это делать на платформе!
+            # Создаем необходимые объекты документов по requirements указанных в созданной company
+            # Используем bulk_create для создания всех объектов одновременно
+            #doc_codes = parse_requirements(instance.requirements)
+            #Documents.objects.bulk_create([
+            #    Documents(
+            #        company=instance,
+            #        user=self.request.user,
+            #        doc_type=doc_code
+            #    ) for doc_code in doc_codes
+            #])
+
+        # Отправляем пользователю уведомление на страницу о успехе операции
+        messages.success(
+            self.request,
+            'Ваша заявка на добавление категории услуг успешно отправлена на Платформу и теперь проходит проверку! Если Сервис не подключен к Платформе, можете активировать категорию услуг в списке вручную.'
+        )
+
+        return super().form_valid(form)  # Возвращаем успешный ответ
+
+
+#class ServiceListView(UserPassesTestMixin, SingleTableView):
+class ServiceTariffsListView(BaseView, SingleTableView):
+    page_title = _('Тарифы сервиса')
+    page_name = 'service_tariff'
+    table_class = ServiceTariffsTable
     queryset = Service.objects.all()
+    template_name = 'sharix_admin/service_tariffs.html'
+
+    def get_queryset(self):
+        queryset = super().get_queryset()
+        search_query = self.request.GET.get('q', '').strip()
+        if search_query:
+            queryset = queryset.filter(
+                Q(id__icontains=search_query) |
+                Q(service_category__icontains=search_query) |
+                Q(resource__icontains=search_query) |
+                Q(company__icontains=search_query)
+            ).distinct()
+        return queryset
+
+    def get_context_data(self, **kwargs):
+        context = super().get_context_data(**kwargs)
+        context.update({
+            'object_list': context['object_list'],
+        })
+        return context
+
+    def testing(self, queryset, is_descending):
+        queryset = queryset.annotate.order_by("-" if is_descending else "")
+        return (queryset, True)
+
+    def test_func(self) -> bool or None:
+        return True
+    #    group_names = ('METASERVICE-ADMIN')
+    #    if bool(self.request.user.groups.filter(name=group_names)) or self.request.user.is_superuser:
+    #        return True
+    #    return False
+
+
+class ServiceTariffUpdateView(BaseView, UpdateView):
+    model = Service
+    page_title = _('Редактирование тарифов услуг Сервиса')
+    form_class = ServiceTariffUpdateForm
+    success_url = reverse_lazy("sharix_admin:service_tariffs")
+    template_name = "sharix_admin/service_tariff_form.html"
+    page_name = 'service_tariff/edit/'
+
+    def get_context_data(self, **kwargs):
+        context = super().get_context_data(**kwargs)
+        context.update({
+            'title': _('Тарифы услуг сервиса'),
+            'object': self.object,
+            "current_page": "sharix_admin:service_tariffs"
+        })
+        return context
+
+    def test_func(self) -> bool or None:
+        #TODO: Add a check a user belongs to a company!
+        group_names = ('PARTNER-ADMIN')
+        #group_names = ('METASERVICE-SUPERVISOR','PARTNER-ADMIN')
+        if bool(self.request.user.groups.filter(name=group_names)):
+            return True
+        return False
+
+    #def get_success_url(self):
+    #    return success_url
+        #return reverse_lazy('sharix_admin:service_categories')
+
+    def form_valid(self, form):
+        with transaction.atomic():
+            # Сохраняем форму, чтобы получить объект
+            instance = form.save(commit=False)
+
+            #деактивируем измененную сущность
+            instance.status = "1"
+
+            # Создаем новую запись в БД, чтобы иметь доступ к ID
+            instance.save()
+
+            # Создание тикета на активацию тарифа услуги.
+            # Создаем объект тикета и присваиваем его полю ticket_status
+            instance.ticket_status = create_ticket_service_activation(self.request.user, instance)
+
+            # Создание тикета на утверждение прав пользователя
+            # create_ticket_role_activation_partner_admin(self.request.user, instance)
+
+            # Сохраняем новые изменения
+            instance.save()
+
+            #TODO CHECK IF DOCUMENTS NEEDED
+            # Создаем необходимые объекты документов по requirements указанных в созданной company
+            # Используем bulk_create для создания всех объектов одновременно
+            #doc_codes = parse_requirements(instance.requirements)
+            #Documents.objects.bulk_create([
+            #    Documents(
+            #        company=instance,
+            #        user=self.request.user,
+            #        doc_type=doc_code
+            #    ) for doc_code in doc_codes
+            #])
+
+        # Отправляем пользователю уведомление на страницу о успехе операции
+        messages.success(
+            self.request,
+            'Ваша заявка на изменение тарифов услуг успешно отправлена и теперь проходит проверку!'
+        )
+
+        return super().form_valid(form)  # Возвращаем успешный ответ
+
+class ServiceTariffsMyListView(BaseView, SingleTableView):
+#class ServiceListView(UserPassesTestMixin, SingleTableView):
+    table_class = ServiceTable
+    #TODO change to concrete company
+    #queryset = Service.objects.all()
     template_name = 'sharix_admin/service.html'
 
     def get_context_data(self, **kwargs):
@@ -22,14 +212,14 @@ class ServiceListView(UserPassesTestMixin, SingleTableView):
         return context
 
     def test_func(self) -> bool or None:
-        group_names = ('PROVIDER')
-        if bool(self.request.user.groups.filter(name=group_names)) or self.request.user.is_superuser:
+        group_names = ('PARTNER-ADMIN','PARTNER-SUPERVISOR','PROVIDER')
+        if bool(self.request.user.groups.filter(name=group_names)):
             return True
         return False
 
 
 @login_required
-@group_required('PROVIDER')
+@group_required('METASERVICE_SUPERVISOR')
 def change_service_status(request):
     if request.method == 'POST':
         service_id = request.POST.get('service_id')

+ 193 - 51
sharix_admin/views/service_category.py

@@ -8,38 +8,118 @@ from sharix_admin.forms import ServiceCategoryCreateForm, ServiceCategoryUpdateF
 from sharix_admin.tables import ServiceCategoriesTable
 from .base import BaseView
 
+from sharix_admin.utils import group_required
+from django.contrib.auth.decorators import login_required
+from django.urls import reverse_lazy
+from django.views.generic.edit import FormView
+from django.db import transaction
+from django.contrib import messages
 
-class ServiceCategoryCreate(BaseView, CreateView):
-    page_title = _('Услуги сервиса')
-    page_name = 'service_category'
-    model = ServiceCategory
+from django.db.models import Q
+from django.contrib.auth.mixins import UserPassesTestMixin
+
+class ServiceCategoryCreate(BaseView, FormView):
     form_class = ServiceCategoryCreateForm
     template_name = "sharix_admin/service_category_form.html"
+    success_url = reverse_lazy("sharix_admin:service_categories")
+    page_title = 'Добавить категорию услуг'
+    page_name = 'service_category/add/'
 
-    def get_context_data(self, **kwargs):
-        context = super().get_context_data(**kwargs)
-        context.update({
-            'object': self.object,
-        })
-        return context
-
-    def get_success_url(self):
-        return reverse('service_category')
-
-    def test_func(self) -> bool or None:
+    # Проверяем не состояит ли текущий пользователь в группе METASERVICE-ADMIN
+    def test_func(self):
         group_names = ('METASERVICE-ADMIN')
-        if bool(self.request.user.groups.filter(name=group_names)) or self.request.user.is_superuser:
+        if bool(self.request.user.groups.filter(name=group_names)): #or self.request.user.is_superuser:
             return True
         return False
-
-
+            #return not "METASERVICE-ADMIN" in self.user_groups
+
+    def form_valid(self, form):
+        with transaction.atomic():
+            # Сохраняем форму, чтобы получить объект компании
+            instance = form.save(commit=False)
+
+            # Присваиваем полю repr идентификатор текущего пользователя
+            instance.repr = self.request.user
+
+            # Создаем новую запись в БД, чтобы иметь доступ к ID
+            instance.save()
+
+            #TODO ADD INTEGRATION WITH PLATFORM!
+            # Создание тикета на активацию Категории услуг на Платформе.
+            # Создаем объект тикета и присваиваем его полю ticket_status
+            #instance.ticket_status = create_ticket_company_activation(self.request.user, instance)
+
+            # Создание тикета на утверждение прав пользователя
+            #create_ticket_role_activation_partner_admin(self.request.user, instance)
+
+            # Сохраняем новые изменения
+            instance.save()
+
+            #TODO! Это делать на платформе!
+            # Создаем необходимые объекты документов по requirements указанных в созданной company
+            # Используем bulk_create для создания всех объектов одновременно
+            #doc_codes = parse_requirements(instance.requirements)
+            #Documents.objects.bulk_create([
+            #    Documents(
+            #        company=instance,
+            #        user=self.request.user,
+            #        doc_type=doc_code
+            #    ) for doc_code in doc_codes
+            #])
+
+        # Отправляем пользователю уведомление на страницу о успехе операции
+        messages.success(
+            self.request,
+            'Ваша заявка на добавление категории услуг успешно отправлена на Платформу и теперь проходит проверку! Если Сервис не подключен к Платформе, можете активировать категорию услуг в списке вручную.'
+        )
+
+        return super().form_valid(form)  # Возвращаем успешный ответ
+
+
+#class ServiceCategoryCreate(BaseView, CreateView):
+#    page_title = _('Услуги сервиса')
+#    page_name = 'service_category'
+#    model = ServiceCategory
+#    form_class = ServiceCategoryCreateForm
+#    template_name = "sharix_admin/service_category_form.html"
+#
+#    def get_context_data(self, **kwargs):
+#        context = super().get_context_data(**kwargs)
+#        context.update({
+#            'object': self.object,
+#        })
+#        return context
+#
+#    def get_success_url(self):
+#        return reverse('service_category')
+#
+#    def test_func(self) -> bool or None:
+#        group_names = ('METASERVICE-ADMIN')
+#        if bool(self.request.user.groups.filter(name=group_names)) or self.request.user.is_superuser:
+#            return True
+#        return False
+
+
+#class ServiceCategoriesListView(UserPassesTestMixin, SingleTableView):
 class ServiceCategoriesListView(BaseView, SingleTableView):
     page_title = _('Услуги сервиса')
-    page_name = 'service_category'
+    page_name = 'service_categories'
     table_class = ServiceCategoriesTable
     queryset = ServiceCategory.objects.all()
     template_name = 'sharix_admin/service_categories.html'
 
+    def get_queryset(self):
+        queryset = super().get_queryset()
+        search_query = self.request.GET.get('q', '').strip()
+        if search_query:
+            queryset = queryset.filter(
+                Q(id__icontains=search_query) |
+                Q(caption__icontains=search_query) |
+                Q(codename__icontains=search_query) |
+                Q(description__icontains=search_query)
+            ).distinct()
+        return queryset
+
     def get_context_data(self, **kwargs):
         context = super().get_context_data(**kwargs)
         context.update({
@@ -51,24 +131,28 @@ class ServiceCategoriesListView(BaseView, SingleTableView):
         queryset = queryset.annotate.order_by("-" if is_descending else "")
         return (queryset, True)
 
-    def test_func(self) -> bool or None:
-        group_names = ('METASERVICE-ADMIN')
-        if bool(self.request.user.groups.filter(name=group_names)) or self.request.user.is_superuser:
-            return True
-        return False
+    #def test_func(self) -> bool or None:
+    #    return True
+    #    group_names = ('METASERVICE-ADMIN')
+    #    if bool(self.request.user.groups.filter(name=group_names)) or self.request.user.is_superuser:
+    #        return True
+    #    return False
 
 
 class ServiceCategoryUpdateView(BaseView, UpdateView):
     model = ServiceCategory
-    form_class = ServiceCategoryCreateForm
+    page_title = _('Редактирование услуг Сервиса')
+    form_class = ServiceCategoryUpdateForm
+    success_url = reverse_lazy("sharix_admin:service_categories")
     template_name = "sharix_admin/service_category_form.html"
+    page_name = 'service_category/edit/'
 
     def get_context_data(self, **kwargs):
         context = super().get_context_data(**kwargs)
         context.update({
             'title': _('Услуги сервиса'),
             'object': self.object,
-            "current_page": "service_category"
+            "current_page": "sharix_admin:service_categories"
         })
         return context
 
@@ -78,28 +162,86 @@ class ServiceCategoryUpdateView(BaseView, UpdateView):
             return True
         return False
 
-    def get_success_url(self):
-        return reverse('service_category')
-
-
-class ServiceCategoryDelete(BaseView, DeleteView):
-    model = ServiceCategory
-    template_name = "sharix_admin/service_category_delete.html"
-
-    def get_context_data(self, **kwargs):
-        context = super().get_context_data(**kwargs)
-        context.update({
-            'title': 'Услуги сервиса',
-            'object': self.object,
-            "current_page": "service_category"
-        })
-        return context
-
-    def get_success_url(self):
-        return reverse('service_category')
-
-    def test_func(self) -> bool or None:
-        group_names = ('METASERVICE-ADMIN')
-        if bool(self.request.user.groups.filter(name=group_names)) or self.request.user.is_superuser:
-            return True
-        return False
+    #def get_success_url(self):
+    #    return success_url
+        #return reverse_lazy('sharix_admin:service_categories')
+
+    def form_valid(self, form):
+        with transaction.atomic():
+            # Сохраняем форму, чтобы получить объект ресурса
+            instance = form.save(commit=False)
+
+            # Присваиваем полю repr идентификатор текущего пользователя
+            instance.repr = self.request.user
+
+            # Создаем новую запись в БД, чтобы иметь доступ к ID
+            instance.save()
+
+            #TODO ADD INTEGRATION WITH PLATFORM
+
+            # Создание тикета на активацию категории услуги.
+            # Создаем объект тикета и присваиваем его полю ticket_status
+            #instance.ticket_status = create_ticket_resource_activation_by_metaservice_supervisor(self.request.user, instance)
+
+            # Создание тикета на утверждение прав пользователя
+            # create_ticket_role_activation_partner_admin(self.request.user, instance)
+
+            # Сохраняем новые изменения
+            instance.save()
+
+            #TODO ADD INTEGRATION WITH PLATFORM
+            # Создаем необходимые объекты документов по requirements указанных в созданной company
+            # Используем bulk_create для создания всех объектов одновременно
+            #doc_codes = parse_requirements(instance.requirements)
+            #Documents.objects.bulk_create([
+            #    Documents(
+            #        company=instance,
+            #        user=self.request.user,
+            #        doc_type=doc_code
+            #    ) for doc_code in doc_codes
+            #])
+
+        # Отправляем пользователю уведомление на страницу о успехе операции
+        messages.success(
+            self.request,
+            'Ваша заявка на изменение категории услуг успешно отправлена и теперь проходит проверку! Если Сервис не подключен к платформе - актифируйте самостоятельно.'
+        )
+
+        return super().form_valid(form)  # Возвращаем успешный ответ
+
+
+#class ServiceCategoryDelete(BaseView, DeleteView):
+#    model = ServiceCategory
+#    template_name = "sharix_admin/service_category_delete.html"
+#
+#    def get_context_data(self, **kwargs):
+#        context = super().get_context_data(**kwargs)
+#        context.update({
+#            'title': 'Услуги сервиса',
+#            'object': self.object,
+#            "current_page": "service_category"
+#        })
+#        return context
+#
+#    def get_success_url(self):
+#        return reverse('service_category')
+#
+#    def test_func(self) -> bool or None:
+#        group_names = ('METASERVICE-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('METASERVICE-ADMIN')
+def change_service_category_status(request):
+    if request.method == 'POST':
+        service_category = request.POST.get('resource')
+        new_status = request.POST.get('new_status')
+
+        service_category = ServiceCategory.objects.get(pk=service_category)
+        service_category.status = new_status
+        service_category.save()
+        return JsonResponse({'status': 'success'})
+    else:
+        return JsonResponse({'status': 'error'})

+ 44 - 6
sharix_admin/views/staff.py

@@ -23,10 +23,12 @@ from django.utils.translation import gettext as _
 
 
 #TODO This is abslutely incorrect, custom page needed!
-class AccessControlListView(UserPassesTestMixin, SingleTableView):
+class AccessControlListView(BaseView, UserPassesTestMixin, SingleTableView):
     table_class = PermissionsTable
     queryset = Permissions.objects.all()
     template_name = 'sharix_admin/staff/access_control.html'
+    page_title = 'Управление правами доступа'
+    page_name = 'access_control'
 
     def get_context_data(self, **kwargs):
         context = super().get_context_data(**kwargs)
@@ -37,18 +39,31 @@ class AccessControlListView(UserPassesTestMixin, SingleTableView):
         })
         return context
 
+    def get_queryset(self):
+        queryset = super().get_queryset()
+        search_query = self.request.GET.get('q', '').strip()
+        if search_query:
+            queryset = queryset.filter(
+                Q(id__icontains=search_query) |
+                Q(user__icontains=search_query) |
+                Q(checked_by__icontains=search_query) |
+                Q(expire_date__icontains=search_query)
+            ).distinct()
+        return queryset
+
     def test_func(self) -> bool or None:
-        group_names = ('PLATFORM-ADMIN')
+        group_names = ('METASERVICE-ADMIN')
         if bool(self.request.user.groups.filter(name=group_names)) or self.request.user.is_superuser:
             return True
         return False
+    #    return True
 
 class RelationshipListView(BaseView, SingleTableView):
     page_title = _('Relationship')
     page_name = 'relationship'
     table_class = RelationshipTable
     queryset = Relationship.objects.all()
-    template_name = 'sharix_admin/staff/relationship.html'
+    template_name = 'sharix_admin/staff/access_control.html'
 
     def get_context_data(self, **kwargs):
         context = super().get_context_data(**kwargs)
@@ -57,8 +72,20 @@ class RelationshipListView(BaseView, SingleTableView):
         })
         return context
 
+    def get_queryset(self):
+        queryset = super().get_queryset()
+        search_query = self.request.GET.get('q', '').strip()
+        if search_query:
+            queryset = queryset.filter(
+                Q(id__icontains=search_query) |
+                Q(user_who__icontains=search_query) |
+                Q(user_whom__icontains=search_query) |
+                Q(neg_type__icontains=search_query)
+            ).distinct()
+        return queryset
+
     def test_func(self):
-        group_names = ('PLATFORM-ADMIN')
+        group_names = ('METASERVICE-ADMIN')
         if bool(self.request.user.groups.filter(name=group_names)) or self.request.user.is_superuser:
             return True
         return False
@@ -70,7 +97,7 @@ 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 = Relationship.objects.get(pk=relationship)
         relationship.status = new_status
         relationship.save()
         return JsonResponse({'status': 'success'})
@@ -78,5 +105,16 @@ def change_relationship_status(request):
         return JsonResponse({'status': 'error'})
 
 
-
+@login_required
+@group_required('PLATFORM-ADMIN')
+def change_permissions_status(request):
+    if request.method == 'POST':
+        permissions_id = request.POST.get('permissions')
+        new_status = request.POST.get('new_status')
+        permissions = Permissions.objects.get(pk=permissions)
+        permissions.status = new_status
+        permissions.save()
+        return JsonResponse({'status': 'success'})
+    else:
+        return JsonResponse({'status': 'error'})
 

+ 44 - 0
sharix_admin/views/user_info.py

@@ -5,7 +5,11 @@ from django.utils.translation import gettext as _
 from django_tables2 import SingleTableView
 
 from sharix_admin.tables import UserInfoTable
+from django.views.generic import DetailView
 
+from dbsynce.models import Company, Documents, DocumentFile
+
+from .base import BaseView
 
 class UserListView(UserPassesTestMixin, SingleTableView):
     table_class = UserInfoTable
@@ -26,3 +30,43 @@ class UserListView(UserPassesTestMixin, SingleTableView):
         if bool(self.request.user.groups.filter(name=group_names)) or self.request.user.is_superuser:
             return True
         return False
+
+#TODO change to smth working
+class UserDetailView(BaseView, DetailView):
+#class UserDetailView(UserPassesTestMixin, DetailView):
+
+#class PartnerDetailView(PartnerBaseView, DetailView):
+#TODO - change to sharix user
+    model = Company
+#TODO create this template
+#    template_name = 'sharix_admin/user_detail.html'
+    template_name = 'sharix_admin/user_info.html'
+    context_object_name = 'user_detail'
+    page_title = 'Информация о пользователе'
+
+#TODO change to smth about user
+    def get_object(self, queryset=None):
+        return get_object_or_404(Company, repr=self.request.user)
+
+    def get_context_data(self, **kwargs):
+        context = super().get_context_data(**kwargs)
+
+        if not pk:
+            docs = Documents.objects.filter(
+                user=pk,
+                company=company.objects.filter(user=pk)
+                ).prefetch_related('files').order_by('doc_type')
+                #user=self.request.user,
+                #company=self.object
+            #).prefetch_related('files').order_by('doc_type')
+
+            context.update({"docs": docs})
+        else:
+            docs = Documents.objects.filter(
+                user=self.request.user,
+                company=self.object
+            ).prefetch_related('files').order_by('doc_type')
+
+            context.update({"docs": docs})
+
+        return context